Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-04-07 18:08:29 +00:00
parent fe4751154c
commit c2bdb9d027
68 changed files with 1795 additions and 931 deletions

View File

@ -16,7 +16,7 @@ stages:
# in cases where jobs require Docker-in-Docker, the job
# definition must be extended with `.use-docker-in-docker`
default:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
image: $DEFAULT_CI_IMAGE
tags:
- gitlab-org
# All jobs are interruptible by default
@ -58,6 +58,8 @@ workflow:
- if: '$CI_COMMIT_BRANCH =~ /^security\//'
variables:
PG_VERSION: "12"
DEFAULT_CI_IMAGE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-${PG_VERSION}-graphicsmagick-1.3.36"
RAILS_ENV: "test"
NODE_ENV: "test"
BUNDLE_WITHOUT: "production:development"

View File

@ -44,16 +44,16 @@
- lib/gitlab/setup_helper.rb
prefix: "gitaly-binaries-${DEBIAN-VERSION}"
paths:
- tmp/tests/gitaly/_build/bin/
- tmp/tests/gitaly/_build/deps/git/install/
- tmp/tests/gitaly/config.toml
- tmp/tests/gitaly/gitaly2.config.toml
- tmp/tests/gitaly/internal/
- tmp/tests/gitaly/run/
- tmp/tests/gitaly/run2/
- tmp/tests/gitaly/Makefile
- tmp/tests/gitaly/praefect.config.toml
- tmp/tests/gitaly/ruby/
- ${TMP_TEST_FOLDER}/gitaly/_build/bin/
- ${TMP_TEST_FOLDER}/gitaly/_build/deps/git/install/
- ${TMP_TEST_FOLDER}/gitaly/config.toml
- ${TMP_TEST_FOLDER}/gitaly/gitaly2.config.toml
- ${TMP_TEST_FOLDER}/gitaly/internal/
- ${TMP_TEST_FOLDER}/gitaly/run/
- ${TMP_TEST_FOLDER}/gitaly/run2/
- ${TMP_TEST_FOLDER}/gitaly/Makefile
- ${TMP_TEST_FOLDER}/gitaly/praefect.config.toml
- ${TMP_TEST_FOLDER}/gitaly/ruby/
policy: pull
.go-pkg-cache: &go-pkg-cache
@ -214,34 +214,33 @@
- *storybook-node-modules-cache-push
.use-pg11:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine
variables:
POSTGRES_HOST_AUTH_METHOD: trust
PG_VERSION: "11"
.use-pg12:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-12-graphicsmagick-1.3.36
services:
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:6.0-alpine
variables:
POSTGRES_HOST_AUTH_METHOD: trust
PG_VERSION: "12"
.use-pg13:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-13-graphicsmagick-1.3.36
services:
- name: postgres:13
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine
variables:
POSTGRES_HOST_AUTH_METHOD: trust
PG_VERSION: "13"
.use-pg11-ee:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@ -250,9 +249,9 @@
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
PG_VERSION: "11"
.use-pg12-ee:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-12-graphicsmagick-1.3.36
services:
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@ -261,9 +260,9 @@
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
PG_VERSION: "12"
.use-pg13-ee:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-13-graphicsmagick-1.3.36
services:
- name: postgres:13
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@ -272,6 +271,7 @@
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
PG_VERSION: "13"
.use-kaniko:
image:

View File

@ -124,7 +124,6 @@ linters:
- Performance/RedundantMatch
- Performance/StringReplacement
- Rails/LinkToBlank
- Rails/Presence
- Rails/RequestReferer
- Style/ColonMethodCall
- Style/ConditionalAssignment

View File

@ -25,15 +25,6 @@ Layout/MultilineOperationIndentation:
Layout/SpaceInLambdaLiteral:
Enabled: false
# Offense count: 1209
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideBlockBraces:
Enabled: false
EnforcedStyle: space
# Offense count: 585
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
@ -41,22 +32,6 @@ Layout/SpaceInsideBlockBraces:
Layout/SpaceInsideParens:
Enabled: false
# Offense count: 18
Lint/BinaryOperatorWithIdenticalOperands:
Exclude:
- 'ee/spec/lib/ee/gitlab/application_context_spec.rb'
- 'spec/helpers/visibility_level_helper_spec.rb'
- 'spec/lib/gitlab/conan_token_spec.rb'
- 'spec/lib/gitlab/git/conflict/parser_spec.rb'
- 'spec/lib/gitlab/graphql/lazy_spec.rb'
- 'spec/models/ci/build_trace_chunk_spec.rb'
- 'spec/models/clusters/platforms/kubernetes_spec.rb'
- 'spec/models/concerns/where_composite_spec.rb'
- 'spec/models/metrics/dashboard/annotation_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/models/ssh_host_key_spec.rb'
- 'spec/tooling/danger/sidekiq_queues_spec.rb'
# Offense count: 84
Lint/ConstantDefinitionInBlock:
Enabled: false

View File

@ -0,0 +1,770 @@
---
# Cop supports --auto-correct.
Layout/SpaceInsideBlockBraces:
# Offense count: 1508
# Temporarily disabled due to too many offenses
Enabled: false
EnforcedStyle: space
Exclude:
- 'app/controllers/groups/boards_controller.rb'
- 'app/controllers/profiles/two_factor_auths_controller.rb'
- 'app/controllers/projects/boards_controller.rb'
- 'app/experiments/security_reports_mr_widget_prompt_experiment.rb'
- 'app/experiments/video_tutorials_continuous_onboarding_experiment.rb'
- 'app/graphql/types/concerns/find_closest.rb'
- 'app/helpers/favicon_helper.rb'
- 'app/helpers/time_zone_helper.rb'
- 'app/helpers/todos_helper.rb'
- 'app/models/authentication_event.rb'
- 'app/models/bulk_imports/entity.rb'
- 'app/models/ci/pipeline.rb'
- 'app/models/concerns/cache_markdown_field.rb'
- 'app/models/concerns/featurable.rb'
- 'app/models/integrations/bamboo.rb'
- 'app/models/integrations/buildkite.rb'
- 'app/models/integrations/teamcity.rb'
- 'app/models/network/graph.rb'
- 'app/models/operations/feature_flag.rb'
- 'app/models/packages/package.rb'
- 'app/models/preloaders/labels_preloader.rb'
- 'app/models/project.rb'
- 'app/models/release.rb'
- 'app/models/release_highlight.rb'
- 'app/services/authorized_project_update/project_recalculate_service.rb'
- 'app/services/notification_service.rb'
- 'config/initializers/wikicloth_redos_patch.rb'
- 'db/post_migrate/20210707210916_finalize_ci_stages_bigint_conversion.rb'
- 'db/post_migrate/20210802043253_finalize_push_event_payloads_bigint_conversion_3.rb'
- 'ee/app/finders/security/training_providers/base_url_finder.rb'
- 'ee/app/graphql/mutations/incident_management/oncall_rotation/base.rb'
- 'ee/app/helpers/ee/dashboard_helper.rb'
- 'ee/app/models/approvals/scan_finding_wrapped_rule_set.rb'
- 'ee/app/models/compliance_management/framework.rb'
- 'ee/app/models/dora/daily_metrics.rb'
- 'ee/app/models/ee/application_setting.rb'
- 'ee/app/models/ee/member.rb'
- 'ee/app/models/vulnerabilities/identifier.rb'
- 'ee/app/serializers/vulnerabilities/finding_entity.rb'
- 'ee/app/services/elastic/cluster_reindexing_service.rb'
- 'ee/lib/ee/banzai/filter/references/iteration_reference_filter.rb'
- 'ee/lib/ee/gitlab/auth/ldap/group.rb'
- 'ee/lib/ee/gitlab/background_migration/drop_invalid_remediations.rb'
- 'ee/lib/elastic/latest/git_class_proxy.rb'
- 'ee/lib/gitlab/auth/smartcard/san_extension.rb'
- 'ee/lib/pseudonymizer/dumper.rb'
- 'ee/lib/world.rb'
- 'ee/spec/controllers/autocomplete_controller_spec.rb'
- 'ee/spec/controllers/countries_controller_spec.rb'
- 'ee/spec/controllers/groups/epics_controller_spec.rb'
- 'ee/spec/controllers/projects/issues_controller_spec.rb'
- 'ee/spec/controllers/projects/pipelines_controller_spec.rb'
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
- 'ee/spec/elastic_integration/global_search_spec.rb'
- 'ee/spec/factories/dast/profiles_pipelines.rb'
- 'ee/spec/factories/licenses.rb'
- 'ee/spec/features/billings/billing_plans_spec.rb'
- 'ee/spec/features/boards/board_filters_spec.rb'
- 'ee/spec/features/boards/scoped_issue_board_spec.rb'
- 'ee/spec/features/boards/swimlanes/epics_swimlanes_filtering_spec.rb'
- 'ee/spec/features/epics/todo_spec.rb'
- 'ee/spec/features/google_analytics_datalayer_spec.rb'
- 'ee/spec/features/groups/issues_spec.rb'
- 'ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb'
- 'ee/spec/features/issues/form_spec.rb'
- 'ee/spec/features/issues/issue_sidebar_spec.rb'
- 'ee/spec/features/issues/user_edits_issue_spec.rb'
- 'ee/spec/features/merge_request/user_edits_multiple_reviewers_mr_spec.rb'
- 'ee/spec/features/merge_request/user_sees_closing_issues_message_spec.rb'
- 'ee/spec/features/merge_requests/user_resets_approvers_spec.rb'
- 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
- 'ee/spec/features/projects/integrations/user_activates_github_spec.rb'
- 'ee/spec/features/projects/push_rules_spec.rb'
- 'ee/spec/features/projects/security/dast_scanner_profiles_spec.rb'
- 'ee/spec/features/projects/security/dast_site_profiles_spec.rb'
- 'ee/spec/features/projects/settings/ee/service_desk_setting_spec.rb'
- 'ee/spec/finders/billed_users_finder_spec.rb'
- 'ee/spec/finders/clusters/environments_finder_spec.rb'
- 'ee/spec/finders/dast/profiles_finder_spec.rb'
- 'ee/spec/finders/ee/namespaces/projects_finder_spec.rb'
- 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb'
- 'ee/spec/finders/security/training_providers/kontra_url_finder_spec.rb'
- 'ee/spec/finders/security/vulnerabilities_finder_spec.rb'
- 'ee/spec/finders/security/vulnerability_reads_finder_spec.rb'
- 'ee/spec/finders/status_page/incidents_finder_spec.rb'
- 'ee/spec/frontend/fixtures/epic.rb'
- 'ee/spec/frontend/fixtures/projects.rb'
- 'ee/spec/graphql/ee/resolvers/namespace_projects_resolver_spec.rb'
- 'ee/spec/graphql/mutations/boards/epics/create_spec.rb'
- 'ee/spec/graphql/mutations/compliance_management/frameworks/destroy_spec.rb'
- 'ee/spec/graphql/mutations/dast_site_validations/revoke_spec.rb'
- 'ee/spec/graphql/mutations/incident_management/escalation_policy/create_spec.rb'
- 'ee/spec/graphql/mutations/releases/update_spec.rb'
- 'ee/spec/graphql/mutations/vulnerabilities/destroy_external_issue_link_spec.rb'
- 'ee/spec/graphql/resolvers/iterations_resolver_spec.rb'
- 'ee/spec/helpers/ee/projects/pipeline_helper_spec.rb'
- 'ee/spec/helpers/ee/projects/security/dast_configuration_helper_spec.rb'
- 'ee/spec/helpers/ee/registrations_helper_spec.rb'
- 'ee/spec/helpers/ee/trial_helper_spec.rb'
- 'ee/spec/helpers/projects/on_demand_scans_helper_spec.rb'
- 'ee/spec/lib/analytics/group_activity_calculator_spec.rb'
- 'ee/spec/lib/ee/gitlab/alert_management/payload/generic_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/drop_invalid_remediations_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/migrate_job_artifact_registry_to_ssf_spec.rb'
- 'ee/spec/lib/ee/gitlab/ci/reports/security/reports_spec.rb'
- 'ee/spec/lib/ee/gitlab/import_export/group/tree_saver_spec.rb'
- 'ee/spec/lib/ee/gitlab/import_export/project/tree_restorer_spec.rb'
- 'ee/spec/lib/ee/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb'
- 'ee/spec/lib/ee/sidebars/groups/menus/issues_menu_spec.rb'
- 'ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb'
- 'ee/spec/lib/ee/sidebars/projects/menus/ci_cd_menu_spec.rb'
- 'ee/spec/lib/ee/sidebars/projects/menus/issues_menu_spec.rb'
- 'ee/spec/lib/ee/sidebars/projects/menus/repository_menu_spec.rb'
- 'ee/spec/lib/gitlab/auth/group_saml/gma_membership_enforcer_spec.rb'
- 'ee/spec/lib/gitlab/auth/otp/session_enforcer_spec.rb'
- 'ee/spec/lib/gitlab/ci/parsers/security/container_scanning_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/license_scanning/dependency_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/finding_spec.rb'
- 'ee/spec/lib/gitlab/ci/templates/dependency_scanning_gitlab_ci_yaml_spec.rb'
- 'ee/spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
- 'ee/spec/lib/gitlab/geo/git_ssh_proxy_spec.rb'
- 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_renamed_event_spec.rb'
- 'ee/spec/lib/gitlab/git_access_spec.rb'
- 'ee/spec/lib/gitlab/graphql/loaders/bulk_epic_aggregate_loader_spec.rb'
- 'ee/spec/lib/gitlab/ip_address_state_spec.rb'
- 'ee/spec/lib/gitlab/search_context/builder_spec.rb'
- 'ee/spec/lib/gitlab/status_page/filter/image_filter_spec.rb'
- 'ee/spec/lib/gitlab/usage/metrics/instrumentations/approval_project_rules_with_user_metric_spec.rb'
- 'ee/spec/lib/pseudonymizer/pager_spec.rb'
- 'ee/spec/lib/pseudonymizer/uploader_spec.rb'
- 'ee/spec/mailers/credentials_inventory_mailer_spec.rb'
- 'ee/spec/migrations/geo/migrate_job_artifact_registry_spec.rb'
- 'ee/spec/models/analytics/devops_adoption/enabled_namespace_spec.rb'
- 'ee/spec/models/analytics/devops_adoption/snapshot_spec.rb'
- 'ee/spec/models/approval_project_rule_spec.rb'
- 'ee/spec/models/approval_state_spec.rb'
- 'ee/spec/models/approvals/scan_finding_wrapped_rule_set_spec.rb'
- 'ee/spec/models/ci/minutes/limit_spec.rb'
- 'ee/spec/models/compliance_management/framework_spec.rb'
- 'ee/spec/models/concerns/ee/clusters/agents/authorization_config_scopes_spec.rb'
- 'ee/spec/models/concerns/elastic/issue_spec.rb'
- 'ee/spec/models/dast/profile_schedule_spec.rb'
- 'ee/spec/models/ee/audit_event_spec.rb'
- 'ee/spec/models/ee/ci/build_dependencies_spec.rb'
- 'ee/spec/models/ee/iteration_spec.rb'
- 'ee/spec/models/ee/namespace/root_storage_size_spec.rb'
- 'ee/spec/models/ee/namespace_limit_spec.rb'
- 'ee/spec/models/environment_spec.rb'
- 'ee/spec/models/epic_spec.rb'
- 'ee/spec/models/gitlab/seat_link_data_spec.rb'
- 'ee/spec/models/gitlab_subscription_spec.rb'
- 'ee/spec/models/member_spec.rb'
- 'ee/spec/models/milestone_release_spec.rb'
- 'ee/spec/models/project_member_spec.rb'
- 'ee/spec/models/protected_environment_spec.rb'
- 'ee/spec/models/push_rule_spec.rb'
- 'ee/spec/models/requirements_management/test_report_spec.rb'
- 'ee/spec/models/security/orchestration_policy_rule_schedule_spec.rb'
- 'ee/spec/models/vulnerabilities/feedback_spec.rb'
- 'ee/spec/models/vulnerabilities/finding_spec.rb'
- 'ee/spec/presenters/epic_issue_presenter_spec.rb'
- 'ee/spec/requests/api/analytics/code_review_analytics_spec.rb'
- 'ee/spec/requests/api/analytics/group_activity_analytics_spec.rb'
- 'ee/spec/requests/api/ci/minutes_spec.rb'
- 'ee/spec/requests/api/epic_links_spec.rb'
- 'ee/spec/requests/api/graphql/boards/board_lists_query_spec.rb'
- 'ee/spec/requests/api/graphql/group/epic/epic_aggregate_query_spec.rb'
- 'ee/spec/requests/api/graphql/group/epic/epic_issues_spec.rb'
- 'ee/spec/requests/api/graphql/group_query_spec.rb'
- 'ee/spec/requests/api/graphql/iteration_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/dast_site_validations/revoke_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/incident_management/oncall_rotation/update_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/releases/create_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/releases/update_spec.rb'
- 'ee/spec/requests/api/graphql/project/dast_profiles_spec.rb'
- 'ee/spec/requests/api/graphql/project/dast_site_validations_spec.rb'
- 'ee/spec/requests/api/graphql/project/issues_spec.rb'
- 'ee/spec/requests/api/graphql/projects/compliance_frameworks_spec.rb'
- 'ee/spec/requests/api/group_variables_spec.rb'
- 'ee/spec/requests/api/internal/base_spec.rb'
- 'ee/spec/requests/api/managed_licenses_spec.rb'
- 'ee/spec/requests/api/members_spec.rb'
- 'ee/spec/requests/api/projects_spec.rb'
- 'ee/spec/requests/api/protected_branches_spec.rb'
- 'ee/spec/requests/api/releases_spec.rb'
- 'ee/spec/requests/groups/contribution_analytics_spec.rb'
- 'ee/spec/requests/lfs_http_spec.rb'
- 'ee/spec/requests/projects/security/policies_controller_spec.rb'
- 'ee/spec/requests/survey_responses_controller_spec.rb'
- 'ee/spec/serializers/member_user_entity_spec.rb'
- 'ee/spec/serializers/merge_request_poll_widget_entity_spec.rb'
- 'ee/spec/serializers/vulnerabilities/finding_reports_comparer_entity_spec.rb'
- 'ee/spec/services/audit_events/register_runner_audit_event_service_spec.rb'
- 'ee/spec/services/audit_events/unregister_runner_audit_event_service_spec.rb'
- 'ee/spec/services/auto_merge/add_to_merge_train_when_pipeline_succeeds_service_spec.rb'
- 'ee/spec/services/auto_merge/merge_train_service_spec.rb'
- 'ee/spec/services/ci/runners/register_runner_service_spec.rb'
- 'ee/spec/services/ee/design_management/delete_designs_service_spec.rb'
- 'ee/spec/services/ee/design_management/save_designs_service_spec.rb'
- 'ee/spec/services/ee/issuable/bulk_update_service_spec.rb'
- 'ee/spec/services/ee/notes/quick_actions_service_spec.rb'
- 'ee/spec/services/ee/notification_service_spec.rb'
- 'ee/spec/services/ee/vulnerability_feedback_module/update_service_spec.rb'
- 'ee/spec/services/epic_issues/create_service_spec.rb'
- 'ee/spec/services/epics/create_service_spec.rb'
- 'ee/spec/services/epics/descendant_count_service_spec.rb'
- 'ee/spec/services/epics/transfer_service_spec.rb'
- 'ee/spec/services/geo/container_repository_sync_service_spec.rb'
- 'ee/spec/services/geo/framework_repository_sync_service_spec.rb'
- 'ee/spec/services/geo/hashed_storage_attachments_event_store_spec.rb'
- 'ee/spec/services/geo/repository_sync_service_spec.rb'
- 'ee/spec/services/geo/wiki_sync_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/activate_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/apply_trial_service_spec.rb'
- 'ee/spec/services/group_saml/sign_up_service_spec.rb'
- 'ee/spec/services/groups/epics_count_service_spec.rb'
- 'ee/spec/services/groups/memberships/export_service_spec.rb'
- 'ee/spec/services/iterations/cadences/create_iterations_in_advance_service_spec.rb'
- 'ee/spec/services/merge_trains/check_status_service_spec.rb'
- 'ee/spec/services/personal_access_tokens/groups/update_lifetime_service_spec.rb'
- 'ee/spec/services/projects/destroy_service_spec.rb'
- 'ee/spec/services/projects/update_mirror_service_spec.rb'
- 'ee/spec/services/quick_actions/interpret_service_spec.rb'
- 'ee/spec/services/requirements_management/create_requirement_service_spec.rb'
- 'ee/spec/services/requirements_management/update_requirement_service_spec.rb'
- 'ee/spec/services/resource_access_tokens/create_service_spec.rb'
- 'ee/spec/services/search/group_service_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_findings_spec.rb'
- 'ee/spec/services/security/security_orchestration_policies/policy_commit_service_spec.rb'
- 'ee/spec/services/sitemap/create_service_spec.rb'
- 'ee/spec/services/software_license_policies/update_service_spec.rb'
- 'ee/spec/services/status_page/publish_attachments_service_spec.rb'
- 'ee/spec/services/system_notes/epics_service_spec.rb'
- 'ee/spec/services/vulnerability_external_issue_links/create_service_spec.rb'
- 'ee/spec/services/vulnerability_feedback/destroy_service_spec.rb'
- 'ee/spec/support/shared_examples/features/ultimate_trial_callout_shared_examples.rb'
- 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/base_sync_service_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/boards/base_service_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/search_notes_shared_examples.rb'
- 'ee/spec/tasks/gitlab/elastic_rake_spec.rb'
- 'ee/spec/uploaders/every_gitlab_uploader_spec.rb'
- 'ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb'
- 'ee/spec/views/shared/billings/_eoa_bronze_plan_banner.html.haml_spec.rb'
- 'ee/spec/views/shared/credentials_inventory/_expiry_date.html.haml_spec.rb'
- 'ee/spec/views/shared/credentials_inventory/personal_access_tokens/_personal_access_token.html.haml_spec.rb'
- 'ee/spec/views/shared/credentials_inventory/ssh_keys/_ssh_key.html.haml_spec.rb'
- 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb'
- 'ee/spec/workers/adjourned_projects_deletion_cron_worker_spec.rb'
- 'ee/spec/workers/security/create_orchestration_policy_worker_spec.rb'
- 'ee/spec/workers/security/orchestration_policy_rule_schedule_worker_spec.rb'
- 'lib/api/commits.rb'
- 'lib/api/helpers/merge_requests_helpers.rb'
- 'lib/backup/manager.rb'
- 'lib/banzai/filter/references/label_reference_filter.rb'
- 'lib/banzai/filter/references/milestone_reference_filter.rb'
- 'lib/bitbucket/representation/base.rb'
- 'lib/bitbucket_server/representation/base.rb'
- 'lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb'
- 'lib/gitlab/contributions_calendar.rb'
- 'lib/gitlab/database/migrations/test_background_runner.rb'
- 'lib/gitlab/database/postgres_hll/buckets.rb'
- 'lib/gitlab/elasticsearch/logs/lines.rb'
- 'lib/gitlab/email/message/in_product_marketing/helper.rb'
- 'lib/gitlab/issues/rebalancing/state.rb'
- 'lib/gitlab/profiler.rb'
- 'lib/kramdown/converter/commonmark.rb'
- 'lib/release_highlights/validator/entry.rb'
- 'lib/security/ci_configuration/sast_build_action.rb'
- 'lib/tasks/gitlab/db.rake'
- 'lib/tasks/gitlab/info.rake'
- 'lib/tasks/gitlab/praefect.rake'
- 'lib/tasks/gitlab/shell.rake'
- 'lib/tasks/gitlab/tw/codeowners.rake'
- 'qa/qa/service/praefect_manager.rb'
- 'qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb'
- 'qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb'
- 'qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb'
- 'qa/qa/specs/features/ee/browser_ui/11_fulfillment/license/cloud_activation_spec.rb'
- 'qa/qa/specs/features/ee/browser_ui/11_fulfillment/license/license_spec.rb'
- 'qa/qa/specs/features/ee/browser_ui/12_geo/geo_replication_npm_registry_spec.rb'
- 'qa/spec/scenario/test/integration/mattermost_spec.rb'
- 'qa/spec/support/page_error_checker_spec.rb'
- 'rubocop/cop/migration/add_limit_to_text_columns.rb'
- 'spec/config/settings_spec.rb'
- 'spec/controllers/admin/application_settings_controller_spec.rb'
- 'spec/controllers/application_controller_spec.rb'
- 'spec/controllers/groups/labels_controller_spec.rb'
- 'spec/controllers/groups/releases_controller_spec.rb'
- 'spec/controllers/groups/settings/ci_cd_controller_spec.rb'
- 'spec/controllers/import/manifest_controller_spec.rb'
- 'spec/controllers/projects/blame_controller_spec.rb'
- 'spec/controllers/projects/deploy_keys_controller_spec.rb'
- 'spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb'
- 'spec/controllers/projects/feature_flags_controller_spec.rb'
- 'spec/controllers/projects/jobs_controller_spec.rb'
- 'spec/controllers/projects/labels_controller_spec.rb'
- 'spec/controllers/projects/notes_controller_spec.rb'
- 'spec/controllers/projects/releases_controller_spec.rb'
- 'spec/controllers/projects/tree_controller_spec.rb'
- 'spec/controllers/registrations/welcome_controller_spec.rb'
- 'spec/controllers/snippets/notes_controller_spec.rb'
- 'spec/dependencies/omniauth_saml_spec.rb'
- 'spec/experiments/application_experiment_spec.rb'
- 'spec/factories/ci/build_trace_chunks.rb'
- 'spec/factories/ci/job_artifacts.rb'
- 'spec/factories/ci/pipeline_artifacts.rb'
- 'spec/factories/commit_statuses.rb'
- 'spec/factories/emails.rb'
- 'spec/factories/external_pull_requests.rb'
- 'spec/factories/gitlab/database/postgres_index.rb'
- 'spec/factories/packages/dependencies.rb'
- 'spec/factories/packages/package_tags.rb'
- 'spec/factories/packages/packages.rb'
- 'spec/factories/prometheus_alert.rb'
- 'spec/factories/prometheus_metrics.rb'
- 'spec/features/admin/admin_mode/login_spec.rb'
- 'spec/features/admin/users/users_spec.rb'
- 'spec/features/boards/board_filters_spec.rb'
- 'spec/features/boards/reload_boards_on_browser_back_spec.rb'
- 'spec/features/dashboard/archived_projects_spec.rb'
- 'spec/features/error_tracking/user_filters_errors_by_status_spec.rb'
- 'spec/features/groups/issues_spec.rb'
- 'spec/features/groups_spec.rb'
- 'spec/features/issuables/user_sees_sidebar_spec.rb'
- 'spec/features/issues/gfm_autocomplete_spec.rb'
- 'spec/features/issues/todo_spec.rb'
- 'spec/features/issues/user_bulk_edits_issues_spec.rb'
- 'spec/features/issues/user_interacts_with_awards_spec.rb'
- 'spec/features/issues/user_uses_quick_actions_spec.rb'
- 'spec/features/merge_request/user_approves_spec.rb'
- 'spec/features/merge_request/user_customizes_merge_commit_message_spec.rb'
- 'spec/features/merge_request/user_edits_assignees_sidebar_spec.rb'
- 'spec/features/merge_request/user_sees_closing_issues_message_spec.rb'
- 'spec/features/merge_request/user_sees_deployment_widget_spec.rb'
- 'spec/features/merge_request/user_sees_diff_spec.rb'
- 'spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb'
- 'spec/features/merge_request/user_sees_versions_spec.rb'
- 'spec/features/merge_request/user_uses_quick_actions_spec.rb'
- 'spec/features/profiles/user_edit_profile_spec.rb'
- 'spec/features/projects/cluster_agents_spec.rb'
- 'spec/features/projects/commits/user_browses_commits_spec.rb'
- 'spec/features/projects/environments/environment_spec.rb'
- 'spec/features/projects/files/user_browses_files_spec.rb'
- 'spec/features/projects/pipelines/pipelines_spec.rb'
- 'spec/features/projects/settings/service_desk_setting_spec.rb'
- 'spec/features/projects/tree/tree_show_spec.rb'
- 'spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb'
- 'spec/features/users/login_spec.rb'
- 'spec/finders/ci/jobs_finder_spec.rb'
- 'spec/finders/ci/runners_finder_spec.rb'
- 'spec/finders/concerns/packages/finder_helper_spec.rb'
- 'spec/finders/container_repositories_finder_spec.rb'
- 'spec/finders/design_management/versions_finder_spec.rb'
- 'spec/finders/milestones_finder_spec.rb'
- 'spec/finders/packages/group_packages_finder_spec.rb'
- 'spec/finders/packages/npm/package_finder_spec.rb'
- 'spec/finders/projects_finder_spec.rb'
- 'spec/frontend/fixtures/api_merge_requests.rb'
- 'spec/frontend/fixtures/api_projects.rb'
- 'spec/frontend/fixtures/application_settings.rb'
- 'spec/frontend/fixtures/blob.rb'
- 'spec/frontend/fixtures/branches.rb'
- 'spec/frontend/fixtures/clusters.rb'
- 'spec/frontend/fixtures/deploy_keys.rb'
- 'spec/frontend/fixtures/groups.rb'
- 'spec/frontend/fixtures/issues.rb'
- 'spec/frontend/fixtures/jobs.rb'
- 'spec/frontend/fixtures/labels.rb'
- 'spec/frontend/fixtures/merge_requests.rb'
- 'spec/frontend/fixtures/merge_requests_diffs.rb'
- 'spec/frontend/fixtures/metrics_dashboard.rb'
- 'spec/frontend/fixtures/pipeline_schedules.rb'
- 'spec/frontend/fixtures/pipelines.rb'
- 'spec/frontend/fixtures/projects.rb'
- 'spec/frontend/fixtures/prometheus_service.rb'
- 'spec/frontend/fixtures/raw.rb'
- 'spec/frontend/fixtures/services.rb'
- 'spec/frontend/fixtures/snippet.rb'
- 'spec/frontend/fixtures/todos.rb'
- 'spec/graphql/mutations/merge_requests/set_labels_spec.rb'
- 'spec/graphql/mutations/releases/create_spec.rb'
- 'spec/graphql/mutations/releases/delete_spec.rb'
- 'spec/graphql/mutations/releases/update_spec.rb'
- 'spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb'
- 'spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb'
- 'spec/graphql/resolvers/project_jobs_resolver_spec.rb'
- 'spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb'
- 'spec/graphql/resolvers/projects_resolver_spec.rb'
- 'spec/graphql/types/ci/job_token_scope_type_spec.rb'
- 'spec/graphql/types/issue_type_spec.rb'
- 'spec/graphql/types/user_type_spec.rb'
- 'spec/helpers/application_settings_helper_spec.rb'
- 'spec/helpers/blob_helper_spec.rb'
- 'spec/helpers/gitlab_script_tag_helper_spec.rb'
- 'spec/helpers/issuables_helper_spec.rb'
- 'spec/helpers/projects/pipeline_helper_spec.rb'
- 'spec/helpers/routing/pseudonymization_helper_spec.rb'
- 'spec/helpers/search_helper_spec.rb'
- 'spec/helpers/wiki_page_version_helper_spec.rb'
- 'spec/initializers/carrierwave_patch_spec.rb'
- 'spec/initializers/trusted_proxies_spec.rb'
- 'spec/lib/api/entities/ci/job_request/image_spec.rb'
- 'spec/lib/api/entities/ci/job_request/port_spec.rb'
- 'spec/lib/api/helpers/sse_helpers_spec.rb'
- 'spec/lib/api/helpers_spec.rb'
- 'spec/lib/banzai/cross_project_reference_spec.rb'
- 'spec/lib/banzai/filter/broadcast_message_placeholders_filter_spec.rb'
- 'spec/lib/banzai/filter/commit_trailers_filter_spec.rb'
- 'spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb'
- 'spec/lib/banzai/renderer_spec.rb'
- 'spec/lib/bitbucket_server/connection_spec.rb'
- 'spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb'
- 'spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb'
- 'spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb'
- 'spec/lib/feature/definition_spec.rb'
- 'spec/lib/feature_spec.rb'
- 'spec/lib/gitlab/application_context_spec.rb'
- 'spec/lib/gitlab/asciidoc_spec.rb'
- 'spec/lib/gitlab/audit/ci_runner_token_author_spec.rb'
- 'spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb'
- 'spec/lib/gitlab/batch_pop_queueing_spec.rb'
- 'spec/lib/gitlab/chat_name_token_spec.rb'
- 'spec/lib/gitlab/ci/ansi2html_spec.rb'
- 'spec/lib/gitlab/ci/ansi2json_spec.rb'
- 'spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb'
- 'spec/lib/gitlab/ci/config/entry/processable_spec.rb'
- 'spec/lib/gitlab/ci/config/entry/release_spec.rb'
- 'spec/lib/gitlab/ci/config/entry/tags_spec.rb'
- 'spec/lib/gitlab/ci/config/external/file/base_spec.rb'
- 'spec/lib/gitlab/ci/config/external/file/local_spec.rb'
- 'spec/lib/gitlab/ci/config/external/file/remote_spec.rb'
- 'spec/lib/gitlab/ci/config/normalizer_spec.rb'
- 'spec/lib/gitlab/ci/cron_parser_spec.rb'
- 'spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb'
- 'spec/lib/gitlab/ci/pipeline/chain/seed_block_spec.rb'
- 'spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb'
- 'spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb'
- 'spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/reports_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/vulnerability_reports_comparer_spec.rb'
- 'spec/lib/gitlab/ci/reports/test_suite_spec.rb'
- 'spec/lib/gitlab/ci/status/build/canceled_spec.rb'
- 'spec/lib/gitlab/ci/status/build/created_spec.rb'
- 'spec/lib/gitlab/ci/status/build/manual_spec.rb'
- 'spec/lib/gitlab/ci/status/build/pending_spec.rb'
- 'spec/lib/gitlab/ci/status/build/skipped_spec.rb'
- 'spec/lib/gitlab/ci/status/processable/waiting_for_resource_spec.rb'
- 'spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb'
- 'spec/lib/gitlab/ci/trace/remote_checksum_spec.rb'
- 'spec/lib/gitlab/ci/yaml_processor_spec.rb'
- 'spec/lib/gitlab/composer/cache_spec.rb'
- 'spec/lib/gitlab/data_builder/build_spec.rb'
- 'spec/lib/gitlab/data_builder/pipeline_spec.rb'
- 'spec/lib/gitlab/database/background_migration/batched_migration_spec.rb'
- 'spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb'
- 'spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb'
- 'spec/lib/gitlab/database/migration_helpers/v2_spec.rb'
- 'spec/lib/gitlab/database/migration_helpers_spec.rb'
- 'spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb'
- 'spec/lib/gitlab/database/migrations/runner_spec.rb'
- 'spec/lib/gitlab/database/partitioning_spec.rb'
- 'spec/lib/gitlab/database/reindexing/grafana_notifier_spec.rb'
- 'spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb'
- 'spec/lib/gitlab/database/with_lock_retries_spec.rb'
- 'spec/lib/gitlab/database_importers/common_metrics/importer_spec.rb'
- 'spec/lib/gitlab/database_spec.rb'
- 'spec/lib/gitlab/elasticsearch/logs/lines_spec.rb'
- 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
- 'spec/lib/gitlab/email/handler/service_desk_handler_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/admin_verify_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/create_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/experience_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/team_short_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/team_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/trial_short_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/trial_spec.rb'
- 'spec/lib/gitlab/email/message/in_product_marketing/verify_spec.rb'
- 'spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb'
- 'spec/lib/gitlab/exclusive_lease_helpers_spec.rb'
- 'spec/lib/gitlab/file_markdown_link_builder_spec.rb'
- 'spec/lib/gitlab/git/blob_spec.rb'
- 'spec/lib/gitlab/git/commit_spec.rb'
- 'spec/lib/gitlab/git/diff_collection_spec.rb'
- 'spec/lib/gitlab/git/raw_diff_change_spec.rb'
- 'spec/lib/gitlab/git/repository_spec.rb'
- 'spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb'
- 'spec/lib/gitlab/gitaly_client/commit_service_spec.rb'
- 'spec/lib/gitlab/github_import/client_spec.rb'
- 'spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb'
- 'spec/lib/gitlab/gpg_spec.rb'
- 'spec/lib/gitlab/graphql/markdown_field_spec.rb'
- 'spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb'
- 'spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb'
- 'spec/lib/gitlab/graphs/commits_spec.rb'
- 'spec/lib/gitlab/highlight_spec.rb'
- 'spec/lib/gitlab/import_export/import_test_coverage_spec.rb'
- 'spec/lib/gitlab/import_export/json/ndjson_writer_spec.rb'
- 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
- 'spec/lib/gitlab/import_export/version_checker_spec.rb'
- 'spec/lib/gitlab/jira/dvcs_spec.rb'
- 'spec/lib/gitlab/kubernetes/rollout_status_spec.rb'
- 'spec/lib/gitlab/metrics/background_transaction_spec.rb'
- 'spec/lib/gitlab/metrics/web_transaction_spec.rb'
- 'spec/lib/gitlab/middleware/compressed_json_spec.rb'
- 'spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb'
- 'spec/lib/gitlab/otp_key_rotator_spec.rb'
- 'spec/lib/gitlab/pagination/keyset_spec.rb'
- 'spec/lib/gitlab/phabricator_import/conduit/response_spec.rb'
- 'spec/lib/gitlab/prometheus_client_spec.rb'
- 'spec/lib/gitlab/quick_actions/command_definition_spec.rb'
- 'spec/lib/gitlab/quick_actions/extractor_spec.rb'
- 'spec/lib/gitlab/rack_attack/instrumented_cache_store_spec.rb'
- 'spec/lib/gitlab/rack_attack/user_allowlist_spec.rb'
- 'spec/lib/gitlab/redis/hll_spec.rb'
- 'spec/lib/gitlab/reference_counter_spec.rb'
- 'spec/lib/gitlab/regex_spec.rb'
- 'spec/lib/gitlab/search/abuse_detection_spec.rb'
- 'spec/lib/gitlab/search_context/builder_spec.rb'
- 'spec/lib/gitlab/session_spec.rb'
- 'spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb'
- 'spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb'
- 'spec/lib/gitlab/spamcheck/client_spec.rb'
- 'spec/lib/gitlab/suggestions/file_suggestion_spec.rb'
- 'spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb'
- 'spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb'
- 'spec/lib/gitlab/utils/sanitize_node_link_spec.rb'
- 'spec/lib/gitlab/utils/usage_data_spec.rb'
- 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/verify/uploads_spec.rb'
- 'spec/lib/gitlab/version_info_spec.rb'
- 'spec/lib/json_web_token/rsa_token_spec.rb'
- 'spec/lib/marginalia_spec.rb'
- 'spec/lib/mattermost/session_spec.rb'
- 'spec/lib/microsoft_teams/notifier_spec.rb'
- 'spec/lib/sidebars/groups/menus/group_information_menu_spec.rb'
- 'spec/lib/sidebars/menu_spec.rb'
- 'spec/mailers/emails/service_desk_spec.rb'
- 'spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb'
- 'spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb'
- 'spec/migrations/confirm_support_bot_user_spec.rb'
- 'spec/migrations/reset_job_token_scope_enabled_again_spec.rb'
- 'spec/migrations/reset_job_token_scope_enabled_spec.rb'
- 'spec/migrations/reset_severity_levels_to_new_default_spec.rb'
- 'spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb'
- 'spec/models/active_session_spec.rb'
- 'spec/models/aws/role_spec.rb'
- 'spec/models/ci/build_dependencies_spec.rb'
- 'spec/models/ci/build_runner_session_spec.rb'
- 'spec/models/ci/build_spec.rb'
- 'spec/models/ci/daily_build_group_report_result_spec.rb'
- 'spec/models/ci/job_artifact_spec.rb'
- 'spec/models/ci/pipeline_schedule_spec.rb'
- 'spec/models/ci/pipeline_spec.rb'
- 'spec/models/ci/runner_spec.rb'
- 'spec/models/clusters/applications/elastic_stack_spec.rb'
- 'spec/models/clusters/cluster_spec.rb'
- 'spec/models/commit_status_spec.rb'
- 'spec/models/concerns/chronic_duration_attribute_spec.rb'
- 'spec/models/concerns/counter_attribute_spec.rb'
- 'spec/models/concerns/nullify_if_blank_spec.rb'
- 'spec/models/concerns/reactive_caching_spec.rb'
- 'spec/models/concerns/token_authenticatable_spec.rb'
- 'spec/models/container_expiration_policy_spec.rb'
- 'spec/models/container_repository_spec.rb'
- 'spec/models/environment_spec.rb'
- 'spec/models/event_spec.rb'
- 'spec/models/group_spec.rb'
- 'spec/models/hooks/web_hook_log_spec.rb'
- 'spec/models/integrations/chat_message/wiki_page_message_spec.rb'
- 'spec/models/issue_spec.rb'
- 'spec/models/jira_import_state_spec.rb'
- 'spec/models/merge_request_spec.rb'
- 'spec/models/namespace/root_storage_statistics_spec.rb'
- 'spec/models/namespace_spec.rb'
- 'spec/models/note_spec.rb'
- 'spec/models/onboarding_progress_spec.rb'
- 'spec/models/packages/conan/metadatum_spec.rb'
- 'spec/models/packages/package_file_spec.rb'
- 'spec/models/packages/package_spec.rb'
- 'spec/models/postgresql/replication_slot_spec.rb'
- 'spec/models/preloaders/labels_preloader_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb'
- 'spec/models/project_spec.rb'
- 'spec/models/release_spec.rb'
- 'spec/models/releases/link_spec.rb'
- 'spec/models/remote_mirror_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/models/snippet_input_action_collection_spec.rb'
- 'spec/models/snippet_spec.rb'
- 'spec/models/user_spec.rb'
- 'spec/models/users/calloutable_spec.rb'
- 'spec/models/wiki_page/meta_spec.rb'
- 'spec/policies/clusters/agent_policy_spec.rb'
- 'spec/policies/group_member_policy_spec.rb'
- 'spec/policies/issue_policy_spec.rb'
- 'spec/policies/project_policy_spec.rb'
- 'spec/policies/terraform/state_policy_spec.rb'
- 'spec/policies/terraform/state_version_policy_spec.rb'
- 'spec/presenters/packages/composer/packages_presenter_spec.rb'
- 'spec/presenters/packages/conan/package_presenter_spec.rb'
- 'spec/presenters/packages/nuget/packages_metadata_presenter_spec.rb'
- 'spec/presenters/packages/pypi/package_presenter_spec.rb'
- 'spec/presenters/project_presenter_spec.rb'
- 'spec/requests/api/branches_spec.rb'
- 'spec/requests/api/ci/jobs_spec.rb'
- 'spec/requests/api/ci/runner/jobs_request_post_spec.rb'
- 'spec/requests/api/ci/runner/jobs_trace_spec.rb'
- 'spec/requests/api/ci/secure_files_spec.rb'
- 'spec/requests/api/ci/triggers_spec.rb'
- 'spec/requests/api/ci/variables_spec.rb'
- 'spec/requests/api/commits_spec.rb'
- 'spec/requests/api/conan_instance_packages_spec.rb'
- 'spec/requests/api/conan_project_packages_spec.rb'
- 'spec/requests/api/dependency_proxy_spec.rb'
- 'spec/requests/api/go_proxy_spec.rb'
- 'spec/requests/api/graphql/boards/board_list_issues_query_spec.rb'
- 'spec/requests/api/graphql/boards/board_lists_query_spec.rb'
- 'spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb'
- 'spec/requests/api/graphql/mutations/award_emojis/add_spec.rb'
- 'spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb'
- 'spec/requests/api/graphql/mutations/releases/create_spec.rb'
- 'spec/requests/api/graphql/mutations/releases/update_spec.rb'
- 'spec/requests/api/graphql/mutations/snippets/create_spec.rb'
- 'spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb'
- 'spec/requests/api/graphql/packages/conan_spec.rb'
- 'spec/requests/api/graphql/packages/helm_spec.rb'
- 'spec/requests/api/graphql/packages/package_spec.rb'
- 'spec/requests/api/graphql/project/base_service_spec.rb'
- 'spec/requests/api/graphql/project/jira_import_spec.rb'
- 'spec/requests/api/group_variables_spec.rb'
- 'spec/requests/api/groups_spec.rb'
- 'spec/requests/api/helpers_spec.rb'
- 'spec/requests/api/internal/base_spec.rb'
- 'spec/requests/api/markdown_spec.rb'
- 'spec/requests/api/maven_packages_spec.rb'
- 'spec/requests/api/metrics/dashboard/annotations_spec.rb'
- 'spec/requests/api/notes_spec.rb'
- 'spec/requests/api/npm_project_packages_spec.rb'
- 'spec/requests/api/nuget_group_packages_spec.rb'
- 'spec/requests/api/pages/pages_spec.rb'
- 'spec/requests/api/pages_domains_spec.rb'
- 'spec/requests/api/personal_access_tokens_spec.rb'
- 'spec/requests/api/project_hooks_spec.rb'
- 'spec/requests/api/project_templates_spec.rb'
- 'spec/requests/api/projects_spec.rb'
- 'spec/requests/api/pypi_packages_spec.rb'
- 'spec/requests/api/release/links_spec.rb'
- 'spec/requests/api/releases_spec.rb'
- 'spec/requests/api/snippets_spec.rb'
- 'spec/requests/api/unleash_spec.rb'
- 'spec/requests/git_http_spec.rb'
- 'spec/requests/groups/milestones_controller_spec.rb'
- 'spec/requests/lfs_http_spec.rb'
- 'spec/requests/oauth/tokens_controller_spec.rb'
- 'spec/rubocop/cop/migration/create_table_with_foreign_keys_spec.rb'
- 'spec/serializers/cluster_entity_spec.rb'
- 'spec/serializers/deploy_key_entity_spec.rb'
- 'spec/serializers/import/provider_repo_serializer_spec.rb'
- 'spec/services/auto_merge/base_service_spec.rb'
- 'spec/services/auto_merge_service_spec.rb'
- 'spec/services/ci/create_pipeline_service/evaluate_runner_tags_spec.rb'
- 'spec/services/ci/parse_dotenv_artifact_service_spec.rb'
- 'spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb'
- 'spec/services/ci/process_build_service_spec.rb'
- 'spec/services/ci/runners/register_runner_service_spec.rb'
- 'spec/services/ci/runners/update_runner_service_spec.rb'
- 'spec/services/ci/stuck_builds/drop_pending_service_spec.rb'
- 'spec/services/ci/stuck_builds/drop_scheduled_service_spec.rb'
- 'spec/services/clusters/integrations/create_service_spec.rb'
- 'spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb'
- 'spec/services/deployments/create_for_build_service_spec.rb'
- 'spec/services/git/branch_push_service_spec.rb'
- 'spec/services/groups/destroy_service_spec.rb'
- 'spec/services/groups/merge_requests_count_service_spec.rb'
- 'spec/services/groups/update_service_spec.rb'
- 'spec/services/groups/update_statistics_service_spec.rb'
- 'spec/services/import/validate_remote_git_endpoint_service_spec.rb'
- 'spec/services/issues/referenced_merge_requests_service_spec.rb'
- 'spec/services/jira_import/start_import_service_spec.rb'
- 'spec/services/lfs/push_service_spec.rb'
- 'spec/services/members/invite_service_spec.rb'
- 'spec/services/merge_requests/push_options_handler_service_spec.rb'
- 'spec/services/merge_requests/refresh_service_spec.rb'
- 'spec/services/merge_requests/update_service_spec.rb'
- 'spec/services/milestones/transfer_service_spec.rb'
- 'spec/services/notes/copy_service_spec.rb'
- 'spec/services/notification_service_spec.rb'
- 'spec/services/packages/composer/create_package_service_spec.rb'
- 'spec/services/packages/create_dependency_service_spec.rb'
- 'spec/services/packages/debian/extract_deb_metadata_service_spec.rb'
- 'spec/services/packages/debian/parse_debian822_service_spec.rb'
- 'spec/services/packages/debian/sign_distribution_service_spec.rb'
- 'spec/services/packages/helm/process_file_service_spec.rb'
- 'spec/services/packages/npm/create_package_service_spec.rb'
- 'spec/services/packages/rubygems/dependency_resolver_service_spec.rb'
- 'spec/services/pages/delete_service_spec.rb'
- 'spec/services/projects/container_repository/third_party/delete_tags_service_spec.rb'
- 'spec/services/projects/enable_deploy_key_service_spec.rb'
- 'spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb'
- 'spec/services/projects/lfs_pointers/lfs_download_service_spec.rb'
- 'spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb'
- 'spec/services/projects/participants_service_spec.rb'
- 'spec/services/projects/update_statistics_service_spec.rb'
- 'spec/services/quick_actions/interpret_service_spec.rb'
- 'spec/services/releases/destroy_service_spec.rb'
- 'spec/services/releases/update_service_spec.rb'
- 'spec/services/resource_access_tokens/create_service_spec.rb'
- 'spec/services/search/group_service_spec.rb'
- 'spec/services/snippets/update_service_spec.rb'
- 'spec/services/suggestions/apply_service_spec.rb'
- 'spec/services/system_notes/merge_requests_service_spec.rb'
- 'spec/services/terraform/remote_state_handler_spec.rb'
- 'spec/services/todo_service_spec.rb'
- 'spec/services/todos/destroy/design_service_spec.rb'
- 'spec/services/todos/destroy/entity_leave_service_spec.rb'
- 'spec/services/web_hook_service_spec.rb'
- 'spec/support/helpers/cycle_analytics_helpers.rb'
- 'spec/support/redis/redis_shared_examples.rb'
- 'spec/support/shared_contexts/features/integrations/integrations_shared_context.rb'
- 'spec/support/shared_contexts/graphql/requests/packages_shared_context.rb'
- 'spec/support/shared_contexts/markdown_golden_master_shared_examples.rb'
- 'spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb'
- 'spec/support/shared_examples/controllers/error_tracking_shared_examples.rb'
- 'spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb'
- 'spec/support/shared_examples/features/board_sidebar_labels_examples.rb'
- 'spec/support/shared_examples/features/snippets_shared_examples.rb'
- 'spec/support/shared_examples/features/wiki/user_views_asciidoc_page_with_includes_shared_examples.rb'
- 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
- 'spec/support/shared_examples/lib/gitlab/sql/set_operator_shared_examples.rb'
- 'spec/support/shared_examples/models/cluster_application_core_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb'
- 'spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb'
- 'spec/support/shared_examples/models/label_note_shared_examples.rb'
- 'spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb'
- 'spec/support/shared_examples/models/project_latest_successful_build_for_shared_examples.rb'
- 'spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb'
- 'spec/support/shared_examples/requests/api/issues/merge_requests_count_shared_examples.rb'
- 'spec/support/shared_examples/requests/api/labels_api_shared_examples.rb'
- 'spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb'
- 'spec/support/shared_examples/requests/lfs_http_shared_examples.rb'
- 'spec/support/shared_examples/services/alert_management/alert_processing/alert_firing_shared_examples.rb'
- 'spec/support/shared_examples/services/boards/issues_move_service_shared_examples.rb'
- 'spec/support/shared_examples/services/gitlab_projects_import_service_shared_examples.rb'
- 'spec/support/shared_examples/services/merge_request_shared_examples.rb'
- 'spec/support/shared_examples/uploaders/object_storage_shared_examples.rb'
- 'spec/tasks/gitlab/snippets_rake_spec.rb'
- 'spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb'
- 'spec/validators/addressable_url_validator_spec.rb'
- 'spec/views/help/instance_configuration.html.haml_spec.rb'
- 'spec/views/layouts/_header_search.html.haml_spec.rb'
- 'spec/views/layouts/_published_experiments.html.haml_spec.rb'
- 'spec/views/shared/runners/_runner_details.html.haml_spec.rb'
- 'spec/workers/bulk_imports/export_request_worker_spec.rb'
- 'spec/workers/clusters/cleanup/project_namespace_worker_spec.rb'
- 'spec/workers/packages/helm/extraction_worker_spec.rb'
- 'spec/workers/pages_worker_spec.rb'
- 'spec/workers/purge_dependency_proxy_cache_worker_spec.rb'
- 'spec/workers/releases/manage_evidence_worker_spec.rb'
- 'spec/workers/repository_remove_remote_worker_spec.rb'

View File

@ -0,0 +1,15 @@
---
Lint/BinaryOperatorWithIdenticalOperands:
Exclude:
- 'ee/spec/lib/ee/gitlab/application_context_spec.rb'
- 'spec/helpers/visibility_level_helper_spec.rb'
- 'spec/lib/gitlab/conan_token_spec.rb'
- 'spec/lib/gitlab/git/conflict/parser_spec.rb'
- 'spec/lib/gitlab/graphql/lazy_spec.rb'
- 'spec/models/ci/build_trace_chunk_spec.rb'
- 'spec/models/clusters/platforms/kubernetes_spec.rb'
- 'spec/models/concerns/where_composite_spec.rb'
- 'spec/models/metrics/dashboard/annotation_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/models/ssh_host_key_spec.rb'
- 'spec/tooling/danger/sidekiq_queues_spec.rb'

View File

@ -4,7 +4,7 @@ import { sortBy } from 'lodash';
import Draggable from 'vuedraggable';
import { mapState, mapGetters, mapActions } from 'vuex';
import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
import defaultSortableConfig from '~/sortable/sortable_config';
import { defaultSortableOptions } from '~/sortable/constants';
import { DraggableItemTypes } from '../constants';
import BoardColumn from './board_column.vue';
@ -43,7 +43,7 @@ export default {
},
draggableOptions() {
const options = {
...defaultSortableConfig,
...defaultSortableOptions,
disabled: this.disabled,
draggable: '.is-draggable',
fallbackOnBody: false,

View File

@ -2,9 +2,9 @@
import { GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import Draggable from 'vuedraggable';
import { mapActions, mapGetters, mapState } from 'vuex';
import { sortableStart, sortableEnd } from '~/boards/mixins/sortable_default_options';
import { sprintf, __ } from '~/locale';
import defaultSortableConfig from '~/sortable/sortable_config';
import { defaultSortableOptions } from '~/sortable/constants';
import { sortableStart, sortableEnd } from '~/sortable/utils';
import Tracking from '~/tracking';
import listQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql';
import { toggleFormEventPrefix, DraggableItemTypes } from '../constants';
@ -121,7 +121,7 @@ export default {
},
treeRootOptions() {
const options = {
...defaultSortableConfig,
...defaultSortableOptions,
fallbackOnBody: false,
group: 'board-list',
tag: 'ul',

View File

@ -1,21 +0,0 @@
<script>
export default {
props: {
title: {
type: String,
required: true,
},
refPath: {
type: String,
required: true,
},
},
};
</script>
<template>
<div data-testid="issue-title">
<p class="gl-font-weight-bold">{{ title }}</p>
<p class="gl-mb-0">{{ refPath }}</p>
</div>
</template>

View File

@ -130,7 +130,7 @@ export default {
:link-href="authorUrl"
:img-src="authorAvatar"
:img-alt="authorName"
:img-size="40"
:img-size="32"
class="avatar-cell d-none d-sm-block"
/>
</div>

View File

@ -167,6 +167,9 @@ export default {
this.integrationActive = integrationActive;
},
},
descriptionHtmlConfig: {
ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented
},
helpHtmlConfig: {
ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented
ADD_TAGS: ['use'], // to support icon SVGs
@ -212,7 +215,7 @@ export default {
<div class="row">
<div class="col-lg-4">
<h4 class="gl-mt-0">{{ section.title }}</h4>
<p v-safe-html="section.description"></p>
<p v-safe-html:[$options.descriptionHtmlConfig]="section.description"></p>
</div>
<div class="col-lg-8">

View File

@ -1,5 +1,5 @@
<script>
import { GlFormGroup, GlFormCheckbox, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui';
import { GlFormGroup, GlFormCheckbox, GlFormInput } from '@gitlab/ui';
import { mapGetters } from 'vuex';
import { s__, __ } from '~/locale';
import JiraUpgradeCta from './jira_upgrade_cta.vue';
@ -10,8 +10,6 @@ export default {
GlFormGroup,
GlFormCheckbox,
GlFormInput,
GlSprintf,
GlLink,
JiraUpgradeCta,
JiraIssueCreationVulnerabilities: () =>
import('ee_component/integrations/edit/components/jira_issue_creation_vulnerabilities.vue'),
@ -47,21 +45,11 @@ export default {
required: false,
default: null,
},
gitlabIssuesEnabled: {
type: Boolean,
required: false,
default: true,
},
upgradePlanPath: {
type: String,
required: false,
default: '',
},
editProjectPath: {
type: String,
required: false,
default: '',
},
isValidated: {
type: Boolean,
required: false,
@ -91,9 +79,6 @@ export default {
projectKeyLabel: s__('JiraService|Jira project key'),
projectKeyPlaceholder: s__('JiraService|For example, AB'),
requiredFieldFeedback: __('This field is required.'),
issueTrackerConflictWarning: s__(
'JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they wont otherwise be used.',
),
},
};
</script>
@ -112,12 +97,34 @@ export default {
{{ $options.i18n.enableCheckboxHelp }}
</template>
</gl-form-checkbox>
<template v-if="enableJiraIssues">
<div v-if="enableJiraIssues" class="gl-pl-6 gl-mt-3">
<gl-form-group
:label="$options.i18n.projectKeyLabel"
label-for="service_project_key"
:invalid-feedback="$options.i18n.requiredFieldFeedback"
:state="validProjectKey"
class="gl-max-w-26"
data-testid="project-key-form-group"
>
<gl-form-input
id="service_project_key"
v-model="projectKey"
name="service[project_key]"
data-qa-selector="service_jira_project_key_field"
:placeholder="$options.i18n.projectKeyPlaceholder"
:required="enableJiraIssues"
:state="validProjectKey"
:readonly="isInheriting"
/>
</gl-form-group>
<jira-issue-creation-vulnerabilities
:project-key="projectKey"
:initial-is-enabled="initialEnableJiraVulnerabilities"
:initial-issue-type-id="initialVulnerabilitiesIssuetype"
:show-full-feature="showJiraVulnerabilitiesIntegration"
class="gl-mt-6"
data-testid="jira-for-vulnerabilities"
@request-jira-issue-types="$emit('request-jira-issue-types')"
/>
@ -128,43 +135,14 @@ export default {
show-ultimate-message
:upgrade-plan-path="upgradePlanPath"
/>
</template>
</div>
</template>
<jira-upgrade-cta
v-else
class="gl-mt-2"
data-testid="premium-upgrade-cta"
show-premium-message
:upgrade-plan-path="upgradePlanPath"
/>
<template v-if="showJiraIssuesIntegration">
<gl-form-group
:label="$options.i18n.projectKeyLabel"
label-for="service_project_key"
:invalid-feedback="$options.i18n.requiredFieldFeedback"
:state="validProjectKey"
data-testid="project-key-form-group"
>
<gl-form-input
id="service_project_key"
v-model="projectKey"
name="service[project_key]"
data-qa-selector="service_jira_project_key_field"
:placeholder="$options.i18n.projectKeyPlaceholder"
:required="enableJiraIssues"
:state="validProjectKey"
:disabled="!enableJiraIssues"
:readonly="isInheriting"
/>
</gl-form-group>
<p v-if="gitlabIssuesEnabled" data-testid="conflict-warning-text">
<gl-sprintf :message="$options.i18n.issueTrackerConflictWarning">
<template #link="{ content }">
<gl-link :href="editProjectPath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
</template>
</div>
</template>

View File

@ -22,7 +22,6 @@ function parseDatasetToProps(data) {
commentDetail,
projectKey,
upgradePlanPath,
editProjectPath,
learnMorePath,
triggerEvents,
sections,
@ -52,7 +51,6 @@ function parseDatasetToProps(data) {
showJiraVulnerabilitiesIntegration,
enableJiraIssues,
enableJiraVulnerabilities,
gitlabIssuesEnabled,
} = parseBooleanInData(booleanAttributes);
return {
@ -81,9 +79,7 @@ function parseDatasetToProps(data) {
initialEnableJiraVulnerabilities: enableJiraVulnerabilities,
initialVulnerabilitiesIssuetype: vulnerabilitiesIssuetype,
initialProjectKey: projectKey,
gitlabIssuesEnabled,
upgradePlanPath,
editProjectPath,
},
learnMorePath,
triggerEvents: JSON.parse(triggerEvents),

View File

@ -1,11 +1,8 @@
import Sortable from 'sortablejs';
import {
getBoardSortableDefaultOptions,
sortableStart,
} from '~/boards/mixins/sortable_default_options';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { s__ } from '~/locale';
import { getSortableDefaultOptions, sortableStart } from '~/sortable/utils';
const updateIssue = (url, { move_before_id, move_after_id }) =>
axios
@ -28,7 +25,7 @@ const initManualOrdering = () => {
Sortable.create(
issueList,
getBoardSortableDefaultOptions({
getSortableDefaultOptions({
scroll: true,
fallbackTolerance: 1,
dataIdAttr: 'data-id',

View File

@ -1,8 +1,8 @@
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import Sortable from 'sortablejs';
import sortableConfig from '~/sortable/sortable_config';
import RelatedIssuableItem from '~/issuable/components/related_issuable_item.vue';
import { defaultSortableOptions } from '~/sortable/constants';
export default {
name: 'RelatedIssuesList',
@ -53,7 +53,7 @@ export default {
mounted() {
if (this.canReorder) {
this.sortable = Sortable.create(this.$refs.list, {
...sortableConfig,
...defaultSortableOptions,
onStart: this.addDraggingCursor,
onEnd: this.reordered,
});

View File

@ -0,0 +1,19 @@
/**
* Default config options for sortablejs.
* @type {object}
*
* @example
* import Sortable from 'sortablejs';
*
* const sortable = Sortable.create(el, {
* ...defaultSortableOptions,
* });
*/
export const defaultSortableOptions = {
animation: 200,
forceFallback: true,
fallbackClass: 'is-dragging',
fallbackOnBody: true,
ghostClass: 'is-ghost',
fallbackTolerance: 1,
};

View File

@ -1,8 +0,0 @@
export default {
animation: 200,
forceFallback: true,
fallbackClass: 'is-dragging',
fallbackOnBody: true,
ghostClass: 'is-ghost',
fallbackTolerance: 1,
};

View File

@ -1,6 +1,6 @@
/* global DocumentTouch */
import sortableConfig from '~/sortable/sortable_config';
import { defaultSortableOptions } from './constants';
export function sortableStart() {
document.body.classList.add('is-dragging');
@ -10,12 +10,12 @@ export function sortableEnd() {
document.body.classList.remove('is-dragging');
}
export function getBoardSortableDefaultOptions(obj) {
export function getSortableDefaultOptions(options) {
const touchEnabled =
'ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch);
const defaultSortOptions = {
...sortableConfig,
...defaultSortableOptions,
filter: '.no-drag',
delay: touchEnabled ? 100 : 0,
scrollSensitivity: touchEnabled ? 60 : 100,
@ -24,8 +24,8 @@ export function getBoardSortableDefaultOptions(obj) {
onEnd: sortableEnd,
};
Object.keys(obj).forEach((key) => {
defaultSortOptions[key] = obj[key];
});
return defaultSortOptions;
return {
...defaultSortOptions,
...options,
};
}

View File

@ -376,6 +376,7 @@ export default {
<div
v-if="referencedCommands && previewMarkdown && !markdownPreviewLoading"
class="referenced-commands"
data-testid="referenced-commands"
v-html="referencedCommands /* eslint-disable-line vue/no-v-html */"
></div>
<div v-if="shouldShowReferencedUsers" class="referenced-users">

View File

@ -1,318 +1,6 @@
$text-color: $gl-text-color;
$brand-primary: $blue-500;
$brand-success: $green-500;
$brand-info: $blue-500;
$brand-warning: $orange-500;
$brand-danger: $red-500;
$border-radius-base: $gl-border-radius-base;
$modal-body-bg: $white;
$input-border: $border-color;
$padding-base-vertical: $gl-vert-padding;
$padding-base-horizontal: $gl-padding;
/*
* Scss to help with bootstrap 3 to 4 migration
*/
body,
.form-control,
.search form {
// Override default font size used in non-csslab UI
// Use rem to keep default font-size at 14px on body so 1rem still
// fits 8px grid, but also allow users to change browser font size
font-size: 0.875rem;
}
legend {
border-bottom: 1px solid $border-color;
margin-bottom: 20px;
}
button,
html [type='button'],
[type='reset'],
[type='submit'],
[role='button'] {
// Override bootstrap reboot
/* stylelint-disable-next-line property-no-vendor-prefix */
-webkit-appearance: inherit;
cursor: pointer;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
margin-top: 20px;
margin-bottom: 10px;
}
h4,
.h4,
h5,
.h5,
h6,
.h6 {
margin-top: 10px;
margin-bottom: 10px;
}
/* Our adjustments to hx & .hx above add unnecessary margins to modal-title
and page-title in modals, so we set them to 0 in order to have properly
formatted modal headers. */
.modal-header {
.modal-title,
.page-title {
margin-top: 0;
margin-bottom: 0;
}
}
h5,
.h5 {
font-size: $gl-font-size;
}
input[type='file'] {
// Bootstrap 4 file input height is taller by default
// which makes them look ugly
line-height: 1;
}
b,
strong {
font-weight: bold;
}
a {
color: $blue-600;
}
hr {
overflow: hidden;
}
.form-group.row .col-form-label {
// Bootstrap 4 aligns labels to the left
// for horizontal forms
@include media-breakpoint-up(md) {
text-align: right;
}
}
code {
padding: 2px 4px;
color: $code-color;
background-color: $gray-50;
border-radius: $border-radius-default;
.code > &,
.build-log & {
background-color: inherit;
padding: unset;
}
}
table {
// Remove any table border lines
border-spacing: 0;
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.d#{$infix}-table-header-group {
display: table-header-group !important;
}
}
}
.text-secondary {
// Override Bootstrap's light secondary color
// We have to use !important because bootstrap has that set as well
color: $gl-text-color-secondary !important;
}
.bg-success,
.bg-primary,
.bg-info,
.bg-danger,
.bg-warning {
.card-header {
color: $white;
}
}
// Polyfill deprecated selectors
.hidden {
display: none !important;
visibility: hidden !important;
}
.hide {
display: none;
}
.dropdown-toggle::after,
.dropright .dropdown-menu-toggle::after {
// Remove bootstrap's dropdown caret
display: none;
}
// Add to .label so that old system notes that are saved to the db
// will still receive the correct styling
.badge:not(.gl-badge),
.label {
padding: 4px 5px;
font-size: 12px;
font-style: normal;
font-weight: $gl-font-weight-normal;
display: inline-block;
&.badge-gray {
background-color: $label-gray-bg;
color: $gl-text-color;
text-shadow: none;
}
&.badge-inverse {
background-color: $label-inverse-bg;
}
}
.divider {
// copied rules from node_modules/bootstrap/scss/_dropdown.scss:116
// this might be safe to just remove instead
// most places that use divider add overrides to undo these things
// there is also a probably-unintentional use in deprecated_dropdown_divider.scss
// so we would end up with .gl-dropdown .dropdown-divider
height: 0;
margin: 4px 0;
overflow: hidden;
border-top: 1px solid $border-color;
}
.info-well {
background: $gray-10;
color: $gl-text-color;
border: 1px solid $border-color;
border-radius: 4px;
margin-bottom: 16px;
.well-segment {
padding: 16px;
&:not(:last-of-type) {
border-bottom: 1px solid $well-inner-border;
}
p,
ol,
ul,
.form-group {
&:last-of-type {
margin-bottom: 0;
}
}
}
.badge.badge-gray {
background-color: $well-expand-item;
}
}
.card {
&.card-without-border,
&.bg-light {
border: 0 !important;
}
}
.nav-tabs {
// Override bootstrap's default border
border-bottom: 0;
.nav-link {
border-top: 0;
border-left: 0;
border-right: 0;
}
.nav-item {
margin-bottom: 0;
}
}
pre code {
white-space: pre-wrap;
}
.alert {
border-radius: 0;
}
.alert-success {
background-color: $green-500;
border-color: $green-500;
}
.alert-info {
background-color: $blue-500;
border-color: $blue-500;
}
.alert-warning {
background-color: $orange-500;
border-color: $orange-500;
}
.alert-danger {
background-color: $red-500;
border-color: $red-500;
}
.alert-success,
.alert-info,
.alert-warning,
.alert-danger {
color: $white;
h4,
.alert-link {
color: $white;
}
}
input[type=color].form-control {
height: $input-height;
}
.toggle-sidebar-button {
.collapse-text,
.icon-chevron-double-lg-left,
.icon-chevron-double-lg-right {
color: $gl-text-color-secondary;
}
}
.project-templates-buttons {
.btn {
vertical-align: unset;
}
}
/*
Bootstrap 4.1.2 introduced a new default vertical alignment which breaks our icons,
so we need to reset the vertical alignment to the default value. See:
- https://gitlab.com/gitlab-org/gitlab-foss/issues/51362
*/
svg {
vertical-align: baseline;
}
// ---
// Scss to help with bootstrap 3 to 4 migration
// ---
@import 'bootstrap_migration_variables';
@import 'bootstrap_migration_reset';
@import 'bootstrap_migration_components';

View File

@ -0,0 +1,216 @@
// ---
// Scss to help with bootstrap 3 to 4 migration of bootstrap components
// ---
.form-control,
.search form {
// Override default font size used in non-csslab UI
// Use rem to keep default font-size at 14px on body so 1rem still
// fits 8px grid, but also allow users to change browser font size
font-size: 0.875rem;
}
/* Our adjustments to hx & .hx above add unnecessary margins to modal-title
and page-title in modals, so we set them to 0 in order to have properly
formatted modal headers. */
.modal-header {
.modal-title,
.page-title {
margin-top: 0;
margin-bottom: 0;
}
}
input[type='file'] {
// Bootstrap 4 file input height is taller by default
// which makes them look ugly
line-height: 1;
}
.form-group.row .col-form-label {
// Bootstrap 4 aligns labels to the left
// for horizontal forms
@include media-breakpoint-up(md) {
text-align: right;
}
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.d#{$infix}-table-header-group {
display: table-header-group !important;
}
}
}
.text-secondary {
// Override Bootstrap's light secondary color
// We have to use !important because bootstrap has that set as well
color: $gl-text-color-secondary !important;
}
.bg-success,
.bg-primary,
.bg-info,
.bg-danger,
.bg-warning {
.card-header {
color: $white;
}
}
// Polyfill deprecated selectors
.hidden {
display: none !important;
visibility: hidden !important;
}
.hide {
display: none;
}
.dropdown-toggle::after,
.dropright .dropdown-menu-toggle::after {
// Remove bootstrap's dropdown caret
display: none;
}
// Add to .label so that old system notes that are saved to the db
// will still receive the correct styling
.badge:not(.gl-badge),
.label {
padding: 4px 5px;
font-size: 12px;
font-style: normal;
font-weight: $gl-font-weight-normal;
display: inline-block;
&.badge-gray {
background-color: $label-gray-bg;
color: $gl-text-color;
text-shadow: none;
}
&.badge-inverse {
background-color: $label-inverse-bg;
}
}
.divider {
// copied rules from node_modules/bootstrap/scss/_dropdown.scss:116
// this might be safe to just remove instead
// most places that use divider add overrides to undo these things
// there is also a probably-unintentional use in deprecated_dropdown_divider.scss
// so we would end up with .gl-dropdown .dropdown-divider
height: 0;
margin: 4px 0;
overflow: hidden;
border-top: 1px solid $border-color;
}
.info-well {
background: $gray-10;
color: $gl-text-color;
border: 1px solid $border-color;
border-radius: 4px;
margin-bottom: 16px;
.well-segment {
padding: 16px;
&:not(:last-of-type) {
border-bottom: 1px solid $well-inner-border;
}
p,
ol,
ul,
.form-group {
&:last-of-type {
margin-bottom: 0;
}
}
}
.badge.badge-gray {
background-color: $well-expand-item;
}
}
.card {
&.card-without-border,
&.bg-light {
border: 0 !important;
}
}
.nav-tabs {
// Override bootstrap's default border
border-bottom: 0;
.nav-link {
border-top: 0;
border-left: 0;
border-right: 0;
}
.nav-item {
margin-bottom: 0;
}
}
.alert {
border-radius: 0;
}
.alert-success {
background-color: $green-500;
border-color: $green-500;
}
.alert-info {
background-color: $blue-500;
border-color: $blue-500;
}
.alert-warning {
background-color: $orange-500;
border-color: $orange-500;
}
.alert-danger {
background-color: $red-500;
border-color: $red-500;
}
.alert-success,
.alert-info,
.alert-warning,
.alert-danger {
color: $white;
h4,
.alert-link {
color: $white;
}
}
input[type=color].form-control {
height: $input-height;
}
.toggle-sidebar-button {
.collapse-text,
.icon-chevron-double-lg-left,
.icon-chevron-double-lg-right {
color: $gl-text-color-secondary;
}
}
.project-templates-buttons {
.btn {
vertical-align: unset;
}
}

View File

@ -0,0 +1,94 @@
// ---
// Scss to help with bootstrap 3 to 4 migration of core elements
// ---
body {
// Override default font size used in non-csslab UI
// Use rem to keep default font-size at 14px on body so 1rem still
// fits 8px grid, but also allow users to change browser font size
font-size: 0.875rem;
}
legend {
border-bottom: 1px solid $border-color;
margin-bottom: 20px;
}
button,
html [type='button'],
[type='reset'],
[type='submit'],
[role='button'] {
// Override bootstrap reboot
/* stylelint-disable-next-line property-no-vendor-prefix */
-webkit-appearance: inherit;
cursor: pointer;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
margin-top: 20px;
margin-bottom: 10px;
}
h4,
.h4,
h5,
.h5,
h6,
.h6 {
margin-top: 10px;
margin-bottom: 10px;
}
h5,
.h5 {
font-size: $gl-font-size;
}
b,
strong {
font-weight: bold;
}
a {
color: $blue-600;
}
hr {
overflow: hidden;
}
code {
padding: 2px 4px;
color: $code-color;
background-color: $gray-50;
border-radius: $border-radius-default;
.code > &,
.build-log & {
background-color: inherit;
padding: unset;
}
}
table {
// Remove any table border lines
border-spacing: 0;
}
pre code {
white-space: pre-wrap;
}
/*
Bootstrap 4.1.2 introduced a new default vertical alignment which breaks our icons,
so we need to reset the vertical alignment to the default value. See:
- https://gitlab.com/gitlab-org/gitlab-foss/issues/51362
*/
svg {
vertical-align: baseline;
}

View File

@ -0,0 +1,15 @@
$text-color: $gl-text-color;
$brand-primary: $blue-500;
$brand-success: $green-500;
$brand-info: $blue-500;
$brand-warning: $orange-500;
$brand-danger: $red-500;
$border-radius-base: $gl-border-radius-base;
$modal-body-bg: $white;
$input-border: $border-color;
$padding-base-vertical: $gl-vert-padding;
$padding-base-horizontal: $gl-padding;

View File

@ -1,5 +1,6 @@
@import 'framework/mixins';
@import 'framework/variables';
@import 'framework/variables_overrides';
@import 'framework/mixins';
img {
max-width: 100%;

View File

@ -2,20 +2,30 @@
// keep parts that affect elements that can appear in emails;
// omit Bootstrap Reboot since it adds unnecessary styles to every element.
@import 'notify_base';
// bootstrap variables, mixins, functions
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
// bootstrap styles
@import 'bootstrap/scss/code';
// @gitlab/ui variables, mixins, functions
@import '@gitlab/ui/src/scss/variables';
@import '@gitlab/ui/src/scss/utility-mixins/index';
@import '@gitlab/ui/src/scss/components';
@import 'bootstrap_migration';
@import 'framework/common';
// @gitlab/ui styles
@import '@gitlab/ui/src/components/base/icon/icon';
@import '@gitlab/ui/src/components/base/label/label';
// gitlab styles
@import 'bootstrap_migration_variables';
@import 'bootstrap_migration_reset';
@import 'framework/gfm';
@import 'framework/kbd';
@import 'framework/tables';
@import 'framework/typography';
@import 'framework/emojis';
body {
font-family: $regular-font;

View File

@ -543,9 +543,7 @@ a.gl-badge.badge-warning:active {
padding-right: 2rem;
padding-left: 1.75rem;
}
body,
.form-control,
.search form {
body {
font-size: 0.875rem;
}
button,
@ -563,6 +561,13 @@ strong {
a {
color: #63a6e9;
}
svg {
vertical-align: baseline;
}
.form-control,
.search form {
font-size: 0.875rem;
}
.hidden {
display: none !important;
visibility: hidden !important;
@ -587,9 +592,6 @@ a {
.toggle-sidebar-button .icon-chevron-double-lg-left {
color: #999;
}
svg {
vertical-align: baseline;
}
html {
overflow-y: scroll;
}

View File

@ -529,9 +529,7 @@ a.gl-badge.badge-warning:active {
padding-right: 2rem;
padding-left: 1.75rem;
}
body,
.form-control,
.search form {
body {
font-size: 0.875rem;
}
button,
@ -549,6 +547,13 @@ strong {
a {
color: #1068bf;
}
svg {
vertical-align: baseline;
}
.form-control,
.search form {
font-size: 0.875rem;
}
.hidden {
display: none !important;
visibility: hidden !important;
@ -573,9 +578,6 @@ a {
.toggle-sidebar-button .icon-chevron-double-lg-left {
color: #666;
}
svg {
vertical-align: baseline;
}
html {
overflow-y: scroll;
}

View File

@ -369,8 +369,7 @@ fieldset:disabled a.btn {
outline: none;
background-color: #0b5cad;
}
body,
.form-control {
body {
font-size: 0.875rem;
}
[type="submit"] {
@ -387,6 +386,12 @@ a {
hr {
overflow: hidden;
}
svg {
vertical-align: baseline;
}
.form-control {
font-size: 0.875rem;
}
.hidden {
display: none !important;
visibility: hidden !important;
@ -394,9 +399,6 @@ hr {
.hide {
display: none;
}
svg {
vertical-align: baseline;
}
html {
overflow-y: scroll;
}

View File

@ -233,7 +233,7 @@ module IssuablesHelper
canUpdate: can?(current_user, :"update_#{issuable.to_ability_name}", issuable),
canDestroy: can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable),
issuableRef: issuable.to_reference,
markdownPreviewPath: preview_markdown_path(parent),
markdownPreviewPath: preview_markdown_path(parent, target_type: issuable.model_name, target_id: issuable.iid),
markdownDocsPath: help_page_path('user/markdown'),
lockVersion: issuable.lock_version,
issuableTemplateNamesPath: template_names_path(parent, issuable),

View File

@ -143,7 +143,7 @@ module Integrations
end
def help
jira_doc_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/index.html') }
jira_doc_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('integration/jira/index') }
s_("JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe }
end
@ -160,8 +160,6 @@ module Integrations
end
def sections
jira_issues_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/issues.html') }
sections = [
{
type: SECTION_TYPE_CONNECTION,
@ -180,7 +178,7 @@ module Integrations
sections.push({
type: SECTION_TYPE_JIRA_ISSUES,
title: _('Issues'),
description: s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}') % { jira_issues_link_start: jira_issues_link_start, link_end: '</a>'.html_safe }
description: jira_issues_section_description
})
end
@ -610,6 +608,19 @@ module Integrations
data_fields.deployment_server!
end
end
def jira_issues_section_description
jira_issues_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('integration/jira/issues') }
description = s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}') % { jira_issues_link_start: jira_issues_link_start, link_end: '</a>'.html_safe }
if project&.issues_enabled?
gitlab_issues_link_start = '<a href="%{url}">'.html_safe % { url: edit_project_path(project, anchor: 'js-shared-permissions') }
description += '<br><br>'.html_safe
description += s_("JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{gitlab_issues_link_start}disabling GitLab issues%{link_end} if they won't otherwise be used.") % { gitlab_issues_link_start: gitlab_issues_link_start, link_end: '</a>'.html_safe }
end
description
end
end
end

View File

@ -4,6 +4,8 @@ module BulkImports
class RelationExportService
include Gitlab::ImportExport::CommandLineUtil
EXISTING_EXPORT_TTL = 3.minutes
def initialize(user, portable, relation, jid)
@user = user
@portable = portable
@ -31,6 +33,9 @@ module BulkImports
validate_user_permissions!
export = portable.bulk_import_exports.safe_find_or_create_by!(relation: relation)
return export if export.finished? && export.updated_at > EXISTING_EXPORT_TTL.ago
export.update!(status_event: 'start', jid: jid)
yield export

View File

@ -5,9 +5,8 @@
= form_tag admin_groups_path, method: :get, class: 'js-search-form' do |f|
= hidden_field_tag :sort, @sort
.search-holder
- project_name = params[:name].present? ? params[:name] : nil
.search-field-holder
= search_field_tag :name, project_name, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name', data: { qa_selector: 'group_search_field' }
= search_field_tag :name, params[:name].presence, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name', data: { qa_selector: 'group_search_field' }
= sprite_icon('search', css_class: 'search-icon')
= render "shared/groups/dropdown", options_hash: admin_groups_sort_options_hash
= link_to new_admin_group_path, class: "gl-button btn btn-confirm" do

View File

@ -11,7 +11,7 @@
.gl-alert-body
= s_('ExternalIssueIntegration|Only one issue tracker integration can be active at a time. Please disable the active tracker first and try again.')
%h3.page-title
%h2.gl-mb-4
= integration.title
- if integration.operating?
= sprite_icon('check', css_class: 'gl-text-green-500')

View File

@ -3,7 +3,7 @@
- page_title @integration.title, _('Integrations')
- @content_class = 'limit-container-width' unless fluid_layout
%h3.page-title
%h2.gl-mb-4
= @integration.title
= render 'shared/integrations/tabs', integration: @integration, active_tab: 'edit' do

View File

@ -3,12 +3,12 @@
module BulkImports
class RelationExportWorker
include ApplicationWorker
data_consistency :always
include ExceptionBacktrace
idempotent!
deduplicate :until_executed
loggable_arguments 2, 3
data_consistency :always
feature_category :importers
sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION

View File

@ -0,0 +1,34 @@
- name: "Manual iteration management" # The name of the feature to be deprecated
announcement_milestone: "14.10" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-04-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "16.0" # The milestone when this feature is planned to be removed
removal_date: "2023-04-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: mcelicalderonG # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
Manual iteration management is deprecated and only automatic iteration cadences will be supported in the future.
Creating and deleting iterations will be fully removed in 16.0. Updating all iteration fields except for
`description` will also be removed.
On the GraphQL API the following mutations will be removed:
1. `iterationCreate`
1. `iterationDelete`
The update `updateIteration` mutation will only allow updating the iteration's `description`. The following
arguments will be removed:
1. `title`
1. `dueDate`
1. `startDate`
For more information about iteration cadences, you can refer to
[the documentation of the feature](https://docs.gitlab.com/ee/user/group/iterations/#iteration-cadences).
# The following items are not published on the docs page, but may be used in the future.
stage: Plan
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356069
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -26,8 +26,8 @@ Read more about update policies and warnings in the PostgreSQL
| GitLab version | PostgreSQL versions | Default version for fresh installs | Default version for upgrades | Notes |
| -------------- | --------------------- | ---------------------------------- | ---------------------------- | ----- |
| 14.1 | 12.6, 13.3 | 12.6 | 12.6 | PostgreSQL 13 available for fresh installations if not using [Geo](../geo/index.md#requirements-for-running-geo) or [Patroni](../postgresql/index.md#postgresql-replication-and-failover-with-omnibus-gitlab).
| 14.0 | 12.6 | 12.6 | 12.6 | HA installations with repmgr are no longer supported and will be prevented from upgrading to Omnibus GitLab 14.0 |
| 14.1 | 12.7, 13.3 | 12.7 | 12.7 | PostgreSQL 13 available for fresh installations if not using [Geo](../geo/index.md#requirements-for-running-geo) or [Patroni](../postgresql/index.md#postgresql-replication-and-failover-with-omnibus-gitlab).
| 14.0 | 12.7 | 12.7 | 12.7 | HA installations with repmgr are no longer supported and will be prevented from upgrading to Omnibus GitLab 14.0 |
| 13.8 | 11.9, 12.4 | 12.4 | 12.4 | Package upgrades automatically performed PostgreSQL upgrade for nodes that are not part of a Geo or HA cluster.). |
| 13.7 | 11.9, 12.4 | 12.4 | 11.9 | For upgrades users can manually upgrade to 12.4 following the [upgrade docs](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-133-and-later). |
| 13.4 | 11.9, 12.4 | 11.9 | 11.9 | Package upgrades aborted if users not running PostgreSQL 11 already |

View File

@ -28,10 +28,10 @@ The following lists the currently supported OSs and their possible EOL dates.
| Ubuntu 18.04 | GitLab CE / GitLab EE 10.7.0 | amd64 | April 2023 | <https://wiki.ubuntu.com/Releases> |
| Ubuntu 20.04 | GitLab CE / GitLab EE 13.2.0 | amd64, arm64 | April 2025 | <https://wiki.ubuntu.com/Releases> |
| Amazon Linux 2 | GitLab CE / GitLab EE 14.9.0 | amd64, arm64 | June 2023 | <https://aws.amazon.com/amazon-linux-2/faqs/> |
| Raspbian Buster | GitLab CE 12.2.0 | armhf | 2022 | <https://wiki.debian.org/DebianReleases#Production_Releases> |
| Raspberry Pi OS (Buster) (formerly known as Raspbian Buster) | GitLab CE 12.2.0 | armhf | 2024 | <https://www.raspberrypi.com/news/new-old-functionality-with-raspberry-pi-os-legacy/> |
NOTE:
CentOS 8 will be EOL on December 31, 2021. In GitLab 14.5 and later,
CentOS 8 was EOL on December 31, 2021. In GitLab 14.5 and later,
[CentOS builds work in AlmaLinux](https://gitlab.com/gitlab-org/distribution/team-tasks/-/issues/954#note_730198505).
We will officially support all distributions that are binary compatible with Red Hat Enterprise Linux.
This gives users a path forward for their CentOS 8 builds at its end of life.
@ -78,7 +78,7 @@ release for them can be found below:
| Ubuntu 14.04 | [April 2019](https://ubuntu.com/info/release-end-of-life) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_11.10&dist=ubuntu%2Ftrusty) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_11.10&dist=ubuntu%2Ftrusty) 11.10 |
| OpenSUSE 42.3 | [July 2019](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-12.1&dist=opensuse%2F42.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-12.1&dist=opensuse%2F42.3) 12.1 |
| OpenSUSE 15.0 | [December 2019](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-12.5&dist=opensuse%2F15.0) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-12.5&dist=opensuse%2F15.0) 12.5 |
| Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.2&dist=raspbian%2Fstretch) 13.3 |
| Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.3&dist=raspbian%2Fstretch) 13.3 |
| Debian Jessie | [June 2020](https://www.debian.org/News/2020/20200709) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_13.2&dist=debian%2Fjessie) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_13.2&dist=debian%2Fjessie) 13.3 |
| CentOS 6 | [November 2020](https://wiki.centos.org/About/Product) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=13.6&filter=all&filter=all&dist=el%2F6) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=13.6&filter=all&filter=all&dist=el%2F6) 13.6 |
| OpenSUSE 15.1 | [November 2020](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-13.12&dist=opensuse%2F15.1) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-13.12&dist=opensuse%2F15.1) 13.12 |

View File

@ -448,7 +448,7 @@ Example response:
## List project's runners
List all runners available in the project, including from ancestor groups and [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners).
List all runners available in the project, including from ancestor groups and [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners-for-a-project).
```plaintext
GET /projects/:id/runners
@ -566,7 +566,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
## List group's runners
List all runners available in the group as well as its ancestor groups, including [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners).
List all runners available in the group as well as its ancestor groups, including [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners-for-a-group).
```plaintext
GET /groups/:id/runners

View File

@ -37,22 +37,31 @@ If you are using GitLab.com:
- The shared runners consume the [CI/CD minutes](../pipelines/cicd_minutes.md)
included with your account.
### Enable shared runners
### Enable shared runners for a project
On GitLab.com, [shared runners](index.md) are enabled in all projects by
default.
On self-managed instances of GitLab, an administrator must [install](https://docs.gitlab.com/runner/install/index.html)
and [register](https://docs.gitlab.com/runner/register/index.html) them.
On self-managed instances of GitLab, an administrator can
[enable them for all new projects](../../user/admin_area/settings/continuous_integration.md#enable-shared-runners-for-new-projects).
You can also enable shared runners for individual projects.
For existing projects, an administrator must
[install](https://docs.gitlab.com/runner/install/index.html) and
[register](https://docs.gitlab.com/runner/register/index.html) them.
To enable shared runners:
To enable shared runners for a project:
1. Go to the project's **Settings > CI/CD** and expand the **Runners** section.
1. Select **Enable shared runners for this project**.
### Disable shared runners
### Enable shared runners for a group
To enable shared runners for a group:
1. Go to the group's **Settings > CI/CD** and expand the **Runners** section.
1. Select **Enable shared runners for this group**.
### Disable shared runners for a project
You can disable shared runners for individual projects or for groups.
You must have the Owner role for the project
@ -68,6 +77,8 @@ Shared runners are automatically disabled for a project:
- If the shared runners setting for the parent group is disabled, and
- If overriding this setting is not permitted at the project level.
### Disable shared runners for a group
To disable shared runners for a group:
1. Go to the group's **Settings > CI/CD** and expand the **Runners** section.
@ -78,7 +89,7 @@ To disable shared runners for a group:
NOTE:
To re-enable the shared runners for a group, turn on the
**Enable shared runners for this group** toggle.
Then, an owner or maintainer must explicitly change this setting
Then, a user with the Owner or Maintainer role must explicitly change this setting
for each project subgroup or project.
### How shared runners pick jobs

View File

@ -19,8 +19,29 @@ must be documented. For context, see the
When you document feature flags, you must:
- [Add a note at the start of the topic](#use-a-note-to-describe-the-state-of-the-feature-flag).
- [Add version history text](#add-version-history-text).
- [Add a note at the start of the topic](#use-a-note-to-describe-the-state-of-the-feature-flag).
## Add version history text
When the state of a flag changes (for example, disabled by default to enabled by default), add the change to the version history.
Possible version history entries are:
```markdown
> - [Introduced](issue-link) in GitLab X.X [with a flag](../../administration/feature_flags.md) named <flag name>. Disabled by default.
> - [Enabled on GitLab.com](issue-link) in GitLab X.X.
> - [Enabled on GitLab.com](issue-link) in GitLab X.X. Available to GitLab.com administrators only.
> - [Enabled on self-managed](issue-link) in GitLab X.X.
> - [Generally available](issue-link) in GitLab X.Y. [Feature flag <flag name>](issue-link) removed.
```
You can combine entries if they happened in the same release:
```markdown
> - Introduced in GitLab 14.2 [with a flag](../../administration/feature_flags.md) named `ci_include_rules`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3.
```
## Use a note to describe the state of the feature flag
@ -30,7 +51,8 @@ The note has three parts, and follows this structure:
```markdown
FLAG:
<Self-managed GitLab availability information.> <GitLab.com availability information.>
<Self-managed GitLab availability information.>
<GitLab.com availability information.>
<This feature is not ready for production use.>
```
@ -61,27 +83,6 @@ If needed, you can add this sentence:
`The feature is not ready for production use.`
## Add version history text
When the state of a flag changes (for example, disabled by default to enabled by default), add the change to the version history.
Possible version history entries are:
```markdown
> - [Introduced](issue-link) in GitLab X.X [with a flag](../../administration/feature_flags.md) named <flag name>. Disabled by default.
> - [Enabled on GitLab.com](issue-link) in GitLab X.X.
> - [Enabled on GitLab.com](issue-link) in GitLab X.X. Available to GitLab.com administrators only.
> - [Enabled on self-managed](issue-link) in GitLab X.X.
> - [Generally available](issue-link) in GitLab X.Y. [Feature flag <flag name>](issue-link) removed.
```
You can combine entries if they happened in the same release:
```markdown
> - Introduced in GitLab 14.2 [with a flag](../../administration/feature_flags.md) named `ci_include_rules`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3.
```
## Feature flag documentation examples
The following examples show the progression of a feature flag.

View File

@ -760,7 +760,7 @@ To set up Service Ping locally, you must:
1. Clone and start [Versions Application](https://gitlab.com/gitlab-services/version-gitlab-com).
Make sure you run `docker-compose up` to start a PostgreSQL and Redis instance.
1. Point GitLab to the Versions Application endpoint instead of the default endpoint:
1. Open [service_ping/submit_service.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/service_ping/submit_service.rb#L5) in your local and modified `PRODUCTION_URL`.
1. Open [service_ping/submit_service.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/service_ping/submit_service.rb#L5) locally and modify `STAGING_BASE_URL`.
1. Set it to the local Versions Application URL: `http://localhost:3000/usage_data`.
### Test local setup

View File

@ -42,6 +42,38 @@ Each deprecation has a **planned removal milestone** and indicates whether it is
Most of the deprecations are **planned for removal in 15.0**, and many of them are **breaking changes**.
## 14.10
### Manual iteration management
WARNING:
This feature will be changed or removed in 16.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
Manual iteration management is deprecated and only automatic iteration cadences will be supported in the future.
Creating and deleting iterations will be fully removed in 16.0. Updating all iteration fields except for
`description` will also be removed.
On the GraphQL API the following mutations will be removed:
1. `iterationCreate`
1. `iterationDelete`
The update `updateIteration` mutation will only allow updating the iteration's `description`. The following
arguments will be removed:
1. `title`
1. `dueDate`
1. `startDate`
For more information about iteration cadences, you can refer to
[the documentation of the feature](https://docs.gitlab.com/ee/user/group/iterations/#iteration-cadences).
**Planned removal milestone: 16.0 (2023-04-22)**
## 14.9
### Background upload for object storage

View File

@ -28,7 +28,18 @@ From now on, every existing project and newly created ones that don't have a
If you want to disable it for a specific project, you can do so in
[its settings](../../../topics/autodevops/index.md#enable-or-disable-auto-devops).
## Shared runner details
## Enable shared runners for new projects
You can set all new projects to have the instance's shared runners available by default.
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. Select the **Enable shared runners for new projects** checkbox.
Any time a new project is created, the shared runners are available.
## Add a message for shared runners
To display details about the instance's shared runners in all projects'
runner settings:
@ -36,16 +47,17 @@ runner settings:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. Enter your shared runner details in the **Shared runner details** field.
1. Enter text, including Markdown if you want, in the **Shared runner details** field. For example:
You can use [Markdown](../../markdown.md) for improved formatting. To see the rendered
details:
![Shared runner details input](img/continuous_integration_shared_runner_details_input_v14_10.png)
To view the rendered details:
1. On the top bar, select **Menu > Project** and select any group or project.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Runners**.
![Shared runner details example](img/continuous_integration_shared_runner_details_v14_0.png)
![Shared runner details example](img/continuous_integration_shared_runner_details_v14_10.png)
## Maximum artifacts size

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -45,7 +45,7 @@ From there you can create a new iteration or select an iteration to get a more d
WARNING:
Manual iteration management is in its end-of-life process. Creating an iteration is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069)
for use in GitLab 14.10, and is planned for removal in GitLab 15.6.
for use in GitLab 14.10, and is planned for removal in GitLab 16.0.
Prerequisites:
@ -66,7 +66,7 @@ To create an iteration:
WARNING:
Editing all attributes, with the exception of `description` is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069)
for use in GitLab 14.10, and is planned for removal in GitLab 15.6.
for use in GitLab 14.10, and is planned for removal in GitLab 16.0.
In the future only editing an iteration's `description` will be allowed.
Prerequisites:
@ -82,7 +82,7 @@ To edit an iteration, select the three-dot menu (**{ellipsis_v}**) > **Edit**.
WARNING:
Manual iteration management is in its end-of-life process. Deleting an iteration is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069)
for use in GitLab 14.10, and is planned for removal in GitLab 15.6.
for use in GitLab 14.10, and is planned for removal in GitLab 16.0.
Prerequisites:

View File

@ -525,6 +525,7 @@ GitLab Flavored Markdown recognizes the following:
| merge request | `!123` | `namespace/project!123` | `project!123` |
| snippet | `$123` | `namespace/project$123` | `project$123` |
| [epic](group/epics/index.md) | `&123` | `group1/subgroup&123` | |
| [iteration](group/iterations/index.md) | `*iteration:"iteration title"`| | |
| [vulnerability](application_security/vulnerabilities/index.md) <sup>1</sup> | `[vulnerability:123]` | `[vulnerability:namespace/project/123]` | `[vulnerability:project/123]` |
| feature flag | `[feature_flag:123]` | `[feature_flag:namespace/project/123]` | `[feature_flag:project/123]` |
| label by ID | `~123` | `namespace/project~123` | `project~123` |

View File

@ -238,7 +238,7 @@ and the exports between them are compatible.
### Project fails to import due to mismatch
If the [shared runners enablement](../../../ci/runners/runners_scope.md#enable-shared-runners)
If the [shared runners enablement](../../../ci/runners/runners_scope.md#enable-shared-runners-for-a-project)
does not match between the exported project, and the project import, the project fails to import.
Review [issue 276930](https://gitlab.com/gitlab-org/gitlab/-/issues/276930), and either:

View File

@ -101,6 +101,12 @@ These shortcuts are available when viewing issues and [merge requests](project/m
| <kbd>b</kbd> | Copy source branch name (merge requests only). |
| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
Merge requests additionally support the following shortcuts:
| macOS shortcut | Windows shortcut | Description |
|---------------------------------|---------------------|-------------|
| <kbd>Command</kbd> + <kbd>p</kbd> | <kbd>Control</kbd> + <kbd>p</kbd> | Search for, and then jump to a file for review. |
### Project files
These shortcuts are available when browsing the files in a project (go to

View File

@ -21400,7 +21400,7 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they wont otherwise be used."
msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{gitlab_issues_link_start}disabling GitLab issues%{link_end} if they won't otherwise be used."
msgstr ""
msgid "JiraService|Enable Jira issue creation from vulnerabilities"
@ -21451,9 +21451,6 @@ msgstr ""
msgid "JiraService|Jira comments are created when an issue is referenced in a merge request."
msgstr ""
msgid "JiraService|Jira issue type"
msgstr ""
msgid "JiraService|Jira issues"
msgstr ""

View File

@ -43,7 +43,10 @@ module QA
[upstream_project, downstream_project].each(&:remove_via_api!)
end
it 'creates a multi-project pipeline', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348032' do
it(
'creates a multi-project pipeline',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358064'
) do
Page::Project::Pipeline::Show.perform do |show|
expect(show).to have_passed
expect(show).not_to have_job(downstream_job_name)

View File

@ -25,7 +25,10 @@ module QA
runner.remove_via_api!
end
it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348092' do
it(
'parent pipelines passes if child passes',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358062'
) do
add_ci_files(success_child_ci_file)
Flow::Pipeline.visit_latest_pipeline
@ -35,7 +38,10 @@ module QA
end
end
it 'parent pipeline fails if child fails', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348091' do
it(
'parent pipeline fails if child fails',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358063'
) do
add_ci_files(fail_child_ci_file)
Flow::Pipeline.visit_latest_pipeline

View File

@ -25,7 +25,10 @@ module QA
runner.remove_via_api!
end
it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348093' do
it(
'parent pipelines passes if child passes',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358059'
) do
add_ci_files(success_child_ci_file)
Flow::Pipeline.visit_latest_pipeline
@ -35,7 +38,10 @@ module QA
end
end
it 'parent pipeline passes even if child fails', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348094' do
it(
'parent pipeline passes even if child fails',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358060'
) do
add_ci_files(fail_child_ci_file)
Flow::Pipeline.visit_latest_pipeline

View File

@ -79,7 +79,11 @@ RSpec.configure do |config|
# If any tests failed, leave the resources behind to help troubleshoot, otherwise remove them.
# Do not remove the shared resource on live environments
begin
QA::Resource::ReusableCollection.remove_all_via_api! if !suite.reporter.failed_examples.present? && !QA::Runtime::Env.running_on_dot_com?
next if suite.reporter.failed_examples.present?
next unless QA::Runtime::Scenario.attributes.include?(:gitlab_address)
next if QA::Runtime::Env.running_on_dot_com?
QA::Resource::ReusableCollection.remove_all_via_api!
rescue QA::Resource::Errors::InternalServerError => e
# Temporarily prevent this error from failing jobs while the cause is investigated
# See https://gitlab.com/gitlab-org/gitlab/-/issues/354387

View File

@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe "Admin Runners" do
include StubENV
include Spec::Support::Helpers::ModalHelpers
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
@ -15,7 +14,7 @@ RSpec.describe "Admin Runners" do
wait_for_requests
end
describe "Runners page", :js do
describe "Admin Runners page", :js do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:namespace) { create(:namespace) }
@ -486,63 +485,14 @@ RSpec.describe "Admin Runners" do
end
end
describe 'runners registration' do
let!(:token) { Gitlab::CurrentSettings.runners_registration_token }
describe "runners registration" do
before do
visit admin_runners_path
click_on 'Register an instance runner'
end
describe 'show registration instructions' do
before do
click_on 'Show runner installation and registration instructions'
wait_for_requests
end
it 'opens runner installation modal' do
expect(page).to have_text "Install a runner"
expect(page).to have_text "Environment"
expect(page).to have_text "Architecture"
expect(page).to have_text "Download and install binary"
end
it 'dismisses runner installation modal' do
within_modal do
click_button('Close', match: :first)
end
expect(page).not_to have_text "Install a runner"
end
end
it 'has a registration token' do
click_on 'Click to reveal'
expect(page.find('[data-testid="token-value"]')).to have_content(token)
end
describe 'reset registration token' do
let(:page_token) { find('[data-testid="token-value"]').text }
before do
click_on 'Reset registration token'
within_modal do
click_button('Reset token', match: :first)
end
wait_for_requests
end
it 'changes registration token' do
click_on 'Register an instance runner'
click_on 'Click to reveal'
expect(page_token).not_to eq token
end
it_behaves_like "shows and resets runner registration token" do
let(:dropdown_text) { 'Register an instance runner' }
let(:registration_token) { Gitlab::CurrentSettings.runners_registration_token }
end
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe "Group Runners" do
let_it_be(:group_owner) { create(:user) }
let_it_be(:group) { create(:group) }
let!(:group_registration_token) { group.runners_token }
before do
group.add_owner(group_owner)
sign_in(group_owner)
end
describe "Group runners page", :js do
describe "runners registration" do
before do
visit group_runners_path(group)
end
it_behaves_like "shows and resets runner registration token" do
let(:dropdown_text) { 'Register a group runner' }
let(:registration_token) { group_registration_token }
end
end
end
end

View File

@ -71,6 +71,12 @@ RSpec.describe "User creates issue" do
expect(preview).to have_css("gl-emoji")
expect(textarea).not_to be_visible
click_button("Write")
fill_in("Description", with: "/confidential")
click_button("Preview")
expect(form).to have_content('Makes this issue confidential.')
end
end
end

View File

@ -35,6 +35,12 @@ RSpec.describe "Issues > User edits issue", :js do
end
expect(form).to have_button("Write")
click_button("Write")
fill_in("Description", with: "/confidential")
click_button("Preview")
expect(form).to have_content('Makes this issue confidential.')
end
it 'allows user to select unassigned' do

View File

@ -158,33 +158,32 @@ describe('Api', () => {
});
describe('group', () => {
it('fetches a group', (done) => {
it('fetches a group', () => {
const groupId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}`;
mock.onGet(expectedUrl).reply(httpStatus.OK, {
name: 'test',
});
Api.group(groupId, (response) => {
expect(response.name).toBe('test');
done();
return new Promise((resolve) => {
Api.group(groupId, (response) => {
expect(response.name).toBe('test');
resolve();
});
});
});
});
describe('groupMembers', () => {
it('fetches group members', (done) => {
it('fetches group members', () => {
const groupId = '54321';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/members`;
const expectedData = [{ id: 7 }];
mock.onGet(expectedUrl).reply(httpStatus.OK, expectedData);
Api.groupMembers(groupId)
.then(({ data }) => {
expect(data).toEqual(expectedData);
})
.then(done)
.catch(done.fail);
return Api.groupMembers(groupId).then(({ data }) => {
expect(data).toEqual(expectedData);
});
});
});
@ -233,7 +232,7 @@ describe('Api', () => {
});
describe('groupMilestones', () => {
it('fetches group milestones', (done) => {
it('fetches group milestones', () => {
const groupId = '16';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/milestones`;
const expectedData = [
@ -253,17 +252,14 @@ describe('Api', () => {
];
mock.onGet(expectedUrl).reply(httpStatus.OK, expectedData);
Api.groupMilestones(groupId)
.then(({ data }) => {
expect(data).toEqual(expectedData);
})
.then(done)
.catch(done.fail);
return Api.groupMilestones(groupId).then(({ data }) => {
expect(data).toEqual(expectedData);
});
});
});
describe('groups', () => {
it('fetches groups', (done) => {
it('fetches groups', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups.json`;
@ -273,16 +269,18 @@ describe('Api', () => {
},
]);
Api.groups(query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done();
return new Promise((resolve) => {
Api.groups(query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
resolve();
});
});
});
});
describe('groupLabels', () => {
it('fetches group labels', (done) => {
it('fetches group labels', () => {
const options = { params: { search: 'foo' } };
const expectedGroup = 'gitlab-org';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${expectedGroup}/labels`;
@ -293,18 +291,15 @@ describe('Api', () => {
},
]);
Api.groupLabels(expectedGroup, options)
.then((res) => {
expect(res.length).toBe(1);
expect(res[0].name).toBe('Foo Label');
})
.then(done)
.catch(done.fail);
return Api.groupLabels(expectedGroup, options).then((res) => {
expect(res.length).toBe(1);
expect(res[0].name).toBe('Foo Label');
});
});
});
describe('namespaces', () => {
it('fetches namespaces', (done) => {
it('fetches namespaces', () => {
const query = 'dummy query';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/namespaces.json`;
mock.onGet(expectedUrl).reply(httpStatus.OK, [
@ -313,16 +308,18 @@ describe('Api', () => {
},
]);
Api.namespaces(query, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done();
return new Promise((resolve) => {
Api.namespaces(query, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
resolve();
});
});
});
});
describe('projects', () => {
it('fetches projects with membership when logged in', (done) => {
it('fetches projects with membership when logged in', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`;
@ -333,14 +330,16 @@ describe('Api', () => {
},
]);
Api.projects(query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done();
return new Promise((resolve) => {
Api.projects(query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
resolve();
});
});
});
it('fetches projects without membership when not logged in', (done) => {
it('fetches projects without membership when not logged in', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`;
@ -350,31 +349,30 @@ describe('Api', () => {
},
]);
Api.projects(query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done();
return new Promise((resolve) => {
Api.projects(query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
resolve();
});
});
});
});
describe('updateProject', () => {
it('update a project with the given payload', (done) => {
it('update a project with the given payload', () => {
const projectPath = 'foo';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}`;
mock.onPut(expectedUrl).reply(httpStatus.OK, { foo: 'bar' });
Api.updateProject(projectPath, { foo: 'bar' })
.then(({ data }) => {
expect(data.foo).toBe('bar');
done();
})
.catch(done.fail);
return Api.updateProject(projectPath, { foo: 'bar' }).then(({ data }) => {
expect(data.foo).toBe('bar');
});
});
});
describe('projectUsers', () => {
it('fetches all users of a particular project', (done) => {
it('fetches all users of a particular project', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const projectPath = 'gitlab-org%2Fgitlab-ce';
@ -385,13 +383,10 @@ describe('Api', () => {
},
]);
Api.projectUsers('gitlab-org/gitlab-ce', query, options)
.then((response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
})
.then(done)
.catch(done.fail);
return Api.projectUsers('gitlab-org/gitlab-ce', query, options).then((response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
});
});
});
@ -399,38 +394,32 @@ describe('Api', () => {
const projectPath = 'abc';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests`;
it('fetches all merge requests for a project', (done) => {
it('fetches all merge requests for a project', () => {
const mockData = [{ source_branch: 'foo' }, { source_branch: 'bar' }];
mock.onGet(expectedUrl).reply(httpStatus.OK, mockData);
Api.projectMergeRequests(projectPath)
.then(({ data }) => {
expect(data.length).toEqual(2);
expect(data[0].source_branch).toBe('foo');
expect(data[1].source_branch).toBe('bar');
})
.then(done)
.catch(done.fail);
return Api.projectMergeRequests(projectPath).then(({ data }) => {
expect(data.length).toEqual(2);
expect(data[0].source_branch).toBe('foo');
expect(data[1].source_branch).toBe('bar');
});
});
it('fetches merge requests filtered with passed params', (done) => {
it('fetches merge requests filtered with passed params', () => {
const params = {
source_branch: 'bar',
};
const mockData = [{ source_branch: 'bar' }];
mock.onGet(expectedUrl, { params }).reply(httpStatus.OK, mockData);
Api.projectMergeRequests(projectPath, params)
.then(({ data }) => {
expect(data.length).toEqual(1);
expect(data[0].source_branch).toBe('bar');
})
.then(done)
.catch(done.fail);
return Api.projectMergeRequests(projectPath, params).then(({ data }) => {
expect(data.length).toEqual(1);
expect(data[0].source_branch).toBe('bar');
});
});
});
describe('projectMergeRequest', () => {
it('fetches a merge request', (done) => {
it('fetches a merge request', () => {
const projectPath = 'abc';
const mergeRequestId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}`;
@ -438,17 +427,14 @@ describe('Api', () => {
title: 'test',
});
Api.projectMergeRequest(projectPath, mergeRequestId)
.then(({ data }) => {
expect(data.title).toBe('test');
})
.then(done)
.catch(done.fail);
return Api.projectMergeRequest(projectPath, mergeRequestId).then(({ data }) => {
expect(data.title).toBe('test');
});
});
});
describe('projectMergeRequestChanges', () => {
it('fetches the changes of a merge request', (done) => {
it('fetches the changes of a merge request', () => {
const projectPath = 'abc';
const mergeRequestId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}/changes`;
@ -456,17 +442,14 @@ describe('Api', () => {
title: 'test',
});
Api.projectMergeRequestChanges(projectPath, mergeRequestId)
.then(({ data }) => {
expect(data.title).toBe('test');
})
.then(done)
.catch(done.fail);
return Api.projectMergeRequestChanges(projectPath, mergeRequestId).then(({ data }) => {
expect(data.title).toBe('test');
});
});
});
describe('projectMergeRequestVersions', () => {
it('fetches the versions of a merge request', (done) => {
it('fetches the versions of a merge request', () => {
const projectPath = 'abc';
const mergeRequestId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}/versions`;
@ -476,30 +459,24 @@ describe('Api', () => {
},
]);
Api.projectMergeRequestVersions(projectPath, mergeRequestId)
.then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].id).toBe(123);
})
.then(done)
.catch(done.fail);
return Api.projectMergeRequestVersions(projectPath, mergeRequestId).then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].id).toBe(123);
});
});
});
describe('projectRunners', () => {
it('fetches the runners of a project', (done) => {
it('fetches the runners of a project', () => {
const projectPath = 7;
const params = { scope: 'active' };
const mockData = [{ id: 4 }];
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/runners`;
mock.onGet(expectedUrl, { params }).reply(httpStatus.OK, mockData);
Api.projectRunners(projectPath, { params })
.then(({ data }) => {
expect(data).toEqual(mockData);
})
.then(done)
.catch(done.fail);
return Api.projectRunners(projectPath, { params }).then(({ data }) => {
expect(data).toEqual(mockData);
});
});
});
@ -528,7 +505,7 @@ describe('Api', () => {
});
describe('projectMilestones', () => {
it('fetches project milestones', (done) => {
it('fetches project milestones', () => {
const projectId = 1;
const options = { state: 'active' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/1/milestones`;
@ -540,13 +517,10 @@ describe('Api', () => {
},
]);
Api.projectMilestones(projectId, options)
.then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].title).toBe('milestone1');
})
.then(done)
.catch(done.fail);
return Api.projectMilestones(projectId, options).then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].title).toBe('milestone1');
});
});
});
@ -614,7 +588,7 @@ describe('Api', () => {
});
describe('newLabel', () => {
it('creates a new project label', (done) => {
it('creates a new project label', () => {
const namespace = 'some namespace';
const project = 'some project';
const labelData = { some: 'data' };
@ -633,13 +607,15 @@ describe('Api', () => {
];
});
Api.newLabel(namespace, project, labelData, (response) => {
expect(response.name).toBe('test');
done();
return new Promise((resolve) => {
Api.newLabel(namespace, project, labelData, (response) => {
expect(response.name).toBe('test');
resolve();
});
});
});
it('creates a new group label', (done) => {
it('creates a new group label', () => {
const namespace = 'group/subgroup';
const labelData = { name: 'Foo', color: '#000000' };
const expectedUrl = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespace);
@ -654,15 +630,17 @@ describe('Api', () => {
];
});
Api.newLabel(namespace, undefined, labelData, (response) => {
expect(response.name).toBe('Foo');
done();
return new Promise((resolve) => {
Api.newLabel(namespace, undefined, labelData, (response) => {
expect(response.name).toBe('Foo');
resolve();
});
});
});
});
describe('groupProjects', () => {
it('fetches group projects', (done) => {
it('fetches group projects', () => {
const groupId = '123456';
const query = 'dummy query';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/projects.json`;
@ -672,10 +650,12 @@ describe('Api', () => {
},
]);
Api.groupProjects(groupId, query, {}, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done();
return new Promise((resolve) => {
Api.groupProjects(groupId, query, {}, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
resolve();
});
});
});
@ -764,12 +744,14 @@ describe('Api', () => {
templateKey,
)}`;
it('fetches an issue template', (done) => {
it('fetches an issue template', () => {
mock.onGet(expectedUrl).reply(httpStatus.OK, 'test');
Api.issueTemplate(namespace, project, templateKey, templateType, (error, response) => {
expect(response).toBe('test');
done();
return new Promise((resolve) => {
Api.issueTemplate(namespace, project, templateKey, templateType, (_, response) => {
expect(response).toBe('test');
resolve();
});
});
});
@ -777,8 +759,11 @@ describe('Api', () => {
it('rejects the Promise', () => {
mock.onGet(expectedUrl).replyOnce(httpStatus.INTERNAL_SERVER_ERROR);
Api.issueTemplate(namespace, project, templateKey, templateType, () => {
expect(mock.history.get).toHaveLength(1);
return new Promise((resolve) => {
Api.issueTemplate(namespace, project, templateKey, templateType, () => {
expect(mock.history.get).toHaveLength(1);
resolve();
});
});
});
});
@ -790,19 +775,21 @@ describe('Api', () => {
const templateType = 'template type';
const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/templates/${templateType}`;
it('fetches all templates by type', (done) => {
it('fetches all templates by type', () => {
const expectedData = [
{ key: 'Template1', name: 'Template 1', content: 'This is template 1!' },
];
mock.onGet(expectedUrl).reply(httpStatus.OK, expectedData);
Api.issueTemplates(namespace, project, templateType, (error, response) => {
expect(response.length).toBe(1);
const { key, name, content } = response[0];
expect(key).toBe('Template1');
expect(name).toBe('Template 1');
expect(content).toBe('This is template 1!');
done();
return new Promise((resolve) => {
Api.issueTemplates(namespace, project, templateType, (_, response) => {
expect(response.length).toBe(1);
const { key, name, content } = response[0];
expect(key).toBe('Template1');
expect(name).toBe('Template 1');
expect(content).toBe('This is template 1!');
resolve();
});
});
});
@ -818,34 +805,44 @@ describe('Api', () => {
});
describe('projectTemplates', () => {
it('fetches a list of templates', (done) => {
it('fetches a list of templates', () => {
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/gitlab-org%2Fgitlab-ce/templates/licenses`;
mock.onGet(expectedUrl).reply(httpStatus.OK, 'test');
Api.projectTemplates('gitlab-org/gitlab-ce', 'licenses', {}, (response) => {
expect(response).toBe('test');
done();
return new Promise((resolve) => {
Api.projectTemplates('gitlab-org/gitlab-ce', 'licenses', {}, (response) => {
expect(response).toBe('test');
resolve();
});
});
});
});
describe('projectTemplate', () => {
it('fetches a single template', (done) => {
it('fetches a single template', () => {
const data = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/gitlab-org%2Fgitlab-ce/templates/licenses/test%20license`;
mock.onGet(expectedUrl).reply(httpStatus.OK, 'test');
Api.projectTemplate('gitlab-org/gitlab-ce', 'licenses', 'test license', data, (response) => {
expect(response).toBe('test');
done();
return new Promise((resolve) => {
Api.projectTemplate(
'gitlab-org/gitlab-ce',
'licenses',
'test license',
data,
(response) => {
expect(response).toBe('test');
resolve();
},
);
});
});
});
describe('users', () => {
it('fetches users', (done) => {
it('fetches users', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users.json`;
@ -855,68 +852,56 @@ describe('Api', () => {
},
]);
Api.users(query, options)
.then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
})
.then(done)
.catch(done.fail);
return Api.users(query, options).then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
});
});
});
describe('user', () => {
it('fetches single user', (done) => {
it('fetches single user', () => {
const userId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users/${userId}`;
mock.onGet(expectedUrl).reply(httpStatus.OK, {
name: 'testuser',
});
Api.user(userId)
.then(({ data }) => {
expect(data.name).toBe('testuser');
})
.then(done)
.catch(done.fail);
return Api.user(userId).then(({ data }) => {
expect(data.name).toBe('testuser');
});
});
});
describe('user counts', () => {
it('fetches single user counts', (done) => {
it('fetches single user counts', () => {
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/user_counts`;
mock.onGet(expectedUrl).reply(httpStatus.OK, {
merge_requests: 4,
});
Api.userCounts()
.then(({ data }) => {
expect(data.merge_requests).toBe(4);
})
.then(done)
.catch(done.fail);
return Api.userCounts().then(({ data }) => {
expect(data.merge_requests).toBe(4);
});
});
});
describe('user status', () => {
it('fetches single user status', (done) => {
it('fetches single user status', () => {
const userId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users/${userId}/status`;
mock.onGet(expectedUrl).reply(httpStatus.OK, {
message: 'testmessage',
});
Api.userStatus(userId)
.then(({ data }) => {
expect(data.message).toBe('testmessage');
})
.then(done)
.catch(done.fail);
return Api.userStatus(userId).then(({ data }) => {
expect(data.message).toBe('testmessage');
});
});
});
describe('user projects', () => {
it('fetches all projects that belong to a particular user', (done) => {
it('fetches all projects that belong to a particular user', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const userId = '123456';
@ -927,16 +912,18 @@ describe('Api', () => {
},
]);
Api.userProjects(userId, query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done();
return new Promise((resolve) => {
Api.userProjects(userId, query, options, (response) => {
expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
resolve();
});
});
});
});
describe('commitPipelines', () => {
it('fetches pipelines for a given commit', (done) => {
it('fetches pipelines for a given commit', () => {
const projectId = 'example/foobar';
const commitSha = 'abc123def';
const expectedUrl = `${dummyUrlRoot}/${projectId}/commit/${commitSha}/pipelines`;
@ -946,13 +933,10 @@ describe('Api', () => {
},
]);
Api.commitPipelines(projectId, commitSha)
.then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
})
.then(done)
.catch(done.fail);
return Api.commitPipelines(projectId, commitSha).then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
});
});
});
@ -977,7 +961,7 @@ describe('Api', () => {
});
describe('createBranch', () => {
it('creates new branch', (done) => {
it('creates new branch', () => {
const ref = 'main';
const branch = 'new-branch-name';
const dummyProjectPath = 'gitlab-org/gitlab-ce';
@ -991,18 +975,15 @@ describe('Api', () => {
name: branch,
});
Api.createBranch(dummyProjectPath, { ref, branch })
.then(({ data }) => {
expect(data.name).toBe(branch);
expect(axios.post).toHaveBeenCalledWith(expectedUrl, { ref, branch });
})
.then(done)
.catch(done.fail);
return Api.createBranch(dummyProjectPath, { ref, branch }).then(({ data }) => {
expect(data.name).toBe(branch);
expect(axios.post).toHaveBeenCalledWith(expectedUrl, { ref, branch });
});
});
});
describe('projectForks', () => {
it('gets forked projects', (done) => {
it('gets forked projects', () => {
const dummyProjectPath = 'gitlab-org/gitlab-ce';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${encodeURIComponent(
dummyProjectPath,
@ -1012,20 +993,17 @@ describe('Api', () => {
mock.onGet(expectedUrl).replyOnce(httpStatus.OK, ['fork']);
Api.projectForks(dummyProjectPath, { visibility: 'private' })
.then(({ data }) => {
expect(data).toEqual(['fork']);
expect(axios.get).toHaveBeenCalledWith(expectedUrl, {
params: { visibility: 'private' },
});
})
.then(done)
.catch(done.fail);
return Api.projectForks(dummyProjectPath, { visibility: 'private' }).then(({ data }) => {
expect(data).toEqual(['fork']);
expect(axios.get).toHaveBeenCalledWith(expectedUrl, {
params: { visibility: 'private' },
});
});
});
});
describe('createContextCommits', () => {
it('creates a new context commit', (done) => {
it('creates a new context commit', () => {
const projectPath = 'abc';
const mergeRequestId = '123456';
const commitsData = ['abcdefg'];
@ -1044,17 +1022,16 @@ describe('Api', () => {
},
]);
Api.createContextCommits(projectPath, mergeRequestId, expectedData)
.then(({ data }) => {
return Api.createContextCommits(projectPath, mergeRequestId, expectedData).then(
({ data }) => {
expect(data[0].title).toBe('Dummy commit');
})
.then(done)
.catch(done.fail);
},
);
});
});
describe('allContextCommits', () => {
it('gets all context commits', (done) => {
it('gets all context commits', () => {
const projectPath = 'abc';
const mergeRequestId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}/context_commits`;
@ -1065,17 +1042,14 @@ describe('Api', () => {
.onGet(expectedUrl)
.replyOnce(200, [{ id: 'abcdef', short_id: 'abcdefghi', title: 'Dummy commit title' }]);
Api.allContextCommits(projectPath, mergeRequestId)
.then(({ data }) => {
expect(data[0].title).toBe('Dummy commit title');
})
.then(done)
.catch(done.fail);
return Api.allContextCommits(projectPath, mergeRequestId).then(({ data }) => {
expect(data[0].title).toBe('Dummy commit title');
});
});
});
describe('removeContextCommits', () => {
it('removes context commits', (done) => {
it('removes context commits', () => {
const projectPath = 'abc';
const mergeRequestId = '123456';
const commitsData = ['abcdefg'];
@ -1088,12 +1062,9 @@ describe('Api', () => {
mock.onDelete(expectedUrl).replyOnce(204);
Api.removeContextCommits(projectPath, mergeRequestId, expectedData)
.then(() => {
expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { data: expectedData });
})
.then(done)
.catch(done.fail);
return Api.removeContextCommits(projectPath, mergeRequestId, expectedData).then(() => {
expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { data: expectedData });
});
});
});
@ -1336,41 +1307,37 @@ describe('Api', () => {
});
describe('updateIssue', () => {
it('update an issue with the given payload', (done) => {
it('update an issue with the given payload', () => {
const projectId = 8;
const issue = 1;
const expectedArray = [1, 2, 3];
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/issues/${issue}`;
mock.onPut(expectedUrl).reply(httpStatus.OK, { assigneeIds: expectedArray });
Api.updateIssue(projectId, issue, { assigneeIds: expectedArray })
.then(({ data }) => {
expect(data.assigneeIds).toEqual(expectedArray);
done();
})
.catch(done.fail);
return Api.updateIssue(projectId, issue, { assigneeIds: expectedArray }).then(({ data }) => {
expect(data.assigneeIds).toEqual(expectedArray);
});
});
});
describe('updateMergeRequest', () => {
it('update an issue with the given payload', (done) => {
it('update an issue with the given payload', () => {
const projectId = 8;
const mergeRequest = 1;
const expectedArray = [1, 2, 3];
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/merge_requests/${mergeRequest}`;
mock.onPut(expectedUrl).reply(httpStatus.OK, { assigneeIds: expectedArray });
Api.updateMergeRequest(projectId, mergeRequest, { assigneeIds: expectedArray })
.then(({ data }) => {
return Api.updateMergeRequest(projectId, mergeRequest, { assigneeIds: expectedArray }).then(
({ data }) => {
expect(data.assigneeIds).toEqual(expectedArray);
done();
})
.catch(done.fail);
},
);
});
});
describe('tags', () => {
it('fetches all tags of a particular project', (done) => {
it('fetches all tags of a particular project', () => {
const query = 'dummy query';
const options = { unused: 'option' };
const projectId = 8;
@ -1381,13 +1348,10 @@ describe('Api', () => {
},
]);
Api.tags(projectId, query, options)
.then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
})
.then(done)
.catch(done.fail);
return Api.tags(projectId, query, options).then(({ data }) => {
expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
});
});
});

View File

@ -1,33 +0,0 @@
import { shallowMount } from '@vue/test-utils';
import IssuableTitle from '~/boards/components/issuable_title.vue';
describe('IssuableTitle', () => {
let wrapper;
const defaultProps = {
title: 'One',
refPath: 'path',
};
const createComponent = () => {
wrapper = shallowMount(IssuableTitle, {
propsData: { ...defaultProps },
});
};
const findIssueContent = () => wrapper.find('[data-testid="issue-title"]');
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders a title of an issue in the sidebar', () => {
expect(findIssueContent().text()).toContain('One');
});
it('renders a referencePath of an issue in the sidebar', () => {
expect(findIssueContent().text()).toContain('path');
});
});

View File

@ -80,7 +80,7 @@ describe('diffs/components/commit_item', () => {
const imgElement = avatarElement.find('img');
expect(avatarElement.attributes('href')).toBe(commit.author.web_url);
expect(imgElement.classes()).toContain('s40');
expect(imgElement.classes()).toContain('s32');
expect(imgElement.attributes('alt')).toBe(commit.author.name);
expect(imgElement.attributes('src')).toBe(commit.author.avatar_url);
});

View File

@ -10,7 +10,6 @@ describe('JiraIssuesFields', () => {
let wrapper;
const defaultProps = {
editProjectPath: '/edit',
showJiraIssuesIntegration: true,
showJiraVulnerabilitiesIntegration: true,
upgradePlanPath: 'https://gitlab.com',
@ -46,7 +45,6 @@ describe('JiraIssuesFields', () => {
const findPremiumUpgradeCTA = () => wrapper.findByTestId('premium-upgrade-cta');
const findUltimateUpgradeCTA = () => wrapper.findByTestId('ultimate-upgrade-cta');
const findJiraForVulnerabilities = () => wrapper.findByTestId('jira-for-vulnerabilities');
const findConflictWarning = () => wrapper.findByTestId('conflict-warning-text');
const setEnableCheckbox = async (isEnabled = true) =>
findEnableCheckbox().vm.$emit('input', isEnabled);
@ -75,10 +73,9 @@ describe('JiraIssuesFields', () => {
});
if (showJiraIssuesIntegration) {
it('renders checkbox and input field', () => {
it('renders enable checkbox', () => {
expect(findEnableCheckbox().exists()).toBe(true);
expect(findEnableCheckboxDisabled()).toBeUndefined();
expect(findProjectKey().exists()).toBe(true);
});
it('does not render the Premium CTA', () => {
@ -98,9 +95,8 @@ describe('JiraIssuesFields', () => {
});
}
} else {
it('does not render checkbox and input field', () => {
it('does not render enable checkbox', () => {
expect(findEnableCheckbox().exists()).toBe(false);
expect(findProjectKey().exists()).toBe(false);
});
it('renders the Premium CTA', () => {
@ -122,12 +118,8 @@ describe('JiraIssuesFields', () => {
createComponent({ props: { initialProjectKey: '' } });
});
it('renders disabled project_key input', () => {
const projectKey = findProjectKey();
expect(projectKey.exists()).toBe(true);
expect(projectKey.attributes('disabled')).toBe('disabled');
expect(projectKey.attributes('required')).toBeUndefined();
it('does not render project_key input', () => {
expect(findProjectKey().exists()).toBe(false);
});
// As per https://vuejs.org/v2/guide/forms.html#Checkbox-1,
@ -137,45 +129,23 @@ describe('JiraIssuesFields', () => {
});
describe('when isInheriting = true', () => {
it('disables checkbox and sets input as readonly', () => {
it('disables checkbox', () => {
createComponent({ isInheriting: true });
expect(findEnableCheckboxDisabled()).toBe('disabled');
expect(findProjectKey().attributes('readonly')).toBe('readonly');
});
});
describe('on enable issues', () => {
it('enables project_key input as required', async () => {
it('renders project_key input as required', async () => {
await setEnableCheckbox(true);
expect(findProjectKey().attributes('disabled')).toBeUndefined();
expect(findProjectKey().exists()).toBe(true);
expect(findProjectKey().attributes('required')).toBe('required');
});
});
});
it('contains link to editProjectPath', () => {
createComponent();
expect(wrapper.find(`a[href="${defaultProps.editProjectPath}"]`).exists()).toBe(true);
});
describe('GitLab issues warning', () => {
it.each`
gitlabIssuesEnabled | scenario
${true} | ${'displays conflict warning'}
${false} | ${'does not display conflict warning'}
`(
'$scenario when `gitlabIssuesEnabled` is `$gitlabIssuesEnabled`',
({ gitlabIssuesEnabled }) => {
createComponent({ props: { gitlabIssuesEnabled } });
expect(findConflictWarning().exists()).toBe(gitlabIssuesEnabled);
},
);
});
describe('Vulnerabilities creation', () => {
beforeEach(() => {
createComponent();

View File

@ -101,6 +101,21 @@ describe('Markdown field component', () => {
expect(subject.find('.zen-backdrop textarea').element).not.toBeNull();
});
it('renders referenced commands on markdown preview', async () => {
axiosMock
.onPost(markdownPreviewPath)
.reply(200, { references: { users: [], commands: 'test command' } });
previewLink = getPreviewLink();
previewLink.vm.$emit('click', { target: {} });
await axios.waitFor(markdownPreviewPath);
const referencedCommands = subject.find('[data-testid="referenced-commands"]');
expect(referencedCommands.exists()).toBe(true);
expect(referencedCommands.text()).toContain('test command');
});
describe('markdown preview', () => {
beforeEach(() => {
axiosMock.onPost(markdownPreviewPath).reply(200, { body: previewHTML });

View File

@ -288,7 +288,7 @@ RSpec.describe IssuablesHelper do
canUpdate: true,
canDestroy: true,
issuableRef: "##{issue.iid}",
markdownPreviewPath: "/#{@project.full_path}/preview_markdown",
markdownPreviewPath: "/#{@project.full_path}/preview_markdown?target_id=#{issue.iid}&target_type=Issue",
markdownDocsPath: '/help/user/markdown',
lockVersion: issue.lock_version,
projectPath: @project.path,

View File

@ -88,6 +88,18 @@ RSpec.describe BulkImports::RelationExportService do
subject.execute
end
context 'when export is recently finished' do
it 'returns recently finished export instead of re-exporting' do
updated_at = 5.seconds.ago
export.update!(status: 1, updated_at: updated_at)
expect { subject.execute }.not_to change { export.updated_at }
expect(export.status).to eq(1)
expect(export.updated_at).to eq(updated_at)
end
end
end
context 'when exception occurs during export' do

View File

@ -0,0 +1,62 @@
# frozen_string_literal: true
RSpec.shared_examples 'shows and resets runner registration token' do
include Spec::Support::Helpers::ModalHelpers
before do
click_on dropdown_text
end
describe 'shows registration instructions' do
before do
click_on 'Show runner installation and registration instructions'
wait_for_requests
end
it 'opens runner installation modal', :aggregate_failures do
within_modal do
expect(page).to have_text "Install a runner"
expect(page).to have_text "Environment"
expect(page).to have_text "Architecture"
expect(page).to have_text "Download and install binary"
end
end
it 'dismisses runner installation modal' do
within_modal do
click_button('Close', match: :first)
end
expect(page).not_to have_text "Install a runner"
end
end
it 'has a registration token' do
click_on 'Click to reveal'
expect(page.find('[data-testid="token-value"]')).to have_content(registration_token)
end
describe 'reset registration token' do
let!(:old_registration_token) { find('[data-testid="token-value"]').text }
before do
click_on 'Reset registration token'
within_modal do
click_button('Reset token', match: :first)
end
wait_for_requests
end
it 'changes registration token' do
expect(find('.gl-toast')).to have_content('New registration token generated!')
click_on dropdown_text
click_on 'Click to reveal'
expect(old_registration_token).not_to eq registration_token
end
end
end