Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
87543246d9
commit
fdc98c3e3c
77 changed files with 1520 additions and 652 deletions
|
@ -208,152 +208,589 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
|
|||
/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
|
||||
/doc/ @gl-docsteam
|
||||
/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
|
||||
/doc/administration/application_settings_cache.md @marcia
|
||||
/doc/administration/audit_event_streaming.md @eread
|
||||
/doc/administration/audit_events.md @eread
|
||||
/doc/administration/audit_reports.md @eread
|
||||
/doc/administration/auditor_users.md @axil
|
||||
/doc/administration/auth/atlassian.md @eread
|
||||
/doc/administration/auth/authentiq.md @eread
|
||||
/doc/administration/auth/cognito.md @eread
|
||||
/doc/administration/auth/crowd.md @eread
|
||||
/doc/administration/auth/index.md @eread
|
||||
/doc/administration/auth/ldap/google_secure_ldap.md @eread
|
||||
/doc/administration/auth/jwt.md @eread
|
||||
/doc/administration/auth/ldap/ldap-troubleshooting.md @eread
|
||||
/doc/administration/auth/ldap/ldap_synchronization.md @eread
|
||||
/doc/administration/auth/ldap/index.md @eread
|
||||
/doc/administration/auth/oidc.md @eread
|
||||
/doc/administration/auth/smartcard.md @eread
|
||||
/doc/administration/cicd.md @marcel.amirault
|
||||
/doc/administration/clusters/kas.md @marcia
|
||||
/doc/administration/compliance.md @eread
|
||||
/doc/administration/configure.md @axil
|
||||
/doc/administration/consul.md @axil
|
||||
/doc/administration/docs_self_host.md @axil
|
||||
/doc/administration/encrypted_configuration.md @axil
|
||||
/doc/administration/environment_variables.md @axil
|
||||
/doc/administration/external_pipeline_validation.md @marcel.amirault
|
||||
/doc/administration/feature_flags.md @axil
|
||||
/doc/administration/file_hooks.md @aqualls
|
||||
/doc/administration/geo/ @axil
|
||||
/doc/administration/git_protocol.md @aqualls
|
||||
/doc/administration/gitaly/ @eread
|
||||
/doc/administration/lfs/ @aqualls
|
||||
/doc/administration/housekeeping.md @axil
|
||||
/doc/administration/incoming_email.md @msedlakjakubowski
|
||||
/doc/administration/index.md @axil
|
||||
/doc/administration/instance_limits.md @axil
|
||||
/doc/administration/instance_review.md @kpaizee
|
||||
/doc/administration/integration/kroki.md @kpaizee
|
||||
/doc/administration/integration/mailgun.md @kpaizee
|
||||
/doc/administration/integration/plantuml.md @aqualls
|
||||
/doc/administration/integration/terminal.md @kpaizee
|
||||
/doc/administration/invalidate_markdown_cache.md @msedlakjakubowski
|
||||
/doc/administration/issue_closing_pattern.md @aqualls
|
||||
/doc/administration/job_artifacts.md @eread
|
||||
/doc/administration/job_logs.md @sselhorn
|
||||
/doc/administration/lfs/index.md @aqualls
|
||||
/doc/administration/libravatar.md @axil
|
||||
/doc/administration/load_balancer.md @axil
|
||||
/doc/administration/logs.md @ngaskill
|
||||
/doc/administration/maintenance_mode/index.md @axil
|
||||
/doc/administration/merge_request_diffs.md @aqualls
|
||||
/doc/administration/monitoring/ @ngaskill
|
||||
/doc/administration/operations/ @axil @eread @marcia
|
||||
/doc/administration/nfs.md @axil
|
||||
/doc/administration/object_storage.md @axil
|
||||
/doc/administration/operations/ @axil
|
||||
/doc/administration/operations/sidekiq_memory_killer.md @marcia
|
||||
/doc/administration/package_information/ @axil
|
||||
/doc/administration/packages/ @ngaskill
|
||||
/doc/administration/pages/ @rdickenson @kpaizee
|
||||
/doc/administration/pages/ @rdickenson
|
||||
/doc/administration/polling.md @axil
|
||||
/doc/administration/postgresql/ @marcia
|
||||
/doc/administration/raketasks/ @axil @eread
|
||||
/doc/administration/pseudonymizer.md @axil
|
||||
/doc/administration/raketasks/ @axil
|
||||
/doc/administration/read_only_gitlab.md @axil
|
||||
/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/reply_by_email_postfix_setup.md @axil
|
||||
/doc/administration/reply_by_email.md @msedlakjakubowski
|
||||
/doc/administration/repository_checks.md @eread
|
||||
/doc/administration/repository_storage_paths.md @eread
|
||||
/doc/administration/repository_storage_types.md @eread
|
||||
/doc/administration/restart_gitlab.md @axil
|
||||
/doc/administration/server_hooks.md @eread
|
||||
/doc/administration/sidekiq.md @axil
|
||||
/doc/administration/smime_signing_email.md @axil
|
||||
/doc/administration/snippets/index.md @aqualls
|
||||
/doc/administration/static_objects_external_storage.md @aqualls
|
||||
/doc/api/access_requests.md @aqualls
|
||||
/doc/administration/terraform_state.md @marcia
|
||||
/doc/administration/timezone.md @axil
|
||||
/doc/administration/troubleshooting/ @axil
|
||||
/doc/administration/troubleshooting/group_saml_scim.md @eread
|
||||
/doc/administration/troubleshooting/postgresql.md @marcia
|
||||
/doc/administration/uploads.md @axil
|
||||
/doc/administration/user_settings.md @eread
|
||||
/doc/administration/whats-new.md @kpaizee
|
||||
/doc/administration/wikis/index.md @aqualls
|
||||
/doc/api/access_requests.md @eread
|
||||
/doc/api/admin_sidekiq_queues.md @axil
|
||||
/doc/api/api_resources.md @kpaizee
|
||||
/doc/api/appearance.md @eread
|
||||
/doc/api/applications.md @eread
|
||||
/doc/api/audit_events.md @eread
|
||||
/doc/api/avatar.md @eread
|
||||
/doc/api/award_emoji.md @msedlakjakubowski
|
||||
/doc/api/boards.md @msedlakjakubowski
|
||||
/doc/api/branches.md @aqualls
|
||||
/doc/api/broadcast_messages.md @kpaizee
|
||||
/doc/api/bulk_imports.md @ngaskill
|
||||
/doc/api/commits.md @aqualls
|
||||
/doc/api/container_registry.md @ngaskill
|
||||
/doc/api/custom_attributes.md @kpaizee
|
||||
/doc/api/dependencies.md @rdickenson
|
||||
/doc/api/dependency_proxy.md @ngaskill
|
||||
/doc/api/deploy_keys.md @rdickenson
|
||||
/doc/api/deploy_tokens.md @rdickenson
|
||||
/doc/api/deployments.md @rdickenson
|
||||
/doc/api/discussions.md @aqualls
|
||||
/doc/api/dora/metrics.md @fneill
|
||||
/doc/api/dora4_project_analytics.md @fneill
|
||||
/doc/api/environments.md @rdickenson
|
||||
/doc/api/epic_issues.md @msedlakjakubowski
|
||||
/doc/api/epic_links.md @msedlakjakubowski
|
||||
/doc/api/epics.md @msedlakjakubowski
|
||||
/doc/api/error_tracking.md @ngaskill
|
||||
/doc/api/events.md @eread
|
||||
/doc/api/experiments.md @kpaizee
|
||||
/doc/api/feature_flag_specs.md @rdickenson
|
||||
/doc/api/feature_flag_user_lists.md @rdickenson
|
||||
/doc/api/feature_flags_legacy.md @rdickenson
|
||||
/doc/api/feature_flags.md @rdickenson
|
||||
/doc/api/features.md @rdickenson
|
||||
/doc/api/freeze_periods.md @rdickenson
|
||||
/doc/api/geo_nodes.md @axil
|
||||
/doc/api/graphql/ @kpaizee
|
||||
/doc/api/graphql/custom_emoji.md @msedlakjakubowski
|
||||
/doc/api/graphql/sample_issue_boards.md @msedlakjakubowski
|
||||
/doc/api/group_activity_analytics.md @fneill
|
||||
/doc/api/group_badges.md @eread
|
||||
/doc/api/group_boards.md @msedlakjakubowski
|
||||
/doc/api/group_clusters.md @marcia
|
||||
/doc/api/group_import_export.md @ngaskill
|
||||
/doc/api/group_iterations.md @msedlakjakubowski
|
||||
/doc/api/group_labels.md @msedlakjakubowski
|
||||
/doc/api/group_level_variables.md @marcel.amirault
|
||||
/doc/api/group_milestones.md @msedlakjakubowski
|
||||
/doc/api/group_protected_environments.md @rdickenson
|
||||
/doc/api/group_relations_export.md @ngaskill
|
||||
/doc/api/group_repository_storage_moves.md @aqualls
|
||||
/doc/api/group_wikis.md @aqualls
|
||||
/doc/api/groups.md @eread
|
||||
/doc/api/import.md @ngaskill
|
||||
/doc/api/index.md @kpaizee
|
||||
/doc/api/instance_clusters.md @marcia
|
||||
/doc/api/instance_level_ci_variables.md @marcel.amirault
|
||||
/doc/api/integrations.md @kpaizee
|
||||
/doc/api/invitations.md @kpaizee
|
||||
/doc/api/issue_links.md @msedlakjakubowski
|
||||
/doc/api/issues_statistics.md @msedlakjakubowski
|
||||
/doc/api/issues.md @msedlakjakubowski
|
||||
/doc/api/iterations.md @msedlakjakubowski
|
||||
/doc/api/job_artifacts.md @eread
|
||||
/doc/api/jobs.md @marcel.amirault
|
||||
/doc/api/keys.md @aqualls
|
||||
/doc/api/labels.md @msedlakjakubowski
|
||||
/doc/api/license.md @kpaizee
|
||||
/doc/api/lint.md @marcel.amirault
|
||||
/doc/api/managed_licenses.md @kpaizee
|
||||
/doc/api/markdown.md @aqualls
|
||||
/doc/api/members.md @eread
|
||||
/doc/api/merge_request_approvals.md @aqualls
|
||||
/doc/api/merge_request_context_commits.md @aqualls
|
||||
/doc/api/merge_requests.md @aqualls
|
||||
/doc/api/merge_trains.md @marcel.amirault
|
||||
/doc/api/metrics_dashboard_annotations.md @ngaskill
|
||||
/doc/api/metrics_user_starred_dashboards.md @ngaskill
|
||||
/doc/api/milestones.md @msedlakjakubowski
|
||||
/doc/api/namespaces.md @eread
|
||||
/doc/api/notes.md @msedlakjakubowski
|
||||
/doc/api/notification_settings.md @msedlakjakubowski
|
||||
/doc/api/oauth2.md @eread
|
||||
/doc/api/openapi/openapi_interactive.md @kpaizee
|
||||
/doc/api/packages.md @ngaskill
|
||||
/doc/api/packages/ @ngaskill
|
||||
/doc/api/pages_domains.md @rdickenson
|
||||
/doc/api/pages.md @rdickenson
|
||||
/doc/api/personal_access_tokens.md @eread
|
||||
/doc/api/pipeline_schedules.md @marcel.amirault
|
||||
/doc/api/pipeline_triggers.md @marcel.amirault
|
||||
/doc/api/pipelines.md @marcel.amirault
|
||||
/doc/api/plan_limits.md @eread
|
||||
/doc/api/project_aliases.md @aqualls
|
||||
/doc/api/project_badges.md @aqualls
|
||||
/doc/api/project_clusters.md @marcia
|
||||
/doc/api/project_import_export.md @aqualls
|
||||
/doc/api/project_level_variables.md @aqualls
|
||||
/doc/api/project_level_variables.md @marcel.amirault
|
||||
/doc/api/project_relations_export.md @ngaskill
|
||||
/doc/api/project_repository_storage_moves.md @eread
|
||||
/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/projects.md @msedlakjakubowski
|
||||
/doc/api/protected_branches.md @aqualls
|
||||
/doc/api/protected_environments.md @rdickenson
|
||||
/doc/api/protected_tags.md @aqualls
|
||||
/doc/api/releases/index.md @rdickenson
|
||||
/doc/api/releases/links.md @rdickenson
|
||||
/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/resource_access_tokens.md @eread
|
||||
/doc/api/resource_groups.md @rdickenson
|
||||
/doc/api/resource_iteration_events.md @msedlakjakubowski
|
||||
/doc/api/resource_label_events.md @eread
|
||||
/doc/api/resource_milestone_events.md @msedlakjakubowski
|
||||
/doc/api/resource_state_events.md @msedlakjakubowski
|
||||
/doc/api/resource_weight_events.md @msedlakjakubowski
|
||||
/doc/api/runners.md @sselhorn
|
||||
/doc/api/scim.md @eread
|
||||
/doc/api/search.md @aqualls
|
||||
/doc/api/services.md @aqualls
|
||||
/doc/api/settings.md @eread
|
||||
/doc/api/sidekiq_metrics.md @axil
|
||||
/doc/api/snippet_repository_storage_moves.md @aqualls
|
||||
/doc/api/snippets.md @aqualls
|
||||
/doc/api/statistics.md @eread
|
||||
/doc/api/status_checks.md @eread
|
||||
/doc/api/suggestions.md @aqualls
|
||||
/doc/api/system_hooks.md @kpaizee
|
||||
/doc/api/tags.md @aqualls
|
||||
/doc/api/visual_review_discussions.md @aqualls
|
||||
/doc/api/templates/dockerfiles.md @aqualls
|
||||
/doc/api/templates/gitignores.md @aqualls
|
||||
/doc/api/templates/gitlab_ci_ymls.md @marcel.amirault
|
||||
/doc/api/templates/licenses.md @rdickenson
|
||||
/doc/api/todos.md @msedlakjakubowski
|
||||
/doc/api/topics.md @fneill
|
||||
/doc/api/usage_data.md @fneill
|
||||
/doc/api/users.md @eread
|
||||
/doc/api/v3_to_v4.md @kpaizee
|
||||
/doc/api/version.md @kpaizee
|
||||
/doc/api/visual_review_discussions.md @eread
|
||||
/doc/api/vulnerabilities.md @fneill
|
||||
/doc/api/vulnerability_exports.md @fneill
|
||||
/doc/api/vulnerability_findings.md @fneill
|
||||
/doc/api/wikis.md @aqualls
|
||||
/doc/intro/index.md @aqualls
|
||||
/doc/architecture/blueprints/container_registry_metadata_database/index.md @ngaskill
|
||||
/doc/architecture/blueprints/database/scalability/patterns/ @marcia
|
||||
/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md @marcia
|
||||
/doc/ci/caching/index.md @marcel.amirault
|
||||
/doc/ci/chatops/index.md @marcia
|
||||
/doc/ci/ci_cd_for_external_repos/ @marcel.amirault
|
||||
/doc/ci/cloud_deployment/ecs/quick_start_guide.md @rdickenson
|
||||
/doc/ci/cloud_deployment/index.md @rdickenson
|
||||
/doc/ci/directed_acyclic_graph/index.md @marcel.amirault
|
||||
/doc/ci/docker/index.md @marcel.amirault
|
||||
/doc/ci/docker/using_docker_build.md @marcel.amirault
|
||||
/doc/ci/docker/using_docker_images.md @sselhorn
|
||||
/doc/ci/docker/using_kaniko.md @marcel.amirault
|
||||
/doc/ci/enable_or_disable_ci.md @marcel.amirault
|
||||
/doc/ci/environments/ @rdickenson
|
||||
/doc/ci/examples/authenticating-with-hashicorp-vault/index.md @rdickenson
|
||||
/doc/ci/examples/deployment/composer-npm-deploy.md @rdickenson
|
||||
/doc/ci/examples/deployment/index.md @rdickenson
|
||||
/doc/ci/examples/end_to_end_testing_webdriverio/index.md @eread
|
||||
/doc/ci/examples/index.md @marcel.amirault
|
||||
/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md @marcel.amirault
|
||||
/doc/ci/examples/php.md @marcel.amirault
|
||||
/doc/ci/examples/semantic-release.md @ngaskill
|
||||
/doc/ci/git_submodules.md @marcel.amirault
|
||||
/doc/ci/index.md @marcel.amirault
|
||||
/doc/ci/interactive_web_terminal/index.md @sselhorn
|
||||
/doc/ci/introduction/index.md @marcel.amirault
|
||||
/doc/ci/jobs/ci_job_token.md @marcel.amirault
|
||||
/doc/ci/jobs/index.md @marcel.amirault
|
||||
/doc/ci/jobs/job_control.md @marcel.amirault
|
||||
/doc/ci/large_repositories/index.md @sselhorn
|
||||
/doc/ci/lint.md @marcel.amirault
|
||||
/doc/ci/metrics_reports.md @eread
|
||||
/doc/ci/migration/circleci.md @marcel.amirault
|
||||
/doc/ci/migration/jenkins.md @marcel.amirault
|
||||
/doc/ci/pipeline_editor/index.md @marcel.amirault
|
||||
/doc/ci/pipelines/ @marcel.amirault
|
||||
/doc/ci/pipelines/job_artifacts.md @eread
|
||||
/doc/ci/pipelines/pipeline_artifacts.md @eread
|
||||
/doc/ci/quick_start/index.md @marcel.amirault
|
||||
/doc/ci/resource_groups/index.md @rdickenson
|
||||
/doc/ci/review_apps/index.md @eread
|
||||
/doc/ci/runners/ @sselhorn
|
||||
/doc/ci/secrets/index.md @marcia
|
||||
/doc/ci/services/ @sselhorn
|
||||
/doc/ci/ssh_keys/index.md @marcel.amirault
|
||||
/doc/ci/test_cases/index.md @msedlakjakubowski
|
||||
/doc/ci/triggers/index.md @marcel.amirault
|
||||
/doc/ci/troubleshooting.md @marcel.amirault
|
||||
/doc/ci/unit_test_reports.md @eread
|
||||
/doc/ci/variables/ @marcel.amirault
|
||||
/doc/ci/yaml/ @marcel.amirault
|
||||
/doc/ci/yaml/artifacts_reports.md @eread
|
||||
/doc/development/adding_database_indexes.md @marcia
|
||||
/doc/development/application_limits.md @axil
|
||||
/doc/development/approval_rules.md @aqualls
|
||||
/doc/development/audit_event_guide/index.md @eread
|
||||
/doc/development/auto_devops.md @marcia
|
||||
/doc/development/avoiding_downtime_in_migrations.md @marcia
|
||||
/doc/development/backend/ruby_style_guide.md @marcia
|
||||
/doc/development/background_migrations.md @marcia
|
||||
/doc/development/build_test_package.md @axil
|
||||
/doc/development/bulk_import.md @ngaskill
|
||||
/doc/development/cascading_settings.md @eread
|
||||
/doc/development/chatops_on_gitlabcom.md @marcia
|
||||
/doc/development/cicd/cicd_reference_documentation_guide.md @marcel.amirault
|
||||
/doc/development/cicd/index.md @marcel.amirault
|
||||
/doc/development/cicd/templates.md @marcel.amirault
|
||||
/doc/development/code_intelligence/index.md @aqualls
|
||||
/doc/development/contributing/ @marcia
|
||||
/doc/development/creating_enums.md @marcia
|
||||
/doc/development/database_debugging.md @marcia
|
||||
/doc/development/database_query_comments.md @marcia
|
||||
/doc/development/database_review.md @marcia
|
||||
/doc/development/database/ @marcia
|
||||
/doc/development/db_dump.md @marcia
|
||||
/doc/development/developing_with_solargraph.md @aqualls
|
||||
/doc/development/distributed_tracing.md @ngaskill
|
||||
/doc/development/documentation/feature_flags.md @marcia
|
||||
/doc/development/documentation/graphql_styleguide.md @marcia
|
||||
/doc/development/documentation/index.md @cnorris
|
||||
/doc/development/documentation/redirects.md @cnorris
|
||||
/doc/development/documentation/restful_api_styleguide.md @marcia
|
||||
/doc/development/documentation/review_apps.md @cnorris
|
||||
/doc/development/documentation/structure.md @sselhorn
|
||||
/doc/development/documentation/styleguide/index.md @sselhorn
|
||||
/doc/development/documentation/styleguide/word_list.md @sselhorn
|
||||
/doc/development/documentation/testing.md @cnorris
|
||||
/doc/development/elasticsearch.md @marcia
|
||||
/doc/development/experiment_guide/ @kpaizee
|
||||
/doc/development/export_csv.md @ngaskill
|
||||
/doc/development/fe_guide/content_editor.md @aqualls
|
||||
/doc/development/fe_guide/dark_mode.md @marcia
|
||||
/doc/development/fe_guide/graphql.md @marcia
|
||||
/doc/development/fe_guide/source_editor.md @aqualls
|
||||
/doc/development/feature_categorization/index.md @marcia
|
||||
/doc/development/feature_flags/controls.md @marcia
|
||||
/doc/development/feature_flags/index.md @marcia
|
||||
/doc/development/filtering_by_label.md @msedlakjakubowski
|
||||
/doc/development/foreign_keys.md @marcia
|
||||
/doc/development/geo.md @axil
|
||||
/doc/development/geo/framework.md @axil
|
||||
/doc/development/git_object_deduplication.md @eread
|
||||
/doc/development/gitaly.md @eread
|
||||
/doc/development/graphql_guide/batchloader.md @marcia
|
||||
/doc/development/graphql_guide/graphql_pro.md @kpaizee
|
||||
/doc/development/graphql_guide/index.md @kpaizee
|
||||
/doc/development/graphql_guide/pagination.md @kpaizee
|
||||
/doc/development/hash_indexes.md @marcia
|
||||
/doc/development/i18n/ @ngaskill
|
||||
/doc/development/image_scaling.md @marcia
|
||||
/doc/development/import_export.md @ngaskill
|
||||
/doc/development/index.md @marcia
|
||||
/doc/development/insert_into_tables_in_batches.md @marcia
|
||||
/doc/development/integrations/codesandbox.md @marcia
|
||||
/doc/development/integrations/jenkins.md @kpaizee
|
||||
/doc/development/integrations/jira_connect.md @kpaizee
|
||||
/doc/development/integrations/secure_partner_integration.md @rdickenson
|
||||
/doc/development/integrations/secure.md @ngaskill
|
||||
/doc/development/internal_api/ @aqualls
|
||||
/doc/development/internal_users.md @marcia
|
||||
/doc/development/issuable-like-models.md @msedlakjakubowski
|
||||
/doc/development/issue_types.md @msedlakjakubowski
|
||||
/doc/development/iterating_tables_in_batches.md @marcia
|
||||
/doc/development/kubernetes.md @marcia
|
||||
/doc/development/lfs.md @aqualls
|
||||
/doc/development/licensed_feature_availability.md @sselhorn
|
||||
/doc/development/logging.md @ngaskill
|
||||
/doc/development/maintenance_mode.md @axil
|
||||
/doc/development/new_fe_guide/modules/widget_extensions.md @aqualls
|
||||
/doc/development/new_fe_guide/tips.md @marcia
|
||||
/doc/development/omnibus.md @axil
|
||||
/doc/development/ordering_table_columns.md @marcia
|
||||
/doc/development/packages.md @ngaskill
|
||||
/doc/development/permissions.md @eread
|
||||
/doc/development/policies.md @eread
|
||||
/doc/development/prometheus_metrics.md @ngaskill
|
||||
/doc/development/query_performance.md @marcia
|
||||
/doc/development/real_time.md @msedlakjakubowski
|
||||
/doc/development/secure_coding_guidelines.md @marcia
|
||||
/doc/development/serializing_data.md @marcia
|
||||
/doc/development/service_ping/ @fneill
|
||||
/doc/development/snowplow/ @fneill
|
||||
/doc/development/sql.md @marcia
|
||||
/doc/development/stage_group_dashboards.md @marcia
|
||||
/doc/development/swapping_tables.md @marcia
|
||||
/doc/development/testing_guide/best_practices.md @marcia
|
||||
/doc/development/testing_guide/end_to_end/best_practices.md @marcia
|
||||
/doc/development/understanding_explain_plans.md @marcia
|
||||
/doc/development/value_stream_analytics.md @fneill
|
||||
/doc/development/verifying_database_capabilities.md @marcia
|
||||
/doc/development/wikis.md @aqualls
|
||||
/doc/development/work_items.md @msedlakjakubowski
|
||||
/doc/development/work_items_widgets.md @msedlakjakubowski
|
||||
/doc/downgrade_ee_to_ce/index.md @axil
|
||||
/doc/gitlab-basics/add-file.md @aqualls
|
||||
/doc/gitlab-basics/command-line-commands.md @aqualls
|
||||
/doc/gitlab-basics/create-branch.md @aqualls
|
||||
/doc/gitlab-basics/feature_branch_workflow.md @aqualls
|
||||
/doc/gitlab-basics/index.md @aqualls
|
||||
/doc/gitlab-basics/start-using-git.md @aqualls
|
||||
/doc/install/ @axil
|
||||
/doc/integration/ @kpaizee
|
||||
/doc/integration/elasticsearch.md @marcia
|
||||
/doc/integration/gitpod.md @aqualls
|
||||
/doc/integration/kerberos.md @eread
|
||||
/doc/integration/mattermost/index.md @axil
|
||||
/doc/integration/oauth_provider.md @eread
|
||||
/doc/integration/saml.md @eread
|
||||
/doc/integration/security_partners/index.md @rdickenson
|
||||
/doc/integration/sourcegraph.md @aqualls
|
||||
/doc/integration/vault.md @rdickenson
|
||||
/doc/operations/ @ngaskill
|
||||
/doc/operations/feature_flags.md @rdickenson
|
||||
/doc/operations/product_analytics.md @fneill
|
||||
/doc/policy/ @axil
|
||||
/doc/public_access/public_access.md @fneill
|
||||
/doc/push_rules/push_rules.md @aqualls
|
||||
/doc/raketasks/ @axil
|
||||
/doc/raketasks/generate_sample_prometheus_data.md @ngaskill
|
||||
/doc/raketasks/migrate_snippets.md @aqualls
|
||||
/doc/raketasks/spdx.md @rdickenson
|
||||
/doc/raketasks/x509_signatures.md @aqualls
|
||||
/doc/security/ @eread
|
||||
/doc/ssh/index.md @eread
|
||||
/doc/subscriptions/ @sselhorn
|
||||
/doc/system_hooks/system_hooks.md @kpaizee
|
||||
/doc/topics/authentication/index.md @eread
|
||||
/doc/topics/autodevops/customize.md @marcia
|
||||
/doc/topics/autodevops/ @marcia
|
||||
/doc/topics/git/ @aqualls
|
||||
/doc/topics/gitlab_flow.md @aqualls
|
||||
/doc/topics/offline/ @axil
|
||||
/doc/topics/plan_and_track.md @msedlakjakubowski
|
||||
/doc/update/ @axil
|
||||
/doc/update/mysql_to_postgresql.md @marcia
|
||||
/doc/update/upgrading_postgresql_using_slony.md @marcia
|
||||
/doc/user/admin_area/analytics/ @fneill
|
||||
/doc/user/admin_area/broadcast_messages.md @kpaizee
|
||||
/doc/user/admin_area/credentials_inventory.md @eread
|
||||
/doc/user/admin_area/custom_project_templates.md @ngaskill
|
||||
/doc/user/admin_area/diff_limits.md @aqualls
|
||||
/doc/user/admin_area/geo_nodes.md @axil
|
||||
/doc/user/admin_area/labels.md @msedlakjakubowski
|
||||
/doc/user/admin_area/license.md @kpaizee
|
||||
/doc/user/admin_area/merge_requests_approvals.md @aqualls
|
||||
/doc/user/admin_area/moderate_users.md @eread
|
||||
/doc/user/admin_area/monitoring/background_migrations.md @marcia
|
||||
/doc/user/admin_area/monitoring/health_check.md @ngaskill
|
||||
/doc/user/admin_area/review_abuse_reports.md @eread
|
||||
/doc/user/admin_area/settings/account_and_limit_settings.md @aqualls
|
||||
/doc/user/admin_area/settings/continuous_integration.md @marcel.amirault
|
||||
/doc/user/admin_area/settings/deprecated_api_rate_limits.md @aqualls
|
||||
/doc/user/admin_area/settings/email.md @msedlakjakubowski
|
||||
/doc/user/admin_area/settings/external_authorization.md @eread
|
||||
/doc/user/admin_area/settings/files_api_rate_limits.md @aqualls
|
||||
/doc/user/admin_area/settings/git_lfs_rate_limits.md @aqualls
|
||||
/doc/user/admin_area/settings/gitaly_timeouts.md @eread
|
||||
/doc/user/admin_area/settings/import_export_rate_limits.md @ngaskill
|
||||
/doc/user/admin_area/settings/index.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/package_registry_rate_limits.md @ngaskill
|
||||
/doc/user/admin_area/settings/project_integration_management.md @kpaizee
|
||||
/doc/user/admin_area/settings/push_event_activities_limit.md @aqualls
|
||||
/doc/user/admin_area/settings/rate_limit_on_issues_creation.md @msedlakjakubowski
|
||||
/doc/user/admin_area/settings/rate_limit_on_notes_creation.md @msedlakjakubowski
|
||||
/doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls
|
||||
/doc/user/analytics/ci_cd_analytics.md @rdickenson
|
||||
/doc/user/analytics/ @fneill
|
||||
/doc/user/application_security/ @rdickenson
|
||||
/doc/user/application_security/cluster_image_scanning/index.md @ngaskill
|
||||
/doc/user/application_security/container_scanning/index.md @ngaskill
|
||||
/doc/user/application_security/cve_id_request.md @fneill
|
||||
/doc/user/application_security/policies/index.md @ngaskill
|
||||
/doc/user/application_security/security_dashboard/index.md @fneill
|
||||
/doc/user/application_security/threat_monitoring/index.md @ngaskill
|
||||
/doc/user/application_security/vulnerabilities/ @fneill
|
||||
/doc/user/application_security/vulnerability_report/index.md @fneill
|
||||
/doc/user/asciidoc.md @aqualls
|
||||
/doc/user/index.md @aqualls
|
||||
/doc/user/award_emojis.md @msedlakjakubowski
|
||||
/doc/user/clusters/ @marcia
|
||||
/doc/user/compliance/compliance_report/index.md @eread
|
||||
/doc/user/compliance/index.md @eread
|
||||
/doc/user/compliance/license_compliance/index.md @rdickenson
|
||||
/doc/user/discussions/index.md @aqualls
|
||||
/doc/user/feature_flags.md @marcia
|
||||
/doc/user/group/clusters/index.md @marcia
|
||||
/doc/user/group/contribution_analytics/index.md @fneill
|
||||
/doc/user/group/custom_project_templates.md @ngaskill
|
||||
/doc/user/group/devops_adoption/index.md @fneill
|
||||
/doc/user/group/epics/epic_boards.md @msedlakjakubowski
|
||||
/doc/user/group/epics/index.md @msedlakjakubowski
|
||||
/doc/user/group/epics/manage_epics.md @msedlakjakubowski
|
||||
/doc/user/group/import/index.md @ngaskill
|
||||
/doc/user/group/index.md @eread
|
||||
/doc/user/group/insights/index.md @fneill
|
||||
/doc/user/group/issues_analytics/index.md @msedlakjakubowski
|
||||
/doc/user/group/iterations/index.md @msedlakjakubowski
|
||||
/doc/user/group/repositories_analytics/index.md @eread
|
||||
/doc/user/group/roadmap/index.md @msedlakjakubowski
|
||||
/doc/user/group/saml_sso/group_managed_accounts.md @eread
|
||||
/doc/user/group/saml_sso/index.md @eread
|
||||
/doc/user/group/saml_sso/scim_setup.md @eread
|
||||
/doc/user/group/settings/import_export.md @ngaskill
|
||||
/doc/user/group/subgroups/index.md @eread
|
||||
/doc/user/group/value_stream_analytics/index.md @fneill
|
||||
/doc/user/infrastructure/clusters/ @marcia
|
||||
/doc/user/infrastructure/clusters/manage/clusters_health.md @marcia
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/apparmor.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md @marcia
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/falco.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md @marcia
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md @sselhorn
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md @ngaskill
|
||||
/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md @marcia
|
||||
/doc/user/infrastructure/iac/ @marcia
|
||||
/doc/user/infrastructure/index.md @marcia
|
||||
/doc/user/markdown.md @aqualls
|
||||
/doc/user/packages/ @ngaskill
|
||||
/doc/user/packages/infrastructure_registry/index.md @marcia
|
||||
/doc/user/packages/terraform_module_registry/index.md @marcia
|
||||
/doc/user/permissions.md @eread
|
||||
/doc/user/profile/ @eread
|
||||
/doc/user/profile/notifications.md @msedlakjakubowski
|
||||
/doc/user/project/autocomplete_characters.md @aqualls
|
||||
/doc/user/project/badges.md @aqualls
|
||||
/doc/user/project/clusters/ @marcia
|
||||
/doc/user/project/clusters/kubernetes_pod_logs.md @ngaskill
|
||||
/doc/user/project/clusters/protect/ @ngaskill
|
||||
/doc/user/project/code_intelligence.md @aqualls
|
||||
/doc/user/project/code_owners.md @aqualls
|
||||
/doc/user/project/deploy_boards.md @rdickenson
|
||||
/doc/user/project/deploy_keys/index.md @rdickenson
|
||||
/doc/user/project/deploy_tokens/index.md @rdickenson
|
||||
/doc/user/project/description_templates.md @msedlakjakubowski
|
||||
/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/import/ @ngaskill
|
||||
/doc/user/project/import/jira.md @msedlakjakubowski
|
||||
/doc/user/project/index.md @fneill
|
||||
/doc/user/project/integrations/ @kpaizee
|
||||
/doc/user/project/integrations/prometheus_library/ @ngaskill
|
||||
/doc/user/project/integrations/prometheus.md @ngaskill
|
||||
/doc/user/project/issue_board.md @msedlakjakubowski
|
||||
/doc/user/project/issues/ @msedlakjakubowski
|
||||
/doc/user/project/labels.md @msedlakjakubowski
|
||||
/doc/user/project/members/index.md @eread
|
||||
/doc/user/project/members/share_project_with_groups.md @fneill
|
||||
/doc/user/project/merge_requests/ @aqualls
|
||||
/doc/user/project/merge_requests/accessibility_testing.md @eread
|
||||
/doc/user/project/merge_requests/browser_performance_testing.md @eread
|
||||
/doc/user/project/merge_requests/code_quality.md @rdickenson
|
||||
/doc/user/project/merge_requests/csv_export.md @eread
|
||||
/doc/user/project/merge_requests/fail_fast_testing.md @eread
|
||||
/doc/user/project/merge_requests/load_performance_testing.md @eread
|
||||
/doc/user/project/merge_requests/status_checks.md @eread
|
||||
/doc/user/project/merge_requests/test_coverage_visualization.md @eread
|
||||
/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md @eread
|
||||
/doc/user/project/milestones/ @msedlakjakubowski
|
||||
/doc/user/project/pages/ @rdickenson
|
||||
/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/project/quick_actions.md @msedlakjakubowski
|
||||
/doc/user/project/releases/index.md @rdickenson
|
||||
/doc/user/project/releases/release_cli.md @rdickenson
|
||||
/doc/user/project/repository/ @aqualls
|
||||
/doc/user/project/repository/reducing_the_repo_size_using_git.md @eread
|
||||
/doc/user/project/requirements/index.md @msedlakjakubowski
|
||||
/doc/user/project/service_desk.md @msedlakjakubowski
|
||||
/doc/user/project/settings/import_export.md @ngaskill
|
||||
/doc/user/project/settings/index.md @fneill
|
||||
/doc/user/project/settings/project_access_tokens.md @eread
|
||||
/doc/user/project/static_site_editor/index.md @aqualls
|
||||
/doc/user/project/time_tracking.md @msedlakjakubowski
|
||||
/doc/user/project/web_ide/index.md @aqualls
|
||||
/doc/user/project/wiki/group.md @aqualls
|
||||
/doc/user/project/wiki/index.md @aqualls
|
||||
/doc/user/project/working_with_projects.md @fneill
|
||||
/doc/user/reserved_names.md @fneill
|
||||
/doc/user/search/advanced_search.md @marcia
|
||||
/doc/user/search/index.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
|
||||
/doc/user/tasks.md @msedlakjakubowski
|
||||
/doc/user/todos.md @msedlakjakubowski
|
||||
/doc/user/usage_quotas.md @sselhorn
|
||||
/doc/user/workspace/index.md @fneill
|
||||
|
|
|
@ -2,15 +2,6 @@
|
|||
Rails/SaveBang:
|
||||
Exclude:
|
||||
- ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb
|
||||
- ee/spec/models/protected_environment_spec.rb
|
||||
- ee/spec/models/repository_spec.rb
|
||||
- ee/spec/models/scim_identity_spec.rb
|
||||
- ee/spec/models/scim_oauth_access_token_spec.rb
|
||||
- ee/spec/models/upload_spec.rb
|
||||
- ee/spec/models/user_preference_spec.rb
|
||||
- ee/spec/models/visible_approvable_spec.rb
|
||||
- ee/spec/models/vulnerabilities/feedback_spec.rb
|
||||
- ee/spec/models/vulnerabilities/issue_link_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
|
||||
|
|
|
@ -1 +1 @@
|
|||
7b20a6045e8d2a25c86633461c03b13353915643
|
||||
85efc2a008ed64cf8ed516aa43537712b478e139
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlLoadingIcon, GlButton, GlModalDirective } from '@gitlab/ui';
|
||||
import { GlLoadingIcon, GlButton, GlModalDirective, GlBadge } from '@gitlab/ui';
|
||||
import { mapActions, mapState } from 'vuex';
|
||||
import { s__ } from '~/locale';
|
||||
import { PROJECT_BADGE } from '../constants';
|
||||
|
@ -11,6 +11,7 @@ export default {
|
|||
Badge,
|
||||
GlLoadingIcon,
|
||||
GlButton,
|
||||
GlBadge,
|
||||
},
|
||||
directives: {
|
||||
GlModal: GlModalDirective,
|
||||
|
@ -49,7 +50,7 @@ export default {
|
|||
/>
|
||||
<div class="table-section section-30">
|
||||
<label class="label-bold str-truncated mb-0">{{ badge.name }}</label>
|
||||
<span class="badge badge-pill">{{ badgeKindText }}</span>
|
||||
<gl-badge size="sm">{{ badgeKindText }}</gl-badge>
|
||||
</div>
|
||||
<span class="table-section section-30 str-truncated">{{ badge.linkUrl }}</span>
|
||||
<div class="table-section section-10 table-button-footer">
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { GlBadge, GlIcon, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
|
||||
import { __, s__ } from '~/locale';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import DeploymentStatusBadge from './deployment_status_badge.vue';
|
||||
|
||||
export default {
|
||||
|
@ -10,6 +11,7 @@ export default {
|
|||
DeploymentStatusBadge,
|
||||
GlBadge,
|
||||
GlIcon,
|
||||
TimeAgoTooltip,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip,
|
||||
|
@ -35,6 +37,9 @@ export default {
|
|||
shortSha() {
|
||||
return this.deployment?.commit?.shortId;
|
||||
},
|
||||
createdAt() {
|
||||
return this.deployment?.createdAt;
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
latestBadge: s__('Deployment|Latest Deployed'),
|
||||
|
@ -69,6 +74,9 @@ export default {
|
|||
:title="$options.i18n.copyButton"
|
||||
size="small"
|
||||
/>
|
||||
<time-ago-tooltip v-if="createdAt" :time="createdAt" class="gl-ml-5!">
|
||||
<template #default="{ timeAgo }"> <gl-icon name="calendar" /> {{ timeAgo }} </template>
|
||||
</time-ago-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
import { GlButton, GlFormGroup, GlFormSelect } from '@gitlab/ui';
|
||||
import { GlButton, GlFormGroup, GlFormSelect, GlFormCheckbox } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: { GlButton, GlFormGroup, GlFormSelect },
|
||||
components: { GlButton, GlFormGroup, GlFormSelect, GlFormCheckbox },
|
||||
props: {
|
||||
gcpProjects: { required: true, type: Array },
|
||||
environments: { required: true, type: Array },
|
||||
|
@ -19,6 +19,9 @@ export default {
|
|||
environmentDescription: __('Generated service account is linked to the selected environment'),
|
||||
submitLabel: __('Create service account'),
|
||||
cancelLabel: __('Cancel'),
|
||||
checkboxLabel: __(
|
||||
'I understand the responsibilities involved with managing service account keys',
|
||||
),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -59,6 +62,11 @@ export default {
|
|||
</option>
|
||||
</gl-form-select>
|
||||
</gl-form-group>
|
||||
<gl-form-group>
|
||||
<gl-form-checkbox name="confirmation" required>
|
||||
{{ $options.i18n.checkboxLabel }}
|
||||
</gl-form-checkbox>
|
||||
</gl-form-group>
|
||||
|
||||
<div class="form-actions row">
|
||||
<gl-button type="submit" category="primary" variant="confirm">
|
||||
|
|
|
@ -644,6 +644,7 @@ export default {
|
|||
:tabs="$options.IssuableListTabs"
|
||||
:current-tab="state"
|
||||
:tab-counts="tabCounts"
|
||||
:truncate-counts="!isProject"
|
||||
:issuables-loading="$apollo.queries.issues.loading"
|
||||
:is-manual-ordering="isManualOrdering"
|
||||
:show-bulk-edit-sidebar="showBulkEditSidebar"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export const BYTES_IN_KIB = 1024;
|
||||
export const DEFAULT_DEBOUNCE_AND_THROTTLE_MS = 250;
|
||||
export const HIDDEN_CLASS = 'hidden';
|
||||
export const THOUSAND = 1000;
|
||||
export const TRUNCATE_WIDTH_DEFAULT_WIDTH = 80;
|
||||
export const TRUNCATE_WIDTH_DEFAULT_FONT_SIZE = 12;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { sprintf, __ } from '~/locale';
|
||||
import { BYTES_IN_KIB } from './constants';
|
||||
import { BYTES_IN_KIB, THOUSAND } from './constants';
|
||||
|
||||
/**
|
||||
* Function that allows a number with an X amount of decimals
|
||||
|
@ -85,6 +85,27 @@ export function numberToHumanSize(size, digits = 2) {
|
|||
return sprintf(__('%{size} GiB'), { size: bytesToGiB(size).toFixed(digits) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number to kilos or megas.
|
||||
*
|
||||
* For example:
|
||||
* - 123 becomes 123
|
||||
* - 123456 becomes 123.4k
|
||||
* - 123456789 becomes 123.4m
|
||||
*
|
||||
* @param number Number to format
|
||||
* @param digits The number of digits to appear after the decimal point
|
||||
* @return {string} Formatted number
|
||||
*/
|
||||
export function numberToMetricPrefix(number, digits = 1) {
|
||||
if (number < THOUSAND) {
|
||||
return number.toString();
|
||||
}
|
||||
if (number < THOUSAND ** 2) {
|
||||
return `${(number / THOUSAND).toFixed(digits)}k`;
|
||||
}
|
||||
return `${(number / THOUSAND ** 2).toFixed(digits)}m`;
|
||||
}
|
||||
/**
|
||||
* A simple method that returns the value of a + b
|
||||
* It seems unessesary, but when combined with a reducer it
|
||||
|
|
|
@ -307,7 +307,12 @@ export default {
|
|||
@close="handleClose"
|
||||
>
|
||||
<template #collapsed>
|
||||
<div v-if="isClassicSidebar" v-gl-tooltip class="sidebar-collapsed-icon">
|
||||
<div
|
||||
v-if="isClassicSidebar"
|
||||
v-gl-tooltip.left.viewport
|
||||
:title="attributeTypeTitle"
|
||||
class="sidebar-collapsed-icon"
|
||||
>
|
||||
<gl-icon :size="16" :aria-label="attributeTypeTitle" :name="attributeTypeIcon" />
|
||||
<span class="collapse-truncated-title">
|
||||
{{ attributeTitle }}
|
||||
|
|
|
@ -177,19 +177,14 @@ export default {
|
|||
/>
|
||||
<gl-button
|
||||
v-if="isClassicSidebar"
|
||||
v-gl-tooltip.left.viewport
|
||||
:title="tootltipTitle"
|
||||
category="tertiary"
|
||||
type="reset"
|
||||
class="sidebar-collapsed-icon sidebar-collapsed-container gl-rounded-0! gl-shadow-none!"
|
||||
@click.stop.prevent="toggleTodo"
|
||||
>
|
||||
<gl-icon
|
||||
v-gl-tooltip.left.viewport
|
||||
:title="tootltipTitle"
|
||||
:size="16"
|
||||
:class="{ 'todo-undone': hasTodo }"
|
||||
:name="collapsedButtonIcon"
|
||||
:aria-label="collapsedButtonIcon"
|
||||
/>
|
||||
<gl-icon :class="{ 'todo-undone': hasTodo }" :name="collapsedButtonIcon" />
|
||||
</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -78,6 +78,11 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
truncateCounts: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
currentTab: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
@ -261,6 +266,7 @@ export default {
|
|||
:tabs="tabs"
|
||||
:tab-counts="tabCounts"
|
||||
:current-tab="currentTab"
|
||||
:truncate-counts="truncateCounts"
|
||||
@click="$emit('click-tab', $event)"
|
||||
>
|
||||
<template #nav-actions>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import { GlTabs, GlTab, GlBadge } from '@gitlab/ui';
|
||||
import { numberToMetricPrefix } from '~/lib/utils/number_utils';
|
||||
import { formatNumber } from '~/locale';
|
||||
|
||||
export default {
|
||||
|
@ -22,6 +23,11 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
truncateCounts: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isTabActive(tabName) {
|
||||
|
@ -31,7 +37,7 @@ export default {
|
|||
return Number.isInteger(this.tabCounts[tab.name]);
|
||||
},
|
||||
formatNumber(count) {
|
||||
return formatNumber(count);
|
||||
return this.truncateCounts ? numberToMetricPrefix(count) : formatNumber(count);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -108,8 +108,14 @@ class IssuesFinder < IssuableFinder
|
|||
|
||||
if params.filter_by_no_due_date?
|
||||
items.without_due_date
|
||||
elsif params.filter_by_any_due_date?
|
||||
items.with_due_date
|
||||
elsif params.filter_by_overdue?
|
||||
items.due_before(Date.today)
|
||||
elsif params.filter_by_due_today?
|
||||
items.due_today
|
||||
elsif params.filter_by_due_tomorrow?
|
||||
items.due_tomorrow
|
||||
elsif params.filter_by_due_this_week?
|
||||
items.due_between(Date.today.beginning_of_week, Date.today.end_of_week)
|
||||
elsif params.filter_by_due_this_month?
|
||||
|
|
|
@ -10,6 +10,10 @@ class IssuesFinder
|
|||
user_can_see_all_issues?
|
||||
end
|
||||
|
||||
def filter_by_any_due_date?
|
||||
due_date? && params[:due_date] == Issue::AnyDueDate.name
|
||||
end
|
||||
|
||||
def filter_by_no_due_date?
|
||||
due_date? && params[:due_date] == Issue::NoDueDate.name
|
||||
end
|
||||
|
@ -18,6 +22,14 @@ class IssuesFinder
|
|||
due_date? && params[:due_date] == Issue::Overdue.name
|
||||
end
|
||||
|
||||
def filter_by_due_today?
|
||||
due_date? && params[:due_date] == Issue::DueToday.name
|
||||
end
|
||||
|
||||
def filter_by_due_tomorrow?
|
||||
due_date? && params[:due_date] == Issue::DueTomorrow.name
|
||||
end
|
||||
|
||||
def filter_by_due_this_week?
|
||||
due_date? && params[:due_date] == Issue::DueThisWeek.name
|
||||
end
|
||||
|
|
|
@ -65,6 +65,8 @@ module Types
|
|||
feature_flag: :graphql_ci_runner_executor
|
||||
field :groups, ::Types::GroupType.connection_type, null: true,
|
||||
description: 'Groups the runner is associated with. For group runners only.'
|
||||
field :projects, ::Types::ProjectType.connection_type, null: true,
|
||||
description: 'Projects the runner is associated with. For project runners only.'
|
||||
|
||||
def job_count
|
||||
# We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
|
||||
|
@ -94,31 +96,42 @@ module Types
|
|||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
def groups
|
||||
BatchLoader::GraphQL.for(runner.id).batch(key: :runner_groups) do |runner_ids, loader, args|
|
||||
runner_and_namespace_ids =
|
||||
::Ci::RunnerNamespace
|
||||
.where(runner_id: runner_ids)
|
||||
.pluck(:runner_id, :namespace_id)
|
||||
return unless runner.group_type?
|
||||
|
||||
group_ids_by_runner_id = runner_and_namespace_ids.group_by(&:first).transform_values { |v| v.pluck(1) }
|
||||
group_ids = runner_and_namespace_ids.pluck(1).uniq
|
||||
|
||||
groups = Group.where(id: group_ids).index_by(&:id)
|
||||
|
||||
runner_ids.each do |runner_id|
|
||||
loader.call(runner_id, group_ids_by_runner_id[runner_id]&.map { |group_id| groups[group_id] })
|
||||
end
|
||||
end
|
||||
batched_owners(::Ci::RunnerNamespace, Group, :runner_groups, :namespace_id)
|
||||
end
|
||||
|
||||
def projects
|
||||
return unless runner.project_type?
|
||||
|
||||
batched_owners(::Ci::RunnerProject, Project, :runner_projects, :project_id)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
private
|
||||
|
||||
def can_admin_runners?
|
||||
context[:current_user]&.can_admin_all_resources?
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def batched_owners(runner_assoc_type, assoc_type, key, column_name)
|
||||
BatchLoader::GraphQL.for(runner.id).batch(key: key) do |runner_ids, loader, args|
|
||||
runner_and_owner_ids = runner_assoc_type.where(runner_id: runner_ids).pluck(:runner_id, column_name)
|
||||
|
||||
owner_ids_by_runner_id = runner_and_owner_ids.group_by(&:first).transform_values { |v| v.pluck(1) }
|
||||
owner_ids = runner_and_owner_ids.pluck(1).uniq
|
||||
|
||||
owners = assoc_type.where(id: owner_ids).index_by(&:id)
|
||||
|
||||
runner_ids.each do |runner_id|
|
||||
loader.call(runner_id, owner_ids_by_runner_id[runner_id]&.map { |owner_id| owners[owner_id] } || [])
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1284,12 +1284,6 @@ module Ci
|
|||
end
|
||||
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)
|
||||
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)
|
||||
|
|
|
@ -146,6 +146,10 @@ class ContainerRepository < ApplicationRecord
|
|||
update!(expiration_policy_started_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def migration_importing?
|
||||
migration_state == 'importing'
|
||||
end
|
||||
|
||||
def self.build_from_path(path)
|
||||
self.new(project: path.repository_project,
|
||||
name: path.repository_name)
|
||||
|
@ -169,6 +173,11 @@ class ContainerRepository < ApplicationRecord
|
|||
self.find_by!(project: path.repository_project,
|
||||
name: path.repository_name)
|
||||
end
|
||||
|
||||
def self.find_by_path(path)
|
||||
self.find_by(project: path.repository_project,
|
||||
name: path.repository_name)
|
||||
end
|
||||
end
|
||||
|
||||
ContainerRepository.prepend_mod_with('ContainerRepository')
|
||||
|
|
|
@ -29,8 +29,10 @@ class Issue < ApplicationRecord
|
|||
|
||||
DueDateStruct = Struct.new(:title, :name).freeze
|
||||
NoDueDate = DueDateStruct.new('No Due Date', '0').freeze
|
||||
AnyDueDate = DueDateStruct.new('Any Due Date', '').freeze
|
||||
AnyDueDate = DueDateStruct.new('Any Due Date', 'any').freeze
|
||||
Overdue = DueDateStruct.new('Overdue', 'overdue').freeze
|
||||
DueToday = DueDateStruct.new('Due Today', 'today').freeze
|
||||
DueTomorrow = DueDateStruct.new('Due Tomorrow', 'tomorrow').freeze
|
||||
DueThisWeek = DueDateStruct.new('Due This Week', 'week').freeze
|
||||
DueThisMonth = DueDateStruct.new('Due This Month', 'month').freeze
|
||||
DueNextMonthAndPreviousTwoWeeks = DueDateStruct.new('Due Next Month And Previous Two Weeks', 'next_month_and_previous_two_weeks').freeze
|
||||
|
@ -107,7 +109,9 @@ class Issue < ApplicationRecord
|
|||
scope :without_due_date, -> { where(due_date: nil) }
|
||||
scope :due_before, ->(date) { where('issues.due_date < ?', date) }
|
||||
scope :due_between, ->(from_date, to_date) { where('issues.due_date >= ?', from_date).where('issues.due_date <= ?', to_date) }
|
||||
scope :due_today, -> { where(due_date: Date.current) }
|
||||
scope :due_tomorrow, -> { where(due_date: Date.tomorrow) }
|
||||
|
||||
scope :not_authored_by, ->(user) { where.not(author_id: user) }
|
||||
|
||||
scope :order_due_date_asc, -> { reorder(::Gitlab::Database.nulls_last_order('due_date', 'ASC')) }
|
||||
|
|
|
@ -14,6 +14,10 @@ module Auth
|
|||
:build_destroy_container_image
|
||||
].freeze
|
||||
|
||||
FORBIDDEN_IMPORTING_SCOPES = %w[push delete *].freeze
|
||||
|
||||
ActiveImportError = Class.new(StandardError)
|
||||
|
||||
def execute(authentication_abilities:)
|
||||
@authentication_abilities = authentication_abilities
|
||||
|
||||
|
@ -26,12 +30,22 @@ module Auth
|
|||
end
|
||||
|
||||
{ token: authorized_token(*scopes).encoded }
|
||||
rescue ActiveImportError
|
||||
error(
|
||||
'DENIED',
|
||||
status: 403,
|
||||
message: 'Your repository is currently being migrated to a new platform and writes are temporarily disabled. Go to https://gitlab.com/groups/gitlab-org/-/epics/5523 to learn more.'
|
||||
)
|
||||
end
|
||||
|
||||
def self.full_access_token(*names)
|
||||
access_token(%w(*), names)
|
||||
end
|
||||
|
||||
def self.import_access_token(*names)
|
||||
access_token(%w(import), names)
|
||||
end
|
||||
|
||||
def self.pull_access_token(*names)
|
||||
access_token(['pull'], names)
|
||||
end
|
||||
|
@ -104,6 +118,8 @@ module Auth
|
|||
def process_repository_access(type, path, actions)
|
||||
return unless path.valid?
|
||||
|
||||
raise ActiveImportError if actively_importing?(actions, path)
|
||||
|
||||
requested_project = path.repository_project
|
||||
|
||||
return unless requested_project
|
||||
|
@ -129,6 +145,15 @@ module Auth
|
|||
}.compact
|
||||
end
|
||||
|
||||
def actively_importing?(actions, path)
|
||||
return false if FORBIDDEN_IMPORTING_SCOPES.intersection(actions).empty?
|
||||
|
||||
container_repository = ContainerRepository.find_by_path(path)
|
||||
return false unless container_repository
|
||||
|
||||
container_repository.migration_importing?
|
||||
end
|
||||
|
||||
def self.migration_eligible(project: nil, repository_path: nil)
|
||||
return unless Feature.enabled?(:container_registry_migration_phase1)
|
||||
|
||||
|
|
|
@ -40,17 +40,13 @@ module Ci
|
|||
new_build = clone_build(build)
|
||||
|
||||
new_build.run_after_commit do
|
||||
::Deployments::CreateForBuildService.new.execute(new_build)
|
||||
|
||||
::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!
|
||||
|
@ -74,11 +70,7 @@ module Ci
|
|||
def check_assignable_runners!(build); end
|
||||
|
||||
def clone_build(build)
|
||||
project.builds.new(build_attributes(build)).tap do |new_build|
|
||||
unless create_deployment_in_separate_transaction?
|
||||
new_build.assign_attributes(deployment_attributes_for(new_build, build))
|
||||
end
|
||||
end
|
||||
project.builds.new(build_attributes(build))
|
||||
end
|
||||
|
||||
def build_attributes(build)
|
||||
|
@ -86,7 +78,7 @@ module Ci
|
|||
[attribute, build.public_send(attribute)] # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
if create_deployment_in_separate_transaction? && build.persisted_environment.present?
|
||||
if build.persisted_environment.present?
|
||||
attributes[:metadata_attributes] ||= {}
|
||||
attributes[:metadata_attributes][:expanded_environment_name] = build.expanded_environment_name
|
||||
end
|
||||
|
@ -94,17 +86,6 @@ module Ci
|
|||
attributes[:user] = current_user
|
||||
attributes
|
||||
end
|
||||
|
||||
def deployment_attributes_for(new_build, old_build)
|
||||
::Gitlab::Ci::Pipeline::Seed::Build
|
||||
.deployment_attributes_for(new_build, old_build.persisted_environment)
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,6 +12,10 @@ class ImportExportUploader < AttachmentUploader
|
|||
end
|
||||
|
||||
def move_to_cache
|
||||
# Exports create temporary files that we can safely move.
|
||||
# Imports may be from project templates that we want to copy.
|
||||
return super if mounted_as == :export_file
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
%label.label-bold
|
||||
= s_('Profiles|Connected Accounts')
|
||||
%p= s_('Profiles|Click on icon to activate signin with one of the following services')
|
||||
%p= s_('Profiles|Select a service to sign in with.')
|
||||
- providers.each do |provider|
|
||||
- unlink_allowed = unlink_provider_allowed?(provider)
|
||||
- link_allowed = link_provider_allowed?(provider)
|
||||
|
|
|
@ -13,7 +13,6 @@ module ApplicationWorker
|
|||
include Gitlab::SidekiqVersioning::Worker
|
||||
|
||||
LOGGING_EXTRA_KEY = 'extra'
|
||||
DEFAULT_DELAY_INTERVAL = 1
|
||||
SAFE_PUSH_BULK_LIMIT = 1000
|
||||
|
||||
included do
|
||||
|
@ -92,18 +91,6 @@ module ApplicationWorker
|
|||
validate_worker_attributes!
|
||||
end
|
||||
|
||||
def perform_async(*args)
|
||||
return super if Gitlab::Database::LoadBalancing.primary_only?
|
||||
|
||||
# Worker execution for workers with data_consistency set to :delayed or :sticky
|
||||
# will be delayed to give replication enough time to complete
|
||||
if utilizes_load_balancing_capabilities? && Feature.disabled?(:skip_scheduling_workers_for_replicas, default_enabled: :yaml)
|
||||
perform_in(delay_interval, *args)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def set_queue
|
||||
queue_name = ::Gitlab::SidekiqConfig::WorkerRouter.global.route(self)
|
||||
sidekiq_options queue: queue_name # rubocop:disable Cop/SidekiqOptionsQueue
|
||||
|
@ -194,12 +181,6 @@ module ApplicationWorker
|
|||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def delay_interval
|
||||
DEFAULT_DELAY_INTERVAL.seconds
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def do_push_bulk(args_list)
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: create_deployment_in_separate_transaction
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75604
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346879
|
||||
milestone: '14.6'
|
||||
type: development
|
||||
group: group::release
|
||||
default_enabled: true
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: skip_scheduling_workers_for_replicas
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74532
|
||||
rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1380
|
||||
milestone: '14.5'
|
||||
type: development
|
||||
group: group::project management
|
||||
default_enabled: false
|
6
data/removals/14_6/limit_trigger_pipelines.yml
Normal file
6
data/removals/14_6/limit_trigger_pipelines.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
- name: "Limit the number of triggered pipeline to 25K in free tier"
|
||||
removal_date: Dec 22, 2021 # day the removal was released
|
||||
removal_milestone: "14.6"
|
||||
reporter: dhershkovitch # GitLab username of the person reporting the removal
|
||||
body: |
|
||||
A large amount of triggered pipelines in a single project impacts the performance of GitLab.com. In GitLab 14.6, we are limiting the number of triggered pipelines in a single project on GitLab.com at any given moment to 25,000. This change applies to projects in the free tier only, Premium and Ultimate are not affected by this change.
|
6
data/removals/14_6/removal-release-cli-s3.yml
Normal file
6
data/removals/14_6/removal-release-cli-s3.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
- name: "Release CLI distributed as a generic package"
|
||||
removal_date: Dec 22, 2021 # day the removal was released
|
||||
removal_milestone: "14.6"
|
||||
reporter: kbychu # GitLab username of the person reporting the removal
|
||||
body: |
|
||||
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
|
|
@ -147,9 +147,9 @@ When the list of hosts is updated, it might take a while for the old connections
|
|||
to be terminated. The `disconnect_timeout` setting can be used to enforce an
|
||||
upper limit on the time it takes to terminate all old database connections.
|
||||
|
||||
### Handling Stale Reads **(PREMIUM SELF)**
|
||||
### Handling stale reads
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3526) in GitLab 10.3.
|
||||
> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/327902) from GitLab Premium to GitLab Free in 14.0.
|
||||
|
||||
To prevent reading from an outdated secondary the load balancer checks if it
|
||||
is in sync with the primary. If the data is recent enough, the
|
||||
|
|
|
@ -9030,6 +9030,7 @@ Represents the total number of issues and their weights for a particular day.
|
|||
| <a id="cirunnermaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. |
|
||||
| <a id="cirunnerprivateprojectsminutescostfactor"></a>`privateProjectsMinutesCostFactor` | [`Float`](#float) | Private projects' "minutes cost factor" associated with the runner (GitLab.com only). |
|
||||
| <a id="cirunnerprojectcount"></a>`projectCount` | [`Int`](#int) | Number of projects that the runner is associated with. |
|
||||
| <a id="cirunnerprojects"></a>`projects` | [`ProjectConnection`](#projectconnection) | Projects the runner is associated with. For project runners only. (see [Connections](#connections)) |
|
||||
| <a id="cirunnerpublicprojectsminutescostfactor"></a>`publicProjectsMinutesCostFactor` | [`Float`](#float) | Public projects' "minutes cost factor" associated with the runner (GitLab.com only). |
|
||||
| <a id="cirunnerrevision"></a>`revision` | [`String`](#string) | Revision of the runner. |
|
||||
| <a id="cirunnerrununtagged"></a>`runUntagged` | [`Boolean!`](#boolean) | Indicates the runner is able to run untagged jobs. |
|
||||
|
|
|
@ -29,7 +29,9 @@ When requested across groups or projects, it's expected to be the same as the `f
|
|||
|
||||
## List issues
|
||||
|
||||
> The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
|
||||
> The `weight` property moved to GitLab Premium in 13.9.
|
||||
> The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
|
||||
|
||||
Get all issues the authenticated user has access to. By default it
|
||||
returns only issues created by the current user. To get all issues,
|
||||
|
@ -61,7 +63,7 @@ GET /issues?state=opened
|
|||
| `confidential` | boolean | no | Filter confidential or public issues. |
|
||||
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
|
||||
| `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), `any`, `today`, `tomorrow`, `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. |
|
||||
| `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` |
|
||||
|
@ -231,7 +233,9 @@ Please use `iid` of the `epic` attribute instead.
|
|||
|
||||
## List group issues
|
||||
|
||||
> The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
|
||||
> The `weight` property moved to GitLab Premium in 13.9.
|
||||
> The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
|
||||
|
||||
Get a list of a group's issues.
|
||||
|
||||
|
@ -264,7 +268,7 @@ GET /groups/:id/issues?state=opened
|
|||
| `confidential` | boolean | no | Filter confidential or public issues. |
|
||||
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
|
||||
| `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), `any`, `today`, `tomorrow`, `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. |
|
||||
| `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` |
|
||||
|
@ -431,7 +435,9 @@ Please use `iid` of the `epic` attribute instead.
|
|||
|
||||
## List project issues
|
||||
|
||||
> The `due_date` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3.
|
||||
> The `weight` property moved to GitLab Premium in 13.9.
|
||||
> The `due_date` filters `any`, `today`, and `tomorrow` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78460) in GitLab 14.8.
|
||||
|
||||
Get a list of a project's issues.
|
||||
|
||||
|
@ -464,7 +470,7 @@ GET /projects/:id/issues?state=opened
|
|||
| `confidential` | boolean | no | Filter confidential or public issues. |
|
||||
| `created_after` | datetime | no | Return issues created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233420) in GitLab 13.3)_ |
|
||||
| `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), `any`, `today`, `tomorrow`, `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. |
|
||||
| `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` |
|
||||
|
|
|
@ -4,7 +4,7 @@ group: Pipeline Authoring
|
|||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# GitLab CI/CD script syntax **(FREE)**
|
||||
# Format scripts and job logs **(FREE)**
|
||||
|
||||
You can use special syntax in [`script`](index.md#script) sections to:
|
||||
|
||||
|
|
67
doc/development/database/dbcheck-migrations-job.md
Normal file
67
doc/development/database/dbcheck-migrations-job.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
stage: Enablement
|
||||
group: Database
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# db:check-migrations job
|
||||
|
||||
This job runs on the test stage of a merge request pipeline. It checks:
|
||||
|
||||
1. A schema dump comparison between the author's working branch and the target branch,
|
||||
after executing a rollback of your new migrations. This check validates that the
|
||||
schema properly resets to what it was before executing this new migration.
|
||||
1. A schema dump comparison between the author's working branch and the `db/structure.sql`
|
||||
file that the author committed. This check validates that it contains all the expected changes
|
||||
in the migration.
|
||||
1. A Git diff between the `db/schema_migrations` that the author committed and the
|
||||
one that the script generated after running migrations. This check validates that everything
|
||||
was properly committed.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### False positives
|
||||
|
||||
This job is allowed to fail, because it can throw some false positives.
|
||||
|
||||
For example, when we drop a column and then roll back, this column is always
|
||||
re-added at the end of the list of columns. If the column was previously in
|
||||
the middle of the list, the rollback can't return the schema back exactly to
|
||||
its previous state. The job fails, but it's an acceptable situation.
|
||||
|
||||
For a real-life example, refer to
|
||||
[this failed job](https://gitlab.com/gitlab-org/gitlab/-/jobs/2006544972#L138).
|
||||
Here, the author dropped the `position` column.
|
||||
|
||||
### Schema dump comparison fails after rollback
|
||||
|
||||
This failure often happens if your working branch is behind the target branch.
|
||||
A real scenario:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Main((main<br>commit A)) ===> |remove constraint<br>fk_rails_dbebdaa8fe| MainB((main<br>commit B))
|
||||
Main((main<br>commit A)) --> |checkout<br>dev| DevA((dev<br>commit A)):::dev
|
||||
DevA((dev<br>commit A)) --> |add column<br>dependency_proxy_size| DevC((dev<br>commit C)):::dev
|
||||
DevC -.-> |CI pipeline<br>executes| JOB-FAILED((JOB FAILED!)):::error
|
||||
|
||||
classDef main fill:#f4f0ff,stroke:#7b58cf
|
||||
classDef dev fill:#e9f3fc,stroke:#1f75cb
|
||||
classDef error fill:#f15146,stroke:#d4121a
|
||||
```
|
||||
|
||||
1. You check out the `dev` working branch from the `main` target branch. At this point,
|
||||
each branch has their `HEAD` at commit A.
|
||||
1. Someone works on the `main` branch and drops the `fk_rails_dbebdaa8fe` constraint,
|
||||
thus creating commit B on `main`.
|
||||
1. You add column `dependency_proxy_size` to your `dev` branch.
|
||||
1. The `db:check-migrations` job fails for your `dev` branch's CI/CD pipeline, because
|
||||
the `structure.sql` file did not rollback to its expected state.
|
||||
|
||||
This happened because branch `dev` contained commits A and C, not B. Its database schema
|
||||
did not know about the removal of the `fk_rails_dbebdaa8fe` constraint. When comparing the two
|
||||
schemas, the `dev` branch contained this constraint while the `main` branch didn't.
|
||||
|
||||
This example really happened. Read the [job failure logs](https://gitlab.com/gitlab-org/gitlab/-/jobs/1992050890).
|
||||
|
||||
To fix these kind of issues, rebase the working branch onto the target branch to get the latest changes.
|
|
@ -19,6 +19,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
- [Understanding EXPLAIN plans](../understanding_explain_plans.md)
|
||||
- [explain.depesz.com](https://explain.depesz.com/) or [explain.dalibo.com](https://explain.dalibo.com/) for visualizing the output of `EXPLAIN`
|
||||
- [pgFormatter](https://sqlformat.darold.net/) a PostgreSQL SQL syntax beautifier
|
||||
- [db:check-migrations job](dbcheck-migrations-job.md)
|
||||
|
||||
## Migrations
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ If new migrations are introduced, in the MR **you are required to provide**:
|
|||
|
||||
Note that we have automated tooling for
|
||||
[GitLab](https://gitlab.com/gitlab-org/gitlab) (provided by the
|
||||
`db:check-migrations` pipeline job) that provides this output for migrations on
|
||||
[`db:check-migrations`](database/dbcheck-migrations-job.md) pipeline job) that provides this output for migrations on
|
||||
~database merge requests. You do not need to provide this information manually
|
||||
if the bot can do it for you. The bot also checks that migrations are correctly
|
||||
reversible.
|
||||
|
|
|
@ -17,9 +17,7 @@ the tiers are no longer mentioned in GitLab documentation:
|
|||
|
||||
- [Activate GitLab EE with a license](../user/admin_area/license.md)
|
||||
- [Add a help message to the sign-in page](../user/admin_area/settings/help_page.md#add-a-help-message-to-the-sign-in-page)
|
||||
- [Burndown and burnup charts](../user/project/milestones/burndown_and_burnup_charts.md),
|
||||
including [per-project charts](../user/project/milestones/index.md#project-burndown-charts) and
|
||||
[per-group charts](../user/project/milestones/index.md#group-burndown-charts)
|
||||
- [Burndown and burnup charts](../user/project/milestones/burndown_and_burnup_charts.md) in the [Milestone View](../user/project/milestones/index.md#burndown-charts),
|
||||
- [Code owners](../user/project/code_owners.md)
|
||||
- Description templates:
|
||||
- [Setting a default template for merge requests and issues](../user/project/description_templates.md#set-a-default-template-for-merge-requests-and-issues)
|
||||
|
|
|
@ -388,3 +388,13 @@ In GitLab 14.3, we will remove the ability to filter by `name` in the [list proj
|
|||
The support for [`gitlab_pages['use_legacy_storage']` setting](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) in Omnibus installations has been removed.
|
||||
|
||||
In 14.0 we removed [`domain_config_source`](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) which had been previously deprecated, and allowed users to specify disk storage. In 14.0 we added `use_legacy_storage` as a **temporary** flag to unblock upgrades, and allow us to debug issues with our users and it was deprecated and communicated for removal in 14.3.
|
||||
|
||||
## 14.6
|
||||
|
||||
### Limit the number of triggered pipeline to 25K in free tier
|
||||
|
||||
A large amount of triggered pipelines in a single project impacts the performance of GitLab.com. In GitLab 14.6, we are limiting the number of triggered pipelines in a single project on GitLab.com at any given moment to 25,000. This change applies to projects in the free tier only, Premium and Ultimate are not affected by this change.
|
||||
|
||||
### Release CLI distributed as a generic package
|
||||
|
||||
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
|
@ -211,6 +211,46 @@ scan_execution_policy:
|
|||
- scan: dast
|
||||
scanner_profile: Scanner Profile C
|
||||
site_profile: Site Profile D
|
||||
scan_result_policy:
|
||||
- name: critical vulnerability CS approvals
|
||||
description: critical severity level only for container scanning
|
||||
enabled: true
|
||||
rules:
|
||||
- type: scan_finding
|
||||
branches:
|
||||
- main
|
||||
scanners:
|
||||
- container_scanning
|
||||
vulnerabilities_allowed: 1
|
||||
severity_levels:
|
||||
- critical
|
||||
vulnerability_states:
|
||||
- newly_detected
|
||||
actions:
|
||||
- type: require_approval
|
||||
approvals_required: 1
|
||||
user_approvers:
|
||||
- adalberto.dare
|
||||
- name: secondary CS approvals
|
||||
description: secondary only for container scanning
|
||||
enabled: true
|
||||
rules:
|
||||
- type: scan_finding
|
||||
branches:
|
||||
- main
|
||||
scanners:
|
||||
- container_scanning
|
||||
vulnerabilities_allowed: 1
|
||||
severity_levels:
|
||||
- low
|
||||
- unknown
|
||||
vulnerability_states:
|
||||
- newly_detected
|
||||
actions:
|
||||
- type: require_approval
|
||||
approvals_required: 1
|
||||
user_approvers:
|
||||
- sam.white
|
||||
```
|
||||
|
||||
## Security Policy project selection
|
||||
|
@ -445,6 +485,166 @@ actions:
|
|||
- scan: container_scanning
|
||||
```
|
||||
|
||||
### Scan Result Policy editor
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77814) in GitLab 14.8 with a flag named `scan_result_policy`. Disabled by default.
|
||||
|
||||
NOTE:
|
||||
Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
|
||||
to select Security Policy Project.
|
||||
|
||||
Once your policy is complete, save it by selecting **Create merge request** at the bottom of the
|
||||
editor. This redirects you to the merge request on the project's configured security policy project.
|
||||
If a security policy project doesn't link to your project, GitLab creates such a project for you.
|
||||
Existing policies can also be removed from the editor interface by selecting **Delete policy** at
|
||||
the bottom of the editor.
|
||||
|
||||
The policy editor only supports YAML mode. To follow work on Rule mode, see the epic
|
||||
[Allow Users to Edit Rule-mode Scan Result Policies in the Policy UI](https://gitlab.com/groups/gitlab-org/-/epics/5363).
|
||||
|
||||
![Scan Result Policy Editor YAML Mode](img/scan_result_policy_yaml_mode_v14_6.png)
|
||||
|
||||
### Scan Result Policies schema
|
||||
|
||||
The YAML file with Scan Result Policies consists of an array of objects matching the Scan Result
|
||||
Policy schema nested under the `scan_result_policy` key. You can configure a maximum of five
|
||||
policies under the `scan_result_policy` key.
|
||||
|
||||
When you save a new policy, GitLab validates its contents against [this JSON schema](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/validators/json_schemas/security_orchestration_policy.json).
|
||||
If you're not familiar with how to read [JSON schemas](https://json-schema.org/),
|
||||
the following sections and tables provide an alternative.
|
||||
|
||||
| Field | Type | Possible values | Description |
|
||||
|-------|------|-----------------|-------------|
|
||||
| `scan_result_policy` | `array` of Scan Result Policy | | List of Scan Result Policies (maximum 5). |
|
||||
|
||||
### Scan Result Policy schema
|
||||
|
||||
| Field | Type | Possible values | Description |
|
||||
|-------|------|-----------------|-------------|
|
||||
| `name` | `string` | | Name of the policy. |
|
||||
| `description` (optional) | `string` | | Description of the policy. |
|
||||
| `enabled` | `boolean` | `true`, `false` | Flag to enable (`true`) or disable (`false`) the policy. |
|
||||
| `rules` | `array` of rules | | List of rules that the policy applies. |
|
||||
| `actions` | `array` of actions | | List of actions that the policy enforces. |
|
||||
|
||||
### `scan_finding` rule type
|
||||
|
||||
This rule enforces the defined actions based on the information provided.
|
||||
|
||||
| Field | Type | Possible values | Description |
|
||||
|------------|------|-----------------|-------------|
|
||||
| `type` | `string` | `scan_finding` | The rule's type. |
|
||||
| `branches` | `array` of `string` | `*` or the branch's name | The branch the given policy applies to (supports wildcard). |
|
||||
| `scanners` | `array` of `string` | `sast`, `secret_detection`, `dependency_scanning`, `container_scanning`, `dast`, `coverage_fuzzing`, `api_fuzzing` | The security scanners for this rule to consider. |
|
||||
| `vulnerabilities_allowed` | `integer` | Greater than or equal to zero | Number of vulnerabilities allowed before this rule is considered. |
|
||||
| `severity_levels` | `array` of `string` | `info`, `unknown`, `low`, `medium`, `high`, `critical`| The severity levels for this rule to consider. |
|
||||
| `vulnerability_states` | `array` of `string` | `newly_detected`, `detected`, `confirmed`, `resolved`, `dismissed` | The vulnerability states for this rule to consider when the target branch is set to the default branch. |
|
||||
|
||||
### `require_approval` action type
|
||||
|
||||
This action sets an approval rule to be required when conditions are met for at least one rule in
|
||||
the defined policy.
|
||||
|
||||
| Field | Type | Possible values | Description |
|
||||
|-------|------|-----------------|-------------|
|
||||
| `type` | `string` | `require_approval` | The action's type. |
|
||||
| `approvals_required` | `integer` | Greater than or equal to zero | The number of MR approvals required. |
|
||||
| `user_approvers` | `array` of `string` | Username of one of more users | The users to consider as approvers. |
|
||||
| `user_approvers_ids` | `array` of `integer` | ID of one of more users | The IDs of users to consider as approvers. |
|
||||
| `group_approvers` | `array` of `string` | Path of one of more groups | The groups to consider as approvers. |
|
||||
| `group_approvers_ids` | `array` of `integer` | ID of one of more groups | The IDs of groups to consider as approvers. |
|
||||
|
||||
Requirements and limitations:
|
||||
|
||||
- You must add the respective [security scanning tools](../index.md#security-scanning-tools).
|
||||
Otherwise, Scan Result Policies won't have any effect.
|
||||
- The maximum number of policies is five.
|
||||
- Each policy can have a maximum of five rules.
|
||||
|
||||
### Example security scan result policies project
|
||||
|
||||
You can use this example in a `.gitlab/security-policies/policy.yml`, as described in
|
||||
[Security policies project](#security-policies-project):
|
||||
|
||||
```yaml
|
||||
---
|
||||
scan_result_policy:
|
||||
- name: critical vulnerability CS approvals
|
||||
description: critical severity level only for container scanning
|
||||
enabled: true
|
||||
rules:
|
||||
- type: scan_finding
|
||||
branches:
|
||||
- main
|
||||
scanners:
|
||||
- container_scanning
|
||||
vulnerabilities_allowed: 0
|
||||
severity_levels:
|
||||
- critical
|
||||
vulnerability_states:
|
||||
- newly_detected
|
||||
actions:
|
||||
- type: require_approval
|
||||
approvals_required: 1
|
||||
user_approvers:
|
||||
- adalberto.dare
|
||||
- name: secondary CS approvals
|
||||
description: secondary only for container scanning
|
||||
enabled: true
|
||||
rules:
|
||||
- type: scan_finding
|
||||
branches:
|
||||
- main
|
||||
scanners:
|
||||
- container_scanning
|
||||
vulnerabilities_allowed: 1
|
||||
severity_levels:
|
||||
- low
|
||||
- unknown
|
||||
vulnerability_states:
|
||||
- newly_detected
|
||||
actions:
|
||||
- type: require_approval
|
||||
approvals_required: 1
|
||||
user_approvers:
|
||||
- sam.white
|
||||
```
|
||||
|
||||
In this example:
|
||||
|
||||
- Every MR that contains new `critical` vulnerabilities identified by container scanning requires
|
||||
one approval from `alberto.dare`.
|
||||
- Every MR that contains more than one new `low` or `unknown` vulnerability identified by container
|
||||
scanning requires one approval from `sam.white`.
|
||||
|
||||
### Example for Scan Result Policy editor
|
||||
|
||||
You can use this example in the YAML mode of the [Scan Result Policy editor](#scan-result-policy-editor).
|
||||
It corresponds to a single object from the previous example:
|
||||
|
||||
```yaml
|
||||
- name: critical vulnerability CS approvals
|
||||
description: critical severity level only for container scanning
|
||||
enabled: true
|
||||
rules:
|
||||
- type: scan_finding
|
||||
branches:
|
||||
- main
|
||||
scanners:
|
||||
- container_scanning
|
||||
vulnerabilities_allowed: 1
|
||||
severity_levels:
|
||||
- critical
|
||||
vulnerability_states:
|
||||
- newly_detected
|
||||
actions:
|
||||
- type: require_approval
|
||||
approvals_required: 1
|
||||
user_approvers:
|
||||
- adalberto.dare
|
||||
```
|
||||
|
||||
## Roadmap
|
||||
|
||||
See the [Category Direction page](https://about.gitlab.com/direction/protect/container_network_security/)
|
||||
|
|
|
@ -55,13 +55,14 @@ There are two options for deleting users:
|
|||
- **Delete user and contributions**
|
||||
|
||||
When using the **Delete user** option, not all associated records are deleted with the user.
|
||||
Here's a list of things that are **not** deleted:
|
||||
Here's a list of things created by the user that are **not** deleted:
|
||||
|
||||
- Issues that the user created.
|
||||
- Merge requests that the user created.
|
||||
- Notes that the user created.
|
||||
- Abuse reports that the user reported.
|
||||
- Award emoji that the user created.
|
||||
- Abuse reports
|
||||
- Award emoji
|
||||
- Epics
|
||||
- Issues
|
||||
- Merge requests
|
||||
- Notes
|
||||
|
||||
Instead of being deleted, these records are moved to a system-wide
|
||||
user with the username "Ghost User", whose sole purpose is to act as a container
|
||||
|
|
|
@ -6,8 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Kubernetes Logs (DEPRECATED) **(FREE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4752) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26383) to [GitLab Free](https://about.gitlab.com/pricing/) 12.9.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4752) in GitLab 11.0.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26383) from GitLab Ultimate to GitLab Free 12.9.
|
||||
> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
|
||||
|
||||
WARNING:
|
||||
|
|
|
@ -496,6 +496,9 @@ The steps depend on the scope of the list:
|
|||
|
||||
### Filter issues
|
||||
|
||||
> - Filtering by iteration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6.
|
||||
> - Filtering by issue type [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/268152) in GitLab 14.6.
|
||||
|
||||
You can use the filters on top of your issue board to show only
|
||||
the results you want. It's similar to the filtering used in the [issue tracker](issues/index.md).
|
||||
|
||||
|
@ -504,11 +507,12 @@ You can filter by the following:
|
|||
- Assignee
|
||||
- Author
|
||||
- Epic
|
||||
- Iteration ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)
|
||||
- Iteration
|
||||
- Label
|
||||
- Milestone
|
||||
- My Reaction
|
||||
- Release
|
||||
- Type (issue/incident)
|
||||
- Weight
|
||||
|
||||
#### Filtering issues in a group board
|
||||
|
|
|
@ -61,29 +61,29 @@ fields if needed, and newlines to separate rows. The first row contains the
|
|||
headers, which are listed in the following table along with a description of
|
||||
the values:
|
||||
|
||||
| Column | Description |
|
||||
|-------------------|-------------|
|
||||
| Issue ID | Issue `iid` |
|
||||
| URL | A link to the issue on GitLab |
|
||||
| Title | Issue `title` |
|
||||
| State | `Open` or `Closed` |
|
||||
| Description | Issue `description` |
|
||||
| Author | Full name of the issue author |
|
||||
| Author Username | Username of the author, with the `@` symbol omitted |
|
||||
| Assignee | Full name of the issue assignee |
|
||||
| Assignee Username | Username of the author, with the `@` symbol omitted |
|
||||
| Confidential | `Yes` or `No` |
|
||||
| Locked | `Yes` or `No` |
|
||||
| Due Date | Formatted as `YYYY-MM-DD` |
|
||||
| Created At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
|
||||
| Updated At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
|
||||
| Milestone | Title of the issue milestone |
|
||||
| Weight | Issue weight |
|
||||
| Labels | Title of any labels joined with a `,` |
|
||||
| Time Estimate | [Time estimate](../time_tracking.md#estimates) in seconds |
|
||||
| Time Spent | [Time spent](../time_tracking.md#time-spent) in seconds |
|
||||
| Epic ID | ID of the parent epic **(ULTIMATE)**, introduced in 12.7 |
|
||||
| Epic Title | Title of the parent epic **(ULTIMATE)**, introduced in 12.7 |
|
||||
| Column | Description |
|
||||
|------------------------------------------|-----------------------------------------------------------|
|
||||
| Issue ID | Issue `iid` |
|
||||
| URL | A link to the issue on GitLab |
|
||||
| Title | Issue `title` |
|
||||
| State | `Open` or `Closed` |
|
||||
| Description | Issue `description` |
|
||||
| Author | Full name of the issue author |
|
||||
| Author Username | Username of the author, with the `@` symbol omitted |
|
||||
| Assignee | Full name of the issue assignee |
|
||||
| Assignee Username | Username of the author, with the `@` symbol omitted |
|
||||
| Confidential | `Yes` or `No` |
|
||||
| Locked | `Yes` or `No` |
|
||||
| Due Date | Formatted as `YYYY-MM-DD` |
|
||||
| Created At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
|
||||
| Updated At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
|
||||
| Milestone | Title of the issue milestone |
|
||||
| Weight | Issue weight |
|
||||
| Labels | Title of any labels joined with a `,` |
|
||||
| Time Estimate | [Time estimate](../time_tracking.md#estimates) in seconds |
|
||||
| Time Spent | [Time spent](../time_tracking.md#time-spent) in seconds |
|
||||
| [Epic](../../group/epics/index.md) ID | ID of the parent epic, introduced in 12.7 |
|
||||
| [Epic](../../group/epics/index.md) Title | Title of the parent epic, introduced in 12.7 |
|
||||
|
||||
## Limitations
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Design Management **(FREE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/660) in GitLab Premium 12.2.
|
||||
> - Support for SVGs [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12771) in GitLab Premium 12.4.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) to GitLab Free in 13.0.
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/660) in GitLab 12.2.
|
||||
> - Support for SVGs [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12771) in GitLab 12.4.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) from GitLab Premium to GitLab Free in 13.0.
|
||||
|
||||
Design Management allows you to upload design assets (including wireframes and mockups)
|
||||
to GitLab issues and keep them stored in a single place, accessed by the Design
|
||||
|
@ -84,10 +84,10 @@ You can find to the **Design Management** section in the issue description:
|
|||
|
||||
## Adding designs
|
||||
|
||||
> - Drag and drop uploads [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in GitLab Premium 12.9.
|
||||
> - New version creation on upload [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in GitLab Premium 12.9.
|
||||
> - Drag and drop uploads [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in GitLab 12.9.
|
||||
> - New version creation on upload [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in GitLab 12.9.
|
||||
> - Copy and paste uploads [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202634) in GitLab 12.10.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) to GitLab Free in 13.0.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) from GitLab Premium to GitLab Free in 13.0.
|
||||
|
||||
To upload Design images, drag files from your computer and drop them in the Design Management section,
|
||||
or select **click to upload** to select images from your file browser:
|
||||
|
@ -142,9 +142,9 @@ to help summarize changes between versions.
|
|||
|
||||
### Exploring designs by zooming
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13217) in GitLab Premium 12.7.
|
||||
> - Drag to move a zoomed image [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197324) in GitLab 12.10.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) to GitLab Free in 13.0.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13217) in GitLab 12.7.
|
||||
> - Ability to drag a zoomed image to move it [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197324) in GitLab 12.10.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) from GitLab Premium to GitLab Free in 13.0.
|
||||
|
||||
Designs can be explored in greater detail by zooming in and out of the image.
|
||||
Control the amount of zoom with the `+` and `-` buttons at the bottom of the image.
|
||||
|
@ -155,8 +155,8 @@ While zoomed in, you can drag the image to move around it.
|
|||
|
||||
## Deleting designs
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11089) in GitLab Premium 12.4.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) to GitLab Free in 13.0.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11089) in GitLab 12.4.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) from GitLab Premium to GitLab Free in 13.0.
|
||||
|
||||
There are two ways to delete designs: manually delete them
|
||||
individually, or select a few of them to delete at once,
|
||||
|
@ -190,8 +190,8 @@ You can change the order of designs by dragging them to a new position.
|
|||
|
||||
## Starting discussions on designs
|
||||
|
||||
> - Adjusting a pin's position [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in GitLab Premium 12.8.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) to GitLab Free in 13.0.
|
||||
> - Adjusting a pin's position [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) adjusting a pin's position in GitLab 12.8.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) from GitLab Premium to GitLab Free in 13.0.
|
||||
|
||||
When a design is uploaded, you can start a discussion by selecting
|
||||
the image on the exact location you would like the discussion to be focused on.
|
||||
|
|
|
@ -40,6 +40,7 @@ Other coverage analysis frameworks support the format out of the box, for exampl
|
|||
|
||||
- [Istanbul](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) (JavaScript)
|
||||
- [Coverage.py](https://coverage.readthedocs.io/en/coverage-5.0.4/cmd.html#xml-reporting) (Python)
|
||||
- [PHPUnit](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/master/src/textui.rst#command-line-options) (PHP)
|
||||
|
||||
Once configured, if you create a merge request that triggers a pipeline which collects
|
||||
coverage reports, the coverage is shown in the diff view. This includes reports
|
||||
|
@ -236,7 +237,7 @@ run tests:
|
|||
image: python:3
|
||||
script:
|
||||
- pip install pytest pytest-cov
|
||||
- coverage run -m pytest
|
||||
- coverage run -m pytest
|
||||
- coverage report
|
||||
- coverage xml
|
||||
artifacts:
|
||||
|
@ -244,6 +245,42 @@ run tests:
|
|||
cobertura: coverage.xml
|
||||
```
|
||||
|
||||
### PHP example
|
||||
|
||||
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for PHP uses [PHPUnit](https://phpunit.readthedocs.io/)
|
||||
to collect test coverage data and generate the report.
|
||||
|
||||
With a minimal [`phpunit.xml`](https://phpunit.readthedocs.io/en/9.5/configuration.html) file (you may reference
|
||||
[this example repository](https://gitlab.com/yookoala/code-coverage-visualization-with-php/)), you can run the test and
|
||||
generate the coverage xml:
|
||||
|
||||
```yaml
|
||||
run tests:
|
||||
stage: test
|
||||
image: php:latest
|
||||
variables:
|
||||
XDEBUG_MODE: coverage
|
||||
before_script:
|
||||
- apt-get update && apt-get -yq install git unzip zip libzip-dev zlib1g-dev
|
||||
- docker-php-ext-install zip
|
||||
- pecl install xdebug && docker-php-ext-enable xdebug
|
||||
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||||
- composer install
|
||||
- composer require --dev phpunit/phpunit phpunit/php-code-coverage
|
||||
script:
|
||||
- php ./vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml
|
||||
artifacts:
|
||||
reports:
|
||||
cobertura: coverage.cobertura.xml
|
||||
```
|
||||
|
||||
[Codeception](https://codeception.com/), through PHPUnit, also supports generating Cobertura report with
|
||||
[`run`](https://codeception.com/docs/reference/Commands#run). The path for the generated file
|
||||
depends on the `--coverage-cobertura` option and [`paths`](https://codeception.com/docs/reference/Configuration#paths)
|
||||
configuration for the [unit test suite](https://codeception.com/docs/05-UnitTests). Configure `.gitlab-ci.yml`
|
||||
to find Cobertura in the appropriate path.
|
||||
|
||||
### C/C++ example
|
||||
|
||||
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for C/C++ with
|
||||
|
@ -272,3 +309,35 @@ run tests:
|
|||
reports:
|
||||
cobertura: build/coverage.xml
|
||||
```
|
||||
|
||||
### Go example
|
||||
|
||||
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Go uses:
|
||||
|
||||
- [`go test`](https://go.dev/doc/tutorial/add-a-test) to run tests.
|
||||
- [`gocover-cobertura`](https://github.com/t-yuki/gocover-cobertura) to convert Go's coverage profile into the Cobertura XML format.
|
||||
|
||||
This example assumes that [Go modules](https://go.dev/ref/mod) are being used.
|
||||
Using Go modules causes paths within the coverage profile to be prefixed with your
|
||||
project's module identifier, which can be found in the `go.mod` file. This
|
||||
prefix must be removed for GitLab to parse the Cobertura XML file correctly. You can use the following `sed` command to remove the prefix:
|
||||
|
||||
```shell
|
||||
sed -i 's;filename=\"<YOUR_MODULE_ID>/;filename=\";g' coverage.xml
|
||||
```
|
||||
|
||||
Replace the `gitlab.com/my-group/my-project` placeholder in the following example with your own module identifier to make it work.
|
||||
|
||||
```yaml
|
||||
run tests:
|
||||
stage: test
|
||||
image: golang:1.17
|
||||
script:
|
||||
- go install
|
||||
- go test . -coverprofile=coverage.txt -covermode count
|
||||
- go run github.com/t-yuki/gocover-cobertura < coverage.txt > coverage.xml
|
||||
- sed -i 's;filename=\"gitlab.com/my-group/my-project/;filename=\";g' coverage.xml
|
||||
artifacts:
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
```
|
||||
|
|
|
@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
![burndown and burnup chart](img/burndown_and_burnup_charts_v13_6.png)
|
||||
|
||||
## Burndown charts **(PREMIUM)**
|
||||
## Burndown charts
|
||||
|
||||
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6495) to GitLab 11.2 for group milestones.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) [fixed burndown charts](#fixed-burndown-charts) in GitLab 13.6.
|
||||
|
@ -100,7 +100,7 @@ Therefore, when the milestone start date is changed, the number of opened issues
|
|||
change.
|
||||
Reopened issues are considered as having been opened on the day after they were last closed.
|
||||
|
||||
## Burnup charts **(PREMIUM)**
|
||||
## Burnup charts
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) in GitLab 13.6.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268350) in GitLab 13.7.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB |
|
@ -56,27 +56,17 @@ If you're in a project and select **Issues > Milestones**, GitLab displays only
|
|||
NOTE:
|
||||
A permission level of [Developer or higher](../../permissions.md) is required to create milestones.
|
||||
|
||||
### New project milestone
|
||||
Milestones can be created either at project or group level.
|
||||
|
||||
To create a project milestone:
|
||||
To create a milestone:
|
||||
|
||||
1. In a project, go to **{issues}** **Issues > Milestones**.
|
||||
1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group.
|
||||
1. On the left sidebar, select **Issues > Milestones**.
|
||||
1. Select **New milestone**.
|
||||
1. Enter the title, an optional description, an optional start date, and an optional due date.
|
||||
1. Select **New milestone**.
|
||||
|
||||
![New project milestone](img/milestones_new_project_milestone.png)
|
||||
|
||||
### New group milestone
|
||||
|
||||
To create a group milestone:
|
||||
|
||||
1. In a group, go to **{issues}** **Issues > Milestones**.
|
||||
1. Select **New milestone**.
|
||||
1. Enter the title, an optional description, an optional start date, and an optional due date.
|
||||
1. Select **New milestone**.
|
||||
|
||||
![New group milestone](img/milestones_new_group_milestone_v13_5.png)
|
||||
![New milestone](img/milestones_new_project_milestone.png)
|
||||
|
||||
## Editing milestones
|
||||
|
||||
|
@ -155,24 +145,19 @@ There are also tabs below these that show the following:
|
|||
- Completed Issues (closed)
|
||||
- **Merge Requests**: Shows all merge requests assigned to the milestone. These are displayed in four columns named:
|
||||
- Work in progress (open and unassigned)
|
||||
- Waiting for merge (open and unassigned)
|
||||
- Waiting for merge (open and assigned)
|
||||
- Rejected (closed)
|
||||
- Merged
|
||||
- **Participants**: Shows all assignees of issues assigned to the milestone.
|
||||
- **Labels**: Shows all labels that are used in issues assigned to the milestone.
|
||||
|
||||
### Project Burndown Charts
|
||||
### Burndown Charts
|
||||
|
||||
For project milestones, a [burndown chart](burndown_and_burnup_charts.md) is in the milestone view,
|
||||
The milestone view contains a [burndown chart](burndown_and_burnup_charts.md),
|
||||
showing the progress of completing a milestone.
|
||||
|
||||
![burndown chart](img/burndown_chart_v13_6.png)
|
||||
|
||||
### Group Burndown Charts
|
||||
|
||||
For group milestones, a [burndown chart](burndown_and_burnup_charts.md) is in the milestone view,
|
||||
showing the progress of completing a milestone.
|
||||
|
||||
### Milestone sidebar
|
||||
|
||||
The milestone sidebar on the milestone view shows the following:
|
||||
|
|
|
@ -80,7 +80,7 @@ module API
|
|||
desc: 'Return issues ordered by `created_at`, `due_date`, `label_priority`, `milestone_due`, `popularity`, `priority`, `relative_position`, `title`, or `updated_at` fields.'
|
||||
optional :sort, type: String, values: %w[asc desc], default: 'desc',
|
||||
desc: 'Return issues sorted in `asc` or `desc` order.'
|
||||
optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '',
|
||||
optional :due_date, type: String, values: %w[0 any today tomorrow 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: WorkItems::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItems::Type.allowed_types_for_issues.join(', ')}"
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ module BitbucketServer
|
|||
end
|
||||
|
||||
def description
|
||||
project['description']
|
||||
raw['description']
|
||||
end
|
||||
|
||||
def full_name
|
||||
|
|
|
@ -21,10 +21,6 @@ module Gitlab
|
|||
merge_request: @command.merge_request,
|
||||
external_pull_request: @command.external_pull_request,
|
||||
locked: @command.project.default_pipeline_lock)
|
||||
|
||||
# Initialize the feature flag at the beginning of the pipeline creation process
|
||||
# so that the flag references in the latter chains return the same value.
|
||||
@pipeline.create_deployment_in_separate_transaction?
|
||||
end
|
||||
|
||||
def break?
|
||||
|
|
|
@ -6,8 +6,6 @@ module Gitlab
|
|||
module Chain
|
||||
class CreateDeployments < Chain::Base
|
||||
def perform!
|
||||
return unless pipeline.create_deployment_in_separate_transaction?
|
||||
|
||||
create_deployments!
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ module Gitlab
|
|||
module Chain
|
||||
class EnsureEnvironments < Chain::Base
|
||||
def perform!
|
||||
return unless pipeline.create_deployment_in_separate_transaction?
|
||||
|
||||
pipeline.stages.map(&:statuses).flatten.each(&method(:ensure_environment))
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ module Gitlab
|
|||
module Chain
|
||||
class EnsureResourceGroups < Chain::Base
|
||||
def perform!
|
||||
return unless pipeline.create_deployment_in_separate_transaction?
|
||||
|
||||
pipeline.stages.map(&:statuses).flatten.each(&method(:ensure_resource_group))
|
||||
end
|
||||
|
||||
|
|
|
@ -79,9 +79,7 @@ module Gitlab
|
|||
|
||||
def to_resource
|
||||
strong_memoize(:resource) do
|
||||
processable = initialize_processable
|
||||
assign_resource_group(processable) unless @pipeline.create_deployment_in_separate_transaction?
|
||||
processable
|
||||
initialize_processable
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,39 +87,10 @@ module Gitlab
|
|||
if bridge?
|
||||
::Ci::Bridge.new(attributes)
|
||||
else
|
||||
::Ci::Build.new(attributes).tap do |build|
|
||||
unless @pipeline.create_deployment_in_separate_transaction?
|
||||
build.assign_attributes(self.class.deployment_attributes_for(build))
|
||||
end
|
||||
end
|
||||
::Ci::Build.new(attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def assign_resource_group(processable)
|
||||
processable.resource_group =
|
||||
Seed::Processable::ResourceGroup.new(processable, @resource_group_key)
|
||||
.to_resource
|
||||
end
|
||||
|
||||
def self.deployment_attributes_for(build, environment = nil)
|
||||
return {} unless build.has_environment?
|
||||
|
||||
environment = Seed::Environment.new(build).to_resource if environment.nil?
|
||||
|
||||
unless environment.persisted?
|
||||
return { status: :failed, failure_reason: :environment_creation_failure }
|
||||
end
|
||||
|
||||
build.persisted_environment = environment
|
||||
|
||||
{
|
||||
deployment: Seed::Deployment.new(build, environment).to_resource,
|
||||
metadata_attributes: {
|
||||
expanded_environment_name: environment.name
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
delegate :logger, to: :@context
|
||||
|
|
|
@ -17799,6 +17799,9 @@ msgstr ""
|
|||
msgid "I forgot my password"
|
||||
msgstr ""
|
||||
|
||||
msgid "I understand the responsibilities involved with managing service account keys"
|
||||
msgstr ""
|
||||
|
||||
msgid "I want to explore GitLab to see if it’s worth switching to"
|
||||
msgstr ""
|
||||
|
||||
|
@ -27223,9 +27226,6 @@ msgstr ""
|
|||
msgid "Profiles|Clear status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Click on icon to activate signin with one of the following services"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Commit email"
|
||||
msgstr ""
|
||||
|
||||
|
@ -27403,6 +27403,9 @@ msgstr ""
|
|||
msgid "Profiles|Remove avatar"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Select a service to sign in with."
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Set new profile picture"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ RSpec.describe "User sorts issues" do
|
|||
page.within '.issues-list' do
|
||||
expect(page).to have_content('foo')
|
||||
expect(page).to have_content('bar')
|
||||
expect(page).to have_content('baz')
|
||||
expect(page).not_to have_content('baz')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1018,6 +1018,8 @@ RSpec.describe IssuesFinder do
|
|||
end
|
||||
|
||||
context 'filtering by due date' do
|
||||
let_it_be(:issue_due_today) { create(:issue, project: project1, due_date: Date.current) }
|
||||
let_it_be(:issue_due_tomorrow) { create(:issue, project: project1, due_date: 1.day.from_now) }
|
||||
let_it_be(:issue_overdue) { create(:issue, project: project1, due_date: 2.days.ago) }
|
||||
let_it_be(:issue_due_soon) { create(:issue, project: project1, due_date: 2.days.from_now) }
|
||||
|
||||
|
@ -1032,6 +1034,30 @@ RSpec.describe IssuesFinder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with param set to any due date' do
|
||||
let(:params) { base_params.merge(due_date: Issue::AnyDueDate.name) }
|
||||
|
||||
it 'returns issues with any due date' do
|
||||
expect(issues).to contain_exactly(issue_due_today, issue_due_tomorrow, issue_overdue, issue_due_soon)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with param set to due today' do
|
||||
let(:params) { base_params.merge(due_date: Issue::DueToday.name) }
|
||||
|
||||
it 'returns issues due today' do
|
||||
expect(issues).to contain_exactly(issue_due_today)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with param set to due tomorrow' do
|
||||
let(:params) { base_params.merge(due_date: Issue::DueTomorrow.name) }
|
||||
|
||||
it 'returns issues due today' do
|
||||
expect(issues).to contain_exactly(issue_due_tomorrow)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with param set to overdue' do
|
||||
let(:params) { base_params.merge(due_date: Issue::Overdue.name) }
|
||||
|
||||
|
@ -1043,8 +1069,8 @@ RSpec.describe IssuesFinder do
|
|||
context 'with param set to next month and previous two weeks' do
|
||||
let(:params) { base_params.merge(due_date: Issue::DueNextMonthAndPreviousTwoWeeks.name) }
|
||||
|
||||
it 'returns issues from the previous two weeks and next month' do
|
||||
expect(issues).to contain_exactly(issue_overdue, issue_due_soon)
|
||||
it 'returns issues due in the previous two weeks and next month' do
|
||||
expect(issues).to contain_exactly(issue_due_today, issue_due_tomorrow, issue_overdue, issue_due_soon)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { __, s__ } from '~/locale';
|
||||
import { formatDate } from '~/lib/utils/datetime_utility';
|
||||
import { useFakeDate } from 'helpers/fake_date';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
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', () => {
|
||||
useFakeDate(2022, 0, 8, 16);
|
||||
|
||||
const deployment = resolvedEnvironment.lastDeployment;
|
||||
let wrapper;
|
||||
|
||||
|
@ -125,4 +129,23 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('created at time', () => {
|
||||
describe('is present', () => {
|
||||
it('shows the timestamp the deployment was deployed at', () => {
|
||||
wrapper = createWrapper();
|
||||
const date = wrapper.findByTitle(formatDate(deployment.createdAt));
|
||||
|
||||
expect(date.text()).toBe('1 day ago');
|
||||
});
|
||||
});
|
||||
describe('is not present', () => {
|
||||
it('does not show the timestamp', () => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { createdAt: null } } });
|
||||
const date = wrapper.findByTitle(formatDate(deployment.createdAt));
|
||||
|
||||
expect(date.exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import { GlButton, GlFormGroup, GlFormSelect } from '@gitlab/ui';
|
||||
import { GlButton, GlFormGroup, GlFormSelect, GlFormCheckbox } from '@gitlab/ui';
|
||||
import ServiceAccountsForm from '~/google_cloud/components/service_accounts_form.vue';
|
||||
|
||||
describe('ServiceAccountsForm component', () => {
|
||||
|
@ -9,11 +9,12 @@ describe('ServiceAccountsForm component', () => {
|
|||
const findAllFormGroups = () => wrapper.findAllComponents(GlFormGroup);
|
||||
const findAllFormSelects = () => wrapper.findAllComponents(GlFormSelect);
|
||||
const findAllButtons = () => wrapper.findAllComponents(GlButton);
|
||||
const findCheckbox = () => wrapper.findComponent(GlFormCheckbox);
|
||||
|
||||
const propsData = { gcpProjects: [], environments: [], cancelPath: '#cancel-url' };
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallowMount(ServiceAccountsForm, { propsData });
|
||||
wrapper = shallowMount(ServiceAccountsForm, { propsData, stubs: { GlFormCheckbox } });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -35,8 +36,8 @@ describe('ServiceAccountsForm component', () => {
|
|||
});
|
||||
|
||||
it('contains Environments form group', () => {
|
||||
const formGorup = findAllFormGroups().at(1);
|
||||
expect(formGorup.exists()).toBe(true);
|
||||
const formGroup = findAllFormGroups().at(1);
|
||||
expect(formGroup.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('contains Environments dropdown', () => {
|
||||
|
@ -56,4 +57,14 @@ describe('ServiceAccountsForm component', () => {
|
|||
expect(button.text()).toBe(ServiceAccountsForm.i18n.cancelLabel);
|
||||
expect(button.attributes('href')).toBe('#cancel-url');
|
||||
});
|
||||
|
||||
it('contains Confirmation checkbox', () => {
|
||||
const checkbox = findCheckbox();
|
||||
expect(checkbox.text()).toBe(ServiceAccountsForm.i18n.checkboxLabel);
|
||||
});
|
||||
|
||||
it('checkbox must be required', () => {
|
||||
const checkbox = findCheckbox();
|
||||
expect(checkbox.attributes('required')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
bytesToMiB,
|
||||
bytesToGiB,
|
||||
numberToHumanSize,
|
||||
numberToMetricPrefix,
|
||||
sum,
|
||||
isOdd,
|
||||
median,
|
||||
|
@ -99,6 +100,21 @@ describe('Number Utils', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('numberToMetricPrefix', () => {
|
||||
it.each`
|
||||
number | expected
|
||||
${123} | ${'123'}
|
||||
${1234} | ${'1.2k'}
|
||||
${12345} | ${'12.3k'}
|
||||
${123456} | ${'123.5k'}
|
||||
${1234567} | ${'1.2m'}
|
||||
${12345678} | ${'12.3m'}
|
||||
${123456789} | ${'123.5m'}
|
||||
`('returns $expected given $number', ({ number, expected }) => {
|
||||
expect(numberToMetricPrefix(number)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sum', () => {
|
||||
it('should add up two values', () => {
|
||||
expect(sum(1, 2)).toEqual(3);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { GlIcon } from '@gitlab/ui';
|
||||
import { GlIcon, GlButton } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
|
@ -103,7 +103,7 @@ describe('Sidebar Todo Widget', () => {
|
|||
});
|
||||
|
||||
it('sets default tooltip title', () => {
|
||||
expect(wrapper.find(GlIcon).attributes('title')).toBe('Add a to do');
|
||||
expect(wrapper.find(GlButton).attributes('title')).toBe('Add a to do');
|
||||
});
|
||||
|
||||
it('when user has a to do', async () => {
|
||||
|
@ -113,7 +113,7 @@ describe('Sidebar Todo Widget', () => {
|
|||
|
||||
await waitForPromises();
|
||||
expect(wrapper.find(GlIcon).props('name')).toBe('todo-done');
|
||||
expect(wrapper.find(GlIcon).attributes('title')).toBe('Mark as done');
|
||||
expect(wrapper.find(GlButton).attributes('title')).toBe('Mark as done');
|
||||
});
|
||||
|
||||
it('emits `todoUpdated` event on click on icon', async () => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { GlTab, GlBadge } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
import { mount, shallowMount } from '@vue/test-utils';
|
||||
import { setLanguage } from 'helpers/locale_helper';
|
||||
|
||||
import IssuableTabs from '~/vue_shared/issuable/list/components/issuable_tabs.vue';
|
||||
|
@ -10,17 +11,18 @@ const createComponent = ({
|
|||
tabs = mockIssuableListProps.tabs,
|
||||
tabCounts = mockIssuableListProps.tabCounts,
|
||||
currentTab = mockIssuableListProps.currentTab,
|
||||
truncateCounts = false,
|
||||
mountFn = shallowMount,
|
||||
} = {}) =>
|
||||
mount(IssuableTabs, {
|
||||
mountFn(IssuableTabs, {
|
||||
propsData: {
|
||||
tabs,
|
||||
tabCounts,
|
||||
currentTab,
|
||||
truncateCounts,
|
||||
},
|
||||
slots: {
|
||||
'nav-actions': `
|
||||
<button class="js-new-issuable">New issuable</button>
|
||||
`,
|
||||
'nav-actions': `<button class="js-new-issuable">New issuable</button>`,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -29,7 +31,6 @@ describe('IssuableTabs', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
setLanguage('en');
|
||||
wrapper = createComponent();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -40,60 +41,71 @@ describe('IssuableTabs', () => {
|
|||
const findAllGlBadges = () => wrapper.findAllComponents(GlBadge);
|
||||
const findAllGlTabs = () => wrapper.findAllComponents(GlTab);
|
||||
|
||||
describe('methods', () => {
|
||||
describe('isTabActive', () => {
|
||||
it.each`
|
||||
tabName | currentTab | returnValue
|
||||
${'opened'} | ${'opened'} | ${true}
|
||||
${'opened'} | ${'closed'} | ${false}
|
||||
`(
|
||||
'returns $returnValue when tab name is "$tabName" is current tab is "$currentTab"',
|
||||
async ({ tabName, currentTab, returnValue }) => {
|
||||
wrapper.setProps({
|
||||
currentTab,
|
||||
});
|
||||
describe('tabs', () => {
|
||||
it.each`
|
||||
currentTab | returnValue
|
||||
${'opened'} | ${'true'}
|
||||
${'closed'} | ${undefined}
|
||||
`(
|
||||
'when "$currentTab" is the selected tab, the Open tab is active=$returnValue',
|
||||
({ currentTab, returnValue }) => {
|
||||
wrapper = createComponent({ currentTab });
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
const openTab = findAllGlTabs().at(0);
|
||||
|
||||
expect(wrapper.vm.isTabActive(tabName)).toBe(returnValue);
|
||||
},
|
||||
);
|
||||
});
|
||||
expect(openTab.attributes('active')).toBe(returnValue);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
it('renders gl-tab for each tab within `tabs` array', () => {
|
||||
const tabsEl = findAllGlTabs();
|
||||
wrapper = createComponent();
|
||||
|
||||
expect(tabsEl.exists()).toBe(true);
|
||||
expect(tabsEl).toHaveLength(mockIssuableListProps.tabs.length);
|
||||
const tabs = findAllGlTabs();
|
||||
|
||||
expect(tabs).toHaveLength(mockIssuableListProps.tabs.length);
|
||||
});
|
||||
|
||||
it('renders gl-badge component within a tab', () => {
|
||||
it('renders gl-badge component within a tab', async () => {
|
||||
wrapper = createComponent({ mountFn: mount });
|
||||
await nextTick();
|
||||
|
||||
const badges = findAllGlBadges();
|
||||
|
||||
// Does not render `All` badge since it has an undefined count
|
||||
expect(badges).toHaveLength(2);
|
||||
expect(badges.at(0).text()).toBe('5,000');
|
||||
expect(badges.at(0).text()).toBe('5,678');
|
||||
expect(badges.at(1).text()).toBe(`${mockIssuableListProps.tabCounts.closed}`);
|
||||
});
|
||||
|
||||
it('renders contents for slot "nav-actions"', () => {
|
||||
const buttonEl = wrapper.find('button.js-new-issuable');
|
||||
wrapper = createComponent();
|
||||
|
||||
expect(buttonEl.exists()).toBe(true);
|
||||
expect(buttonEl.text()).toBe('New issuable');
|
||||
const button = wrapper.find('button.js-new-issuable');
|
||||
|
||||
expect(button.text()).toBe('New issuable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('counts', () => {
|
||||
it('can display as truncated', async () => {
|
||||
wrapper = createComponent({ truncateCounts: true, mountFn: mount });
|
||||
await nextTick();
|
||||
|
||||
expect(findAllGlBadges().at(0).text()).toBe('5.7k');
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', () => {
|
||||
it('gl-tab component emits `click` event on `click` event', () => {
|
||||
const tabEl = findAllGlTabs().at(0);
|
||||
wrapper = createComponent();
|
||||
|
||||
tabEl.vm.$emit('click', 'opened');
|
||||
const openTab = findAllGlTabs().at(0);
|
||||
|
||||
expect(wrapper.emitted('click')).toBeTruthy();
|
||||
expect(wrapper.emitted('click')[0]).toEqual(['opened']);
|
||||
openTab.vm.$emit('click', 'opened');
|
||||
|
||||
expect(wrapper.emitted('click')).toEqual([['opened']]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -133,7 +133,7 @@ export const mockTabs = [
|
|||
];
|
||||
|
||||
export const mockTabCounts = {
|
||||
opened: 5000,
|
||||
opened: 5678,
|
||||
closed: 0,
|
||||
all: undefined,
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ RSpec.describe GitlabSchema.types['CiRunner'] do
|
|||
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 edit_admin_url user_permissions executor_name
|
||||
groups
|
||||
groups projects
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
|
|
|
@ -9,6 +9,7 @@ RSpec.describe BitbucketServer::Representation::Repo do
|
|||
"slug": "rouge",
|
||||
"id": 1,
|
||||
"name": "rouge",
|
||||
"description": "Rogue Repo",
|
||||
"scmId": "git",
|
||||
"state": "AVAILABLE",
|
||||
"statusMessage": "Available",
|
||||
|
@ -17,7 +18,7 @@ RSpec.describe BitbucketServer::Representation::Repo do
|
|||
"key": "TEST",
|
||||
"id": 1,
|
||||
"name": "test",
|
||||
"description": "Test",
|
||||
"description": "Test Project",
|
||||
"public": false,
|
||||
"type": "NORMAL",
|
||||
"links": {
|
||||
|
@ -73,7 +74,7 @@ RSpec.describe BitbucketServer::Representation::Repo do
|
|||
end
|
||||
|
||||
describe '#description' do
|
||||
it { expect(subject.description).to eq('Test') }
|
||||
it { expect(subject.description).to eq('Rogue Repo') }
|
||||
end
|
||||
|
||||
describe '#full_name' do
|
||||
|
|
|
@ -47,18 +47,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CreateDeployments do
|
|||
expect(job.deployment).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when create_deployment_in_separate_transaction feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(create_deployment_in_separate_transaction: false)
|
||||
end
|
||||
|
||||
it 'does not create a deployment record' do
|
||||
expect { subject }.not_to change { Deployment.count }
|
||||
|
||||
expect(job.deployment).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a pipeline contains a teardown job' do
|
||||
|
|
|
@ -57,18 +57,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::EnsureEnvironments do
|
|||
expect(job.persisted_environment).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when create_deployment_in_separate_transaction feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(create_deployment_in_separate_transaction: false)
|
||||
end
|
||||
|
||||
it 'does not create any environments' do
|
||||
expect { subject }.not_to change { Environment.count }
|
||||
|
||||
expect(job.persisted_environment).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a pipeline contains a teardown job' do
|
||||
|
|
|
@ -60,18 +60,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::EnsureResourceGroups do
|
|||
expect(job.resource_group).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when create_deployment_in_separate_transaction feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(create_deployment_in_separate_transaction: false)
|
||||
end
|
||||
|
||||
it 'does not create any resource groups' do
|
||||
expect { subject }.not_to change { Ci::ResourceGroup.count }
|
||||
|
||||
expect(job.resource_group).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a pipeline does not contain a job that requires a resource group' do
|
||||
|
|
|
@ -411,171 +411,6 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
|
|||
describe '#to_resource' do
|
||||
subject { seed_build.to_resource }
|
||||
|
||||
before do
|
||||
stub_feature_flags(create_deployment_in_separate_transaction: false)
|
||||
end
|
||||
|
||||
context 'when job is Ci::Build' do
|
||||
it { is_expected.to be_a(::Ci::Build) }
|
||||
it { is_expected.to be_valid }
|
||||
|
||||
shared_examples_for 'deployment job' do
|
||||
it 'returns a job with deployment' do
|
||||
expect { subject }.to change { Environment.count }.by(1)
|
||||
|
||||
expect(subject.deployment).not_to be_nil
|
||||
expect(subject.deployment.deployable).to eq(subject)
|
||||
expect(subject.deployment.environment.name).to eq(expected_environment_name)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'non-deployment job' do
|
||||
it 'returns a job without deployment' do
|
||||
expect(subject.deployment).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'ensures environment existence' do
|
||||
it 'has environment' do
|
||||
expect { subject }.to change { Environment.count }.by(1)
|
||||
|
||||
expect(subject).to be_has_environment
|
||||
expect(subject.environment).to eq(environment_name)
|
||||
expect(subject.metadata.expanded_environment_name).to eq(expected_environment_name)
|
||||
expect(Environment.exists?(name: expected_environment_name)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'ensures environment inexistence' do
|
||||
it 'does not have environment' do
|
||||
expect { subject }.not_to change { Environment.count }
|
||||
|
||||
expect(subject).not_to be_has_environment
|
||||
expect(subject.environment).to be_nil
|
||||
expect(subject.metadata&.expanded_environment_name).to be_nil
|
||||
expect(Environment.exists?(name: expected_environment_name)).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when job deploys to production' do
|
||||
let(:environment_name) { 'production' }
|
||||
let(:expected_environment_name) { 'production' }
|
||||
let(:attributes) { { name: 'deploy', ref: 'master', environment: 'production' } }
|
||||
|
||||
it_behaves_like 'deployment job'
|
||||
it_behaves_like 'ensures environment existence'
|
||||
|
||||
context 'when create_deployment_in_separate_transaction feature flag is enabled' do
|
||||
before do
|
||||
stub_feature_flags(create_deployment_in_separate_transaction: true)
|
||||
end
|
||||
|
||||
it 'does not create any deployments nor environments' do
|
||||
expect(subject.deployment).to be_nil
|
||||
expect(Environment.count).to eq(0)
|
||||
expect(Deployment.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the environment name is invalid' do
|
||||
let(:attributes) { { name: 'deploy', ref: 'master', environment: '!!!' } }
|
||||
|
||||
it 'fails the job with a failure reason and does not create an environment' do
|
||||
expect(subject).to be_failed
|
||||
expect(subject).to be_environment_creation_failure
|
||||
expect(subject.metadata.expanded_environment_name).to be_nil
|
||||
expect(Environment.exists?(name: expected_environment_name)).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when job starts a review app' do
|
||||
let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
|
||||
let(:expected_environment_name) { "review/#{pipeline.ref}" }
|
||||
|
||||
let(:attributes) do
|
||||
{
|
||||
name: 'deploy', ref: 'master', environment: environment_name,
|
||||
options: { environment: { name: environment_name } }
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'deployment job'
|
||||
it_behaves_like 'ensures environment existence'
|
||||
end
|
||||
|
||||
context 'when job stops a review app' do
|
||||
let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
|
||||
let(:expected_environment_name) { "review/#{pipeline.ref}" }
|
||||
|
||||
let(:attributes) do
|
||||
{
|
||||
name: 'deploy', ref: 'master', environment: environment_name,
|
||||
options: { environment: { name: environment_name, action: 'stop' } }
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns a job without deployment' do
|
||||
expect(subject.deployment).to be_nil
|
||||
end
|
||||
|
||||
it_behaves_like 'non-deployment job'
|
||||
it_behaves_like 'ensures environment existence'
|
||||
end
|
||||
|
||||
context 'when job belongs to a resource group' do
|
||||
let(:resource_group) { 'iOS' }
|
||||
let(:attributes) { { name: 'rspec', ref: 'master', resource_group_key: resource_group, environment: 'production' }}
|
||||
|
||||
it 'returns a job with resource group' do
|
||||
expect(subject.resource_group).not_to be_nil
|
||||
expect(subject.resource_group.key).to eq('iOS')
|
||||
expect(Ci::ResourceGroup.count).to eq(1)
|
||||
end
|
||||
|
||||
context 'when create_deployment_in_separate_transaction feature flag is enabled' do
|
||||
before do
|
||||
stub_feature_flags(create_deployment_in_separate_transaction: true)
|
||||
end
|
||||
|
||||
it 'does not create any resource groups' do
|
||||
expect(subject.resource_group).to be_nil
|
||||
expect(Ci::ResourceGroup.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when resource group has $CI_ENVIRONMENT_NAME in it' do
|
||||
let(:resource_group) { 'test/$CI_ENVIRONMENT_NAME' }
|
||||
|
||||
it 'expands environment name' do
|
||||
expect(subject.resource_group.key).to eq('test/production')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when job is a bridge' do
|
||||
let(:base_attributes) do
|
||||
{
|
||||
name: 'rspec', ref: 'master', options: { trigger: 'my/project' }, scheduling_type: :stage
|
||||
}
|
||||
end
|
||||
|
||||
let(:attributes) { base_attributes }
|
||||
|
||||
it { is_expected.to be_a(::Ci::Bridge) }
|
||||
it { is_expected.to be_valid }
|
||||
|
||||
context 'when job belongs to a resource group' do
|
||||
let(:attributes) { base_attributes.merge(resource_group_key: 'iOS') }
|
||||
|
||||
it 'returns a job with resource group' do
|
||||
expect(subject.resource_group).not_to be_nil
|
||||
expect(subject.resource_group.key).to eq('iOS')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'memoizes a resource object' do
|
||||
expect(subject.object_id).to eq seed_build.to_resource.object_id
|
||||
end
|
||||
|
|
|
@ -330,6 +330,52 @@ RSpec.describe ContainerRepository do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.find_by_path' do
|
||||
let_it_be(:container_repository) { create(:container_repository) }
|
||||
let_it_be(:repository_path) { container_repository.project.full_path }
|
||||
|
||||
let(:path) { ContainerRegistry::Path.new(repository_path + '/' + container_repository.name) }
|
||||
|
||||
subject { described_class.find_by_path(path) }
|
||||
|
||||
context 'when repository exists' do
|
||||
it 'finds the repository' do
|
||||
expect(subject).to eq(container_repository)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when repository does not exist' do
|
||||
let(:path) { ContainerRegistry::Path.new(repository_path + '/some/image') }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(subject).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.find_by_path!' do
|
||||
let_it_be(:container_repository) { create(:container_repository) }
|
||||
let_it_be(:repository_path) { container_repository.project.full_path }
|
||||
|
||||
let(:path) { ContainerRegistry::Path.new(repository_path + '/' + container_repository.name) }
|
||||
|
||||
subject { described_class.find_by_path!(path) }
|
||||
|
||||
context 'when repository exists' do
|
||||
it 'finds the repository' do
|
||||
expect(subject).to eq(container_repository)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when repository does not exist' do
|
||||
let(:path) { ContainerRegistry::Path.new(repository_path + '/some/image') }
|
||||
|
||||
it 'raises an exception' do
|
||||
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.build_root_repository' do
|
||||
let(:repository) do
|
||||
described_class.build_root_repository(project)
|
||||
|
@ -458,6 +504,24 @@ RSpec.describe ContainerRepository do
|
|||
it { is_expected.to eq([repository]) }
|
||||
end
|
||||
|
||||
describe '#migration_importing?' do
|
||||
let_it_be_with_reload(:container_repository) { create(:container_repository, migration_state: 'importing')}
|
||||
|
||||
subject { container_repository.migration_importing? }
|
||||
|
||||
it { is_expected.to eq(true) }
|
||||
|
||||
context 'when not importing' do
|
||||
before do
|
||||
# Technical debt: when the state machine is added, we should iterate through all possible states
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78499
|
||||
container_repository.update_column(:migration_state, 'default')
|
||||
end
|
||||
|
||||
it { is_expected.to eq(false) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with repositories' do
|
||||
let_it_be_with_reload(:repository) { create(:container_repository, :cleanup_unscheduled) }
|
||||
let_it_be(:other_repository) { create(:container_repository, :cleanup_unscheduled) }
|
||||
|
|
|
@ -25,6 +25,8 @@ RSpec.describe 'Query.runner(id)' do
|
|||
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :shell)
|
||||
end
|
||||
|
||||
let_it_be(:active_project_runner) { create(:ci_runner, :project) }
|
||||
|
||||
def get_runner(id)
|
||||
case id
|
||||
when :active_instance_runner
|
||||
|
@ -33,6 +35,8 @@ RSpec.describe 'Query.runner(id)' do
|
|||
inactive_instance_runner
|
||||
when :active_group_runner
|
||||
active_group_runner
|
||||
when :active_project_runner
|
||||
active_project_runner
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -55,7 +59,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
|
||||
runner = get_runner(runner_id)
|
||||
expect(runner_data).to match a_hash_including(
|
||||
'id' => "gid://gitlab/Ci::Runner/#{runner.id}",
|
||||
'id' => runner.to_global_id.to_s,
|
||||
'description' => runner.description,
|
||||
'createdAt' => runner.created_at&.iso8601,
|
||||
'contactedAt' => runner.contacted_at&.iso8601,
|
||||
|
@ -103,7 +107,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
|
||||
runner = get_runner(runner_id)
|
||||
expect(runner_data).to match a_hash_including(
|
||||
'id' => "gid://gitlab/Ci::Runner/#{runner.id}",
|
||||
'id' => runner.to_global_id.to_s,
|
||||
'adminUrl' => nil
|
||||
)
|
||||
expect(runner_data['tagList']).to match_array runner.tag_list
|
||||
|
@ -179,7 +183,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
runner_data = graphql_data_at(:runner)
|
||||
|
||||
expect(runner_data).to match a_hash_including(
|
||||
'id' => "gid://gitlab/Ci::Runner/#{project_runner.id}",
|
||||
'id' => project_runner.to_global_id.to_s,
|
||||
'locked' => is_locked
|
||||
)
|
||||
end
|
||||
|
@ -216,7 +220,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
a_hash_including(
|
||||
'webUrl' => "http://localhost/groups/#{group.full_path}/-/runners/#{active_group_runner.id}",
|
||||
'node' => {
|
||||
'id' => "gid://gitlab/Ci::Runner/#{active_group_runner.id}"
|
||||
'id' => active_group_runner.to_global_id.to_s
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -227,7 +231,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
let(:query) do
|
||||
%(
|
||||
query {
|
||||
runner(id: "gid://gitlab/Ci::Runner/#{active_group_runner.id}") {
|
||||
runner(id: "#{active_group_runner.to_global_id}") {
|
||||
groups {
|
||||
nodes {
|
||||
id
|
||||
|
@ -302,21 +306,36 @@ RSpec.describe 'Query.runner(id)' do
|
|||
|
||||
let!(:job) { create(:ci_build, runner: project_runner1) }
|
||||
|
||||
context 'requesting project and job counts' do
|
||||
context 'requesting projects and counts for projects and jobs' do
|
||||
let(:query) do
|
||||
%(
|
||||
query {
|
||||
projectRunner1: runner(id: "#{project_runner1.to_global_id}") {
|
||||
projectCount
|
||||
jobCount
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectRunner2: runner(id: "#{project_runner2.to_global_id}") {
|
||||
projectCount
|
||||
jobCount
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
activeInstanceRunner: runner(id: "#{active_instance_runner.to_global_id}") {
|
||||
projectCount
|
||||
jobCount
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -335,13 +354,23 @@ RSpec.describe 'Query.runner(id)' do
|
|||
|
||||
expect(runner1_data).to match a_hash_including(
|
||||
'jobCount' => 1,
|
||||
'projectCount' => 2)
|
||||
'projectCount' => 2,
|
||||
'projects' => {
|
||||
'nodes' => [
|
||||
{ 'id' => project1.to_global_id.to_s },
|
||||
{ 'id' => project2.to_global_id.to_s }
|
||||
]
|
||||
})
|
||||
expect(runner2_data).to match a_hash_including(
|
||||
'jobCount' => 0,
|
||||
'projectCount' => 0)
|
||||
'projectCount' => 0,
|
||||
'projects' => {
|
||||
'nodes' => []
|
||||
})
|
||||
expect(runner3_data).to match a_hash_including(
|
||||
'jobCount' => 0,
|
||||
'projectCount' => nil)
|
||||
'projectCount' => nil,
|
||||
'projects' => nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -356,6 +385,10 @@ RSpec.describe 'Query.runner(id)' do
|
|||
context 'on group runner' do
|
||||
it_behaves_like 'retrieval by unauthorized user', :active_group_runner
|
||||
end
|
||||
|
||||
context 'on project runner' do
|
||||
it_behaves_like 'retrieval by unauthorized user', :active_project_runner
|
||||
end
|
||||
end
|
||||
|
||||
describe 'by non-admin user' do
|
||||
|
|
|
@ -488,6 +488,8 @@ RSpec.describe API::Issues do
|
|||
let_it_be(:issue3) { create(:issue, project: project, author: user, due_date: frozen_time + 10.days) }
|
||||
let_it_be(:issue4) { create(:issue, project: project, author: user, due_date: frozen_time + 34.days) }
|
||||
let_it_be(:issue5) { create(:issue, project: project, author: user, due_date: frozen_time - 8.days) }
|
||||
let_it_be(:issue6) { create(:issue, project: project, author: user, due_date: frozen_time) }
|
||||
let_it_be(:issue7) { create(:issue, project: project, author: user, due_date: frozen_time + 1.day) }
|
||||
|
||||
before do
|
||||
travel_to(frozen_time)
|
||||
|
@ -500,7 +502,13 @@ RSpec.describe API::Issues do
|
|||
it 'returns them all when argument is empty' do
|
||||
get api('/issues?due_date=', user)
|
||||
|
||||
expect_paginated_array_response(issue5.id, issue4.id, issue3.id, issue2.id, issue.id, closed_issue.id)
|
||||
expect_paginated_array_response(issue7.id, issue6.id, issue5.id, issue4.id, issue3.id, issue2.id, issue.id, closed_issue.id)
|
||||
end
|
||||
|
||||
it 'returns issues with due date' do
|
||||
get api('/issues?due_date=any', user)
|
||||
|
||||
expect_paginated_array_response(issue7.id, issue6.id, issue5.id, issue4.id, issue3.id, issue2.id)
|
||||
end
|
||||
|
||||
it 'returns issues without due date' do
|
||||
|
@ -512,19 +520,31 @@ RSpec.describe API::Issues do
|
|||
it 'returns issues due for this week' do
|
||||
get api('/issues?due_date=week', user)
|
||||
|
||||
expect_paginated_array_response(issue2.id)
|
||||
expect_paginated_array_response(issue7.id, issue6.id, issue2.id)
|
||||
end
|
||||
|
||||
it 'returns issues due for this month' do
|
||||
get api('/issues?due_date=month', user)
|
||||
|
||||
expect_paginated_array_response(issue3.id, issue2.id)
|
||||
expect_paginated_array_response(issue7.id, issue6.id, issue3.id, issue2.id)
|
||||
end
|
||||
|
||||
it 'returns issues that are due previous two weeks and next month' do
|
||||
get api('/issues?due_date=next_month_and_previous_two_weeks', user)
|
||||
|
||||
expect_paginated_array_response(issue5.id, issue4.id, issue3.id, issue2.id)
|
||||
expect_paginated_array_response(issue7.id, issue6.id, issue5.id, issue4.id, issue3.id, issue2.id)
|
||||
end
|
||||
|
||||
it 'returns issues that are due today' do
|
||||
get api('/issues?due_date=today', user)
|
||||
|
||||
expect_paginated_array_response(issue6.id)
|
||||
end
|
||||
|
||||
it 'returns issues that are due tomorrow' do
|
||||
get api('/issues?due_date=tomorrow', user)
|
||||
|
||||
expect_paginated_array_response(issue7.id)
|
||||
end
|
||||
|
||||
it 'returns issues that are overdue' do
|
||||
|
|
|
@ -370,23 +370,6 @@ RSpec.describe Ci::RetryBuildService do
|
|||
it_behaves_like 'when build with deployment is retried'
|
||||
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
|
||||
|
||||
it_behaves_like 'when build with deployment is retried'
|
||||
it_behaves_like 'when build with dynamic environment is retried'
|
||||
end
|
||||
|
||||
context 'when build has needs' do
|
||||
before do
|
||||
create(:ci_build_need, build: build, name: 'build1')
|
||||
|
|
|
@ -167,7 +167,7 @@ RSpec.shared_examples 'a container registry auth service' do
|
|||
stub_feature_flags(container_registry_cdn_redirect: false)
|
||||
end
|
||||
|
||||
describe '#full_access_token' do
|
||||
describe '.full_access_token' do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:token) { described_class.full_access_token(project.full_path) }
|
||||
|
@ -181,7 +181,21 @@ RSpec.shared_examples 'a container registry auth service' do
|
|||
it_behaves_like 'not a container repository factory'
|
||||
end
|
||||
|
||||
describe '#pull_access_token' do
|
||||
describe '.import_access_token' do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:token) { described_class.import_access_token(project.full_path) }
|
||||
|
||||
subject { { token: token } }
|
||||
|
||||
it_behaves_like 'an accessible' do
|
||||
let(:actions) { ['import'] }
|
||||
end
|
||||
|
||||
it_behaves_like 'not a container repository factory'
|
||||
end
|
||||
|
||||
describe '.pull_access_token' do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let(:token) { described_class.pull_access_token(project.full_path) }
|
||||
|
@ -1126,4 +1140,72 @@ RSpec.shared_examples 'a container registry auth service' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when importing' do
|
||||
let_it_be(:container_repository) { create(:container_repository, :root, migration_state: 'importing') }
|
||||
let_it_be(:current_project) { container_repository.project }
|
||||
let_it_be(:current_user) { create(:user) }
|
||||
|
||||
before do
|
||||
current_project.add_developer(current_user)
|
||||
end
|
||||
|
||||
shared_examples 'containing the import error' do
|
||||
it 'includes a helpful error message' do
|
||||
expect(subject[:errors].first).to include(message: /Your repository is currently being migrated/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'push request' do
|
||||
let(:current_params) do
|
||||
{ scopes: ["repository:#{container_repository.path}:push"] }
|
||||
end
|
||||
|
||||
it_behaves_like 'a forbidden' do
|
||||
it_behaves_like 'containing the import error'
|
||||
end
|
||||
end
|
||||
|
||||
context 'delete request' do
|
||||
let(:current_params) do
|
||||
{ scopes: ["repository:#{container_repository.path}:delete"] }
|
||||
end
|
||||
|
||||
it_behaves_like 'a forbidden' do
|
||||
it_behaves_like 'containing the import error'
|
||||
end
|
||||
end
|
||||
|
||||
context '* request' do
|
||||
let(:current_params) do
|
||||
{ scopes: ["repository:#{container_repository.path}:*"] }
|
||||
end
|
||||
|
||||
it_behaves_like 'a forbidden' do
|
||||
it_behaves_like 'containing the import error'
|
||||
end
|
||||
end
|
||||
|
||||
context 'pull request' do
|
||||
let(:current_params) do
|
||||
{ scopes: ["repository:#{container_repository.path}:pull"] }
|
||||
end
|
||||
|
||||
let(:project) { current_project }
|
||||
|
||||
it_behaves_like 'a pullable'
|
||||
end
|
||||
|
||||
context 'mixed request' do
|
||||
let(:current_params) do
|
||||
{ scopes: ["repository:#{container_repository.path}:pull,push"] }
|
||||
end
|
||||
|
||||
let(:project) { current_project }
|
||||
|
||||
it_behaves_like 'a forbidden' do
|
||||
it_behaves_like 'containing the import error'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,20 @@ RSpec.describe ImportExportUploader do
|
|||
subject { described_class.new(model, :import_file) }
|
||||
|
||||
context 'local store' do
|
||||
describe '#move_to_cache' do
|
||||
it 'returns false' do
|
||||
expect(subject.move_to_cache).to be false
|
||||
end
|
||||
|
||||
context 'with project export' do
|
||||
subject { described_class.new(model, :export_file) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(subject.move_to_cache).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#move_to_store' do
|
||||
it 'returns true' do
|
||||
expect(subject.move_to_store).to be true
|
||||
|
@ -33,6 +47,20 @@ RSpec.describe ImportExportUploader do
|
|||
let(:fixture) { File.join('spec', 'fixtures', 'group_export.tar.gz') }
|
||||
end
|
||||
|
||||
describe '#move_to_cache' do
|
||||
it 'returns false' do
|
||||
expect(subject.move_to_cache).to be false
|
||||
end
|
||||
|
||||
context 'with project export' do
|
||||
subject { described_class.new(model, :export_file) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(subject.move_to_cache).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#move_to_store' do
|
||||
it 'returns false' do
|
||||
expect(subject.move_to_store).to be false
|
||||
|
|
|
@ -247,45 +247,6 @@ RSpec.describe ApplicationWorker do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.perform_async' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:primary_only?, :skip_scheduling_ff, :data_consistency, :schedules_job?) do
|
||||
true | false | :sticky | false
|
||||
true | false | :delayed | false
|
||||
true | false | :always | false
|
||||
true | true | :sticky | false
|
||||
true | true | :delayed | false
|
||||
true | true | :always | false
|
||||
false | false | :sticky | true
|
||||
false | false | :delayed | true
|
||||
false | false | :always | false
|
||||
false | true | :sticky | false
|
||||
false | true | :delayed | false
|
||||
false | true | :always | false
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const(worker.name, worker)
|
||||
worker.data_consistency(data_consistency)
|
||||
|
||||
allow(Gitlab::Database::LoadBalancing).to receive(:primary_only?).and_return(primary_only?)
|
||||
stub_feature_flags(skip_scheduling_workers_for_replicas: skip_scheduling_ff)
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'schedules or enqueues the job correctly' do
|
||||
if schedules_job?
|
||||
expect(worker).to receive(:perform_in).with(described_class::DEFAULT_DELAY_INTERVAL.seconds, 123)
|
||||
else
|
||||
expect(worker).not_to receive(:perform_in)
|
||||
end
|
||||
|
||||
worker.perform_async(123)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'different kinds of push_bulk' do
|
||||
shared_context 'set safe limit beyond the number of jobs to be enqueued' do
|
||||
before do
|
||||
|
|
Loading…
Reference in a new issue