summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop.yml8
-rw-r--r--.rubocop_todo/gitlab/strong_memoize_attr.yml3
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum4
-rw-r--r--Gemfile.lock9
-rw-r--r--app/assets/images/web-ide-promo-popover.svg101
-rw-r--r--app/assets/javascripts/ide/constants.js2
-rw-r--r--app/assets/javascripts/ide/init_gitlab_web_ide.js5
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue33
-rw-r--r--app/assets/javascripts/issues/list/constants.js3
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/constants.js2
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index.vue42
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions.vue35
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue1
-rw-r--r--app/assets/javascripts/pages/projects/commits/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/shared/web_ide_link/index.js2
-rw-r--r--app/assets/javascripts/performance_bar/components/detailed_metric.vue23
-rw-r--r--app/assets/javascripts/performance_bar/constants.js10
-rw-r--r--app/assets/javascripts/projects/commits/index.js31
-rw-r--r--app/assets/javascripts/vue_shared/components/web_ide_link.vue41
-rw-r--r--app/assets/stylesheets/page_bundles/tree.scss15
-rw-r--r--app/controllers/concerns/vscode_cdn_csp.rb17
-rw-r--r--app/controllers/ide_controller.rb1
-rw-r--r--app/controllers/web_ide/remote_ide_controller.rb2
-rw-r--r--app/graphql/resolvers/ci/runner_projects_resolver.rb14
-rw-r--r--app/views/admin/application_settings/_ci_cd.html.haml3
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml5
-rw-r--r--app/views/projects/commits/show.html.haml2
-rw-r--r--app/views/shared/_web_ide_button.html.haml2
-rw-r--r--config/dependency_decisions.yml2
-rw-r--r--config/feature_flags/development/ci_enforce_rate_limits_jobs_api.yml8
-rw-r--r--config/feature_flags/development/ci_register_job_temporary_lock.yml2
-rw-r--r--config/feature_flags/development/ci_reuse_build_in_seed_context.yml8
-rw-r--r--config/feature_flags/development/usage_data_diff_searches.yml7
-rw-r--r--config/initializers/countries.rb2
-rw-r--r--config/sidekiq_queues.yml4
-rw-r--r--doc/administration/incoming_email.md2
-rw-r--r--doc/administration/index.md2
-rw-r--r--doc/administration/instance_limits.md3
-rw-r--r--doc/administration/raketasks/maintenance.md2
-rw-r--r--doc/ci/environments/protected_environments.md4
-rw-r--r--doc/development/database/avoiding_downtime_in_migrations.md2
-rw-r--r--doc/development/testing_guide/best_practices.md15
-rw-r--r--doc/integration/saml.md26
-rw-r--r--doc/security/rate_limits.md13
-rw-r--r--doc/update/background_migrations.md461
-rw-r--r--doc/update/index.md248
-rw-r--r--doc/update/package/index.md2
-rw-r--r--doc/update/patch_versions.md2
-rw-r--r--doc/update/plan_your_upgrade.md4
-rw-r--r--doc/update/upgrading_from_source.md2
-rw-r--r--doc/update/zero_downtime.md4
-rw-r--r--doc/user/admin_area/monitoring/background_migrations.md247
-rw-r--r--doc/user/infrastructure/iac/terraform_template_recipes.md123
-rw-r--r--doc/user/project/description_templates.md4
-rw-r--r--doc/user/project/issues/create_issues.md221
-rw-r--r--doc/user/project/issues/index.md2
-rw-r--r--doc/user/project/issues/issue_weight.md2
-rw-r--r--doc/user/project/issues/managing_issues.md263
-rw-r--r--doc/user/project/members/share_project_with_groups.md18
-rw-r--r--doc/user/project/merge_requests/approvals/rules.md2
-rw-r--r--jest.config.base.js9
-rw-r--r--jest.config.integration.js4
-rw-r--r--lib/api/ci/jobs.rb2
-rw-r--r--lib/api/helpers.rb4
-rw-r--r--lib/api/integrations/jira_connect/subscriptions.rb2
-rw-r--r--lib/gitlab/application_rate_limiter.rb3
-rw-r--r--lib/gitlab/ci/build/context/build.rb20
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb135
-rw-r--r--lib/gitlab/ci/pipeline/seed/stage.rb55
-rw-r--r--lib/gitlab/i18n.rb16
-rw-r--r--lib/gitlab/usage_data_counters/known_events/code_review_events.yml1
-rw-r--r--lib/tasks/gitlab/feature_categories.rake80
-rw-r--r--locale/gitlab.pot26
-rw-r--r--package.json20
-rw-r--r--rubocop/cop/rspec/avoid_test_prof.rb66
-rw-r--r--scripts/review_apps/base-config.yaml36
-rw-r--r--spec/features/commits_spec.rb2
-rw-r--r--spec/features/projects/commits/user_browses_commits_spec.rb21
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/show/user_interacts_with_stars_spec.rb1
-rw-r--r--spec/features/projects/show/user_manages_notifications_spec.rb1
-rw-r--r--spec/frontend/__helpers__/graphql_transformer.js4
-rw-r--r--spec/frontend/__helpers__/raw_transformer.js2
-rw-r--r--spec/frontend/__helpers__/web_worker_transformer.js10
-rw-r--r--spec/frontend/__helpers__/yaml_transformer.js2
-rw-r--r--spec/frontend/ci/runner/components/runner_status_badge_spec.js4
-rw-r--r--spec/frontend/ci/runner/group_runners/group_runners_app_spec.js16
-rw-r--r--spec/frontend/deploy_freeze/store/actions_spec.js88
-rw-r--r--spec/frontend/environment.js11
-rw-r--r--spec/frontend/ide/init_gitlab_web_ide_spec.js7
-rw-r--r--spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index_spec.js56
-rw-r--r--spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions_spec.js35
-rw-r--r--spec/frontend/monitoring/utils_spec.js1
-rw-r--r--spec/frontend/performance_bar/components/detailed_metric_spec.js13
-rw-r--r--spec/frontend_integration/content_editor/content_editor_integration_spec.js2
-rw-r--r--spec/lib/gitlab/ci/cron_parser_spec.rb18
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build_spec.rb1619
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb2
-rw-r--r--spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb2
-rw-r--r--spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb4
-rw-r--r--spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb2
-rw-r--r--spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb8
-rw-r--r--spec/migrations/schedule_fixing_security_scan_statuses_spec.rb23
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb50
-rw-r--r--spec/requests/api/ci/jobs_spec.rb40
-rw-r--r--spec/requests/api/graphql/ci/runner_spec.rb3
-rw-r--r--spec/requests/api/integrations/jira_connect/subscriptions_spec.rb14
-rw-r--r--spec/requests/ide_controller_spec.rb39
-rw-r--r--spec/requests/web_ide/remote_ide_controller_spec.rb20
-rw-r--r--spec/rubocop/cop/rspec/avoid_test_prof_spec.rb49
-rw-r--r--spec/services/ci/pipeline_schedules/calculate_next_run_service_spec.rb107
-rw-r--r--spec/support/shared_examples/csp.rb15
-rw-r--r--spec/tasks/gitlab/feature_categories_rake_spec.rb51
-rw-r--r--yarn.lock1549
115 files changed, 3800 insertions, 2700 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index beb4b0afd87..29a0b7617e7 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -474,6 +474,14 @@ Naming/PredicateName:
Naming/RescuedExceptionsVariableName:
Enabled: false
+RSpec/AvoidTestProf:
+ Include:
+ - 'spec/migrations/**/*.rb'
+ - 'ee/spec/migrations/**/*.rb'
+ - 'spec/lib/gitlab/background_migration/**/*.rb'
+ - 'ee/spec/lib/gitlab/background_migration/**/*.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/**/*.rb'
+
RSpec/FactoriesInMigrationSpecs:
Enabled: true
Include:
diff --git a/.rubocop_todo/gitlab/strong_memoize_attr.yml b/.rubocop_todo/gitlab/strong_memoize_attr.yml
index c1ba066a181..353ab9f721f 100644
--- a/.rubocop_todo/gitlab/strong_memoize_attr.yml
+++ b/.rubocop_todo/gitlab/strong_memoize_attr.yml
@@ -592,7 +592,6 @@ Gitlab/StrongMemoizeAttr:
- 'lib/gitlab/ci/build/auto_retry.rb'
- 'lib/gitlab/ci/build/cache.rb'
- 'lib/gitlab/ci/build/context/base.rb'
- - 'lib/gitlab/ci/build/context/build.rb'
- 'lib/gitlab/ci/build/context/global.rb'
- 'lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb'
- 'lib/gitlab/ci/build/rules/rule/clause/changes.rb'
@@ -620,10 +619,8 @@ Gitlab/StrongMemoizeAttr:
- 'lib/gitlab/ci/pipeline/logger.rb'
- 'lib/gitlab/ci/pipeline/metrics.rb'
- 'lib/gitlab/ci/pipeline/quota/deployments.rb'
- - 'lib/gitlab/ci/pipeline/seed/build.rb'
- 'lib/gitlab/ci/pipeline/seed/pipeline.rb'
- 'lib/gitlab/ci/pipeline/seed/processable/resource_group.rb'
- - 'lib/gitlab/ci/pipeline/seed/stage.rb'
- 'lib/gitlab/ci/project_config/auto_devops.rb'
- 'lib/gitlab/ci/project_config/external_project.rb'
- 'lib/gitlab/ci/project_config/parameter.rb'
diff --git a/Gemfile b/Gemfile
index ee53723abcb..a3149288203 100644
--- a/Gemfile
+++ b/Gemfile
@@ -522,7 +522,7 @@ gem 'grape_logging', '~> 1.8'
gem 'gitlab-net-dns', '~> 0.9.1'
# Countries list
-gem 'countries', '~> 3.0'
+gem 'countries', '~> 4.0.0'
gem 'retriable', '~> 3.1.2'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 4d4d4a61329..252f27adcac 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -86,7 +86,7 @@
{"name":"contracts","version":"0.11.0","platform":"ruby","checksum":"df6e438efa89c31dd3095851c3f7a25dfdae36b35ff1d4547f1d92941b3c7286"},
{"name":"cork","version":"0.3.0","platform":"ruby","checksum":"a0a0ac50e262f8514d1abe0a14e95e71c98b24e3378690e5d044daf0013ad4bc"},
{"name":"cose","version":"1.0.0","platform":"ruby","checksum":"520ebaad97b56d2873de02ff4e2c973f5e77ce2f8edbda454af9ee3073643bc0"},
-{"name":"countries","version":"3.0.0","platform":"ruby","checksum":"ecb4287436f83f4bb098a9462828b145bec3143fa49e7ce5b1714d0ee5454770"},
+{"name":"countries","version":"4.0.1","platform":"ruby","checksum":"d32e8a3c0b22949f1a41ea6d9005f5168ffce226f8fe077d1d6be785fffa81c5"},
{"name":"crack","version":"0.4.3","platform":"ruby","checksum":"5318ba8cd9cf7e0b5feb38948048503ba4b1fdc1b6ff30a39f0a00feb6036b29"},
{"name":"crass","version":"1.0.6","platform":"ruby","checksum":"dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d"},
{"name":"creole","version":"0.5.0","platform":"ruby","checksum":"951701e2d80760f156b1cb2a93471ca97c076289becc067a33b745133ed32c03"},
@@ -283,7 +283,7 @@
{"name":"httparty","version":"0.20.0","platform":"ruby","checksum":"490d2a028a5accc611f1685d479d80ef80b129140d24a93c53c119f578614867"},
{"name":"httpclient","version":"2.8.3","platform":"ruby","checksum":"2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6"},
{"name":"i18n","version":"1.12.0","platform":"ruby","checksum":"91e3cc1b97616d308707eedee413d82ee021d751c918661fb82152793e64aced"},
-{"name":"i18n_data","version":"0.8.0","platform":"ruby","checksum":"92d942cc193dc4a54a95b68f44e52c79e024fa72e09f26a982bc61153b6f0c6c"},
+{"name":"i18n_data","version":"0.13.1","platform":"ruby","checksum":"e5aa99b09a69b463bb0443fc1f9540351a49f3d1541c5e91316bafa035c63f66"},
{"name":"icalendar","version":"2.8.0","platform":"ruby","checksum":"e404f970c7572bdebf6f09f9890970b68aab400ba9e609dc7d46098f28d0ee87"},
{"name":"ice_cube","version":"0.16.4","platform":"ruby","checksum":"da117e5de24bdc33931be629f9b55048641924442c7e9b72fedc05e5592531b7"},
{"name":"imagen","version":"0.1.8","platform":"ruby","checksum":"fde7b727d4fe79c6bb5ac46c1f7184bf87a6d54df54d712ad2be039d2f93a162"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 92e3527e871..f8eabba2d94 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -290,10 +290,9 @@ GEM
cose (1.0.0)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 0.4.0)
- countries (3.0.0)
- i18n_data (~> 0.8.0)
+ countries (4.0.1)
+ i18n_data (~> 0.13.0)
sixarm_ruby_unaccent (~> 1.1)
- unicode_utils (~> 1.4)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.6)
@@ -767,7 +766,7 @@ GEM
httpclient (2.8.3)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
- i18n_data (0.8.0)
+ i18n_data (0.13.1)
icalendar (2.8.0)
ice_cube (~> 0.16)
ice_cube (0.16.4)
@@ -1612,7 +1611,7 @@ DEPENDENCIES
commonmarker (~> 0.23.6)
concurrent-ruby (~> 1.1)
connection_pool (~> 2.0)
- countries (~> 3.0)
+ countries (~> 4.0.0)
creole (~> 0.5.0)
crystalball (~> 0.7.0)
cvss-suite (~> 3.0.1)
diff --git a/app/assets/images/web-ide-promo-popover.svg b/app/assets/images/web-ide-promo-popover.svg
new file mode 100644
index 00000000000..3ced89860da
--- /dev/null
+++ b/app/assets/images/web-ide-promo-popover.svg
@@ -0,0 +1,101 @@
+<svg width="280" height="140" viewBox="0 0 280 140" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_187_122567)">
+<g clip-path="url(#clip1_187_122567)">
+<circle cx="189.5" cy="-42.5" r="131.5" fill="url(#paint0_radial_187_122567)"/>
+<circle cx="-41.5" cy="-97.5" r="198.5" fill="url(#paint1_radial_187_122567)"/>
+<circle cx="309.5" cy="-7.5" r="121.5" fill="url(#paint2_radial_187_122567)"/>
+<g filter="url(#filter0_b_187_122567)">
+<path d="M0 4C0 1.79086 1.79086 0 4 0H276C278.209 0 280 1.79086 280 4V130H0V4Z" fill="white" fill-opacity="0.01"/>
+</g>
+</g>
+<path d="M183.948 47.9647H100.897V100.482H183.948V47.9647Z" fill="white"/>
+<path d="M100.64 47.9647H184.06V98.9817C184.06 104.1 179.908 108.256 174.793 108.256H100.638V47.9647H100.64Z" fill="white"/>
+<path d="M184.314 34.7452H100.64V47.9676H184.314V34.7452Z" fill="#AEA5D6"/>
+<path d="M109.594 43.2574C110.644 43.2574 111.495 42.4056 111.495 41.3549C111.495 40.3043 110.644 39.4525 109.594 39.4525C108.544 39.4525 107.693 40.3043 107.693 41.3549C107.693 42.4056 108.544 43.2574 109.594 43.2574Z" fill="#10B1B1"/>
+<path d="M116.482 43.2574C117.532 43.2574 118.383 42.4056 118.383 41.3549C118.383 40.3043 117.532 39.4525 116.482 39.4525C115.432 39.4525 114.581 40.3043 114.581 41.3549C114.581 42.4056 115.432 43.2574 116.482 43.2574Z" fill="#A888F4"/>
+<path d="M123.368 43.2574C124.418 43.2574 125.269 42.4056 125.269 41.3549C125.269 40.3043 124.418 39.4525 123.368 39.4525C122.318 39.4525 121.467 40.3043 121.467 41.3549C121.467 42.4056 122.318 43.2574 123.368 43.2574Z" fill="#FF9D73"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M100.556 34.4038H165.377V35.0858H101.238V61.7159H100.556V34.4038Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M101.238 66.3383V83.4486H100.556V66.3383H101.238Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M183.721 99.0231V89.5341H184.403V99.0231C184.403 104.311 180.118 108.599 174.834 108.599H120.244V107.917H174.834C179.741 107.917 183.721 103.935 183.721 99.0231Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M183.721 83.1296V62.2422H184.403V83.1296H183.721Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M109.596 39.7936C108.734 39.7936 108.036 40.4924 108.036 41.355C108.036 42.2176 108.734 42.9164 109.596 42.9164C110.457 42.9164 111.155 42.2176 111.155 41.355C111.155 40.4924 110.457 39.7936 109.596 39.7936ZM107.354 41.355C107.354 40.1162 108.357 39.1116 109.596 39.1116C110.834 39.1116 111.837 40.1162 111.837 41.355C111.837 42.5938 110.834 43.5985 109.596 43.5985C108.357 43.5985 107.354 42.5938 107.354 41.355Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M116.48 39.7936C115.619 39.7936 114.92 40.4924 114.92 41.355C114.92 42.2176 115.619 42.9164 116.48 42.9164C117.342 42.9164 118.04 42.2176 118.04 41.355C118.04 40.4924 117.342 39.7936 116.48 39.7936ZM114.238 41.355C114.238 40.1162 115.242 39.1116 116.48 39.1116C117.719 39.1116 118.722 40.1162 118.722 41.355C118.722 42.5938 117.719 43.5985 116.48 43.5985C115.242 43.5985 114.238 42.5938 114.238 41.355Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M123.367 39.7936C122.506 39.7936 121.808 40.4924 121.808 41.355C121.808 42.2176 122.506 42.9164 123.367 42.9164C124.229 42.9164 124.927 42.2176 124.927 41.355C124.927 40.4924 124.229 39.7936 123.367 39.7936ZM121.125 41.355C121.125 40.1162 122.129 39.1116 123.367 39.1116C124.606 39.1116 125.609 40.1162 125.609 41.355C125.609 42.5938 124.606 43.5985 123.367 43.5985C122.129 43.5985 121.125 42.5938 121.125 41.355Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M160.466 48.3058H100.897V47.6238H160.466V48.3058Z" fill="#171321"/>
+<path d="M173.511 80.7124H152.485V83.4598H173.511V80.7124Z" fill="#D0C5E2"/>
+<path d="M149.08 80.7009H111.703V83.4484H149.08V80.7009Z" fill="#E7E4F2"/>
+<path d="M111.702 68.5293H132.728V65.7819H111.702V68.5293Z" fill="#E7E4F2"/>
+<path d="M136.131 68.5336H173.508V65.7861H136.131V68.5336Z" fill="#AEA5D6"/>
+<path d="M111.703 75.9889H120.838V73.2415H111.703V75.9889Z" fill="#AEA5D6"/>
+<path d="M155.891 75.9978H173.512V73.2504H155.891V75.9978Z" fill="#E7E4F2"/>
+<path d="M124.244 75.9978H152.485V73.2504H124.244V75.9978Z" fill="#D0C5E2"/>
+<path d="M141.099 58.3217H124.332V61.0691H141.099V58.3217Z" fill="#D0C5E2"/>
+<path d="M173.512 58.3217H144.31V61.0691H173.512V58.3217Z" fill="#E7E4F2"/>
+<path d="M120.926 58.3198H111.703V61.0673H120.926V58.3198Z" fill="#AEA5D6"/>
+<path d="M144.115 90.9242H160.882V88.1768H144.115V90.9242Z" fill="#AEA5D6"/>
+<path d="M111.703 90.908H140.905V88.1605H111.703V90.908Z" fill="#D0C5E2"/>
+<path d="M164.288 90.9242H173.512V88.1768H164.288V90.9242Z" fill="#D0C5E2"/>
+<path d="M173.508 95.6178H158.224V98.3652H173.508V95.6178Z" fill="#D0C5E2"/>
+<path d="M154.82 95.6199H111.703V98.3673H154.82V95.6199Z" fill="#E7E4F2"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M167.801 34.8965L168.463 35.0598L162.398 59.6461L189.091 57.5112L189.145 58.1911L161.509 60.4014L167.801 34.8965Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M134.795 81.6335L109.428 116.595L108.876 116.195L133.312 82.5167L92.5055 87.8873L92.4165 87.2111L134.795 81.6335Z" fill="#171321"/>
+<path d="M187.019 57.9366C197.646 57.9366 206.262 49.3147 206.262 38.6791C206.262 28.0435 197.646 19.4216 187.019 19.4216C176.392 19.4216 167.777 28.0435 167.777 38.6791C167.777 49.3147 176.392 57.9366 187.019 57.9366Z" fill="white"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M187.019 19.6948C176.543 19.6948 168.05 28.1943 168.05 38.6794C168.05 49.1646 176.543 57.6641 187.019 57.6641C197.495 57.6641 205.989 49.1646 205.989 38.6794C205.989 28.1943 197.495 19.6948 187.019 19.6948ZM167.504 38.6794C167.504 27.8934 176.241 19.1492 187.019 19.1492C197.797 19.1492 206.534 27.8934 206.534 38.6794C206.534 49.4655 197.797 58.2097 187.019 58.2097C176.241 58.2097 167.504 49.4655 167.504 38.6794Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M212.255 38.6791C212.255 24.7294 200.956 13.4218 187.018 13.4218V12.677C201.368 12.677 213 24.3186 213 38.6791H212.255Z" fill="#AEA5D6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M67.0944 108.321C67.0944 122.27 78.3936 133.578 92.3316 133.578V134.323C77.9817 134.323 66.3496 122.681 66.3496 108.321H67.0944Z" fill="#AEA5D6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M181.794 28.4035C183.212 28.0221 184.673 28.8643 185.054 30.2837L184.395 30.4605C184.112 29.4049 183.026 28.7787 181.971 29.0622L181.794 28.4035Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M192.066 29.0622C191.011 28.7787 189.925 29.4049 189.642 30.4605L188.983 30.2837C189.364 28.8643 190.824 28.0221 192.243 28.4035L192.066 29.0622Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M195.892 33.5398V36.1862L192.04 37.4786L191.823 36.832L195.21 35.6956V33.5398H195.892Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M195.213 44.8355L192.045 43.7774L192.262 43.1305L195.895 44.3442V46.991H195.213V44.8355Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M178.827 35.6957V33.5398H178.145V36.1861L181.995 37.4786L182.212 36.832L178.827 35.6957Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M181.776 43.1305L181.992 43.7773L178.827 44.8354V46.991H178.145V44.3443L181.776 43.1305Z" fill="#171321"/>
+<path d="M182.675 34.3942L181.129 37.5941C179.03 41.9415 182.192 46.9908 187.019 46.9908C191.845 46.9908 195.008 41.9415 192.908 37.5941L191.363 34.3942" fill="#A888F4"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M186.678 46.9908V34.3942H187.36V46.9908H186.678Z" fill="#171321"/>
+<path d="M191.25 34.3939H182.788V33.2534C182.788 28.2918 191.25 28.2987 191.25 33.2534V34.3939Z" fill="#7759C1"/>
+<path d="M92.4612 126.064C103.088 126.064 111.704 117.442 111.704 106.806C111.704 96.1706 103.088 87.5487 92.4612 87.5487C81.8339 87.5487 73.2188 96.1706 73.2188 106.806C73.2188 117.442 81.8339 126.064 92.4612 126.064Z" fill="white"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M92.4604 87.89C82.0217 87.89 73.559 96.359 73.559 106.806C73.559 117.254 82.0217 125.723 92.4604 125.723C102.899 125.723 111.362 117.254 111.362 106.806C111.362 96.359 102.899 87.89 92.4604 87.89ZM72.877 106.806C72.877 95.9828 81.6445 87.208 92.4604 87.208C103.276 87.208 112.044 95.9828 112.044 106.806C112.044 117.63 103.276 126.405 92.4604 126.405C81.6445 126.405 72.877 117.63 72.877 106.806Z" fill="#171321"/>
+<path d="M98.2885 105.28H95.9653V101.385C95.9653 99.3302 94.2951 97.6587 92.2419 97.6587C90.1887 97.6587 88.5184 99.3302 88.5184 101.385V105.28H86.1953V101.385C86.1953 98.0489 88.9083 95.3337 92.2419 95.3337C95.5754 95.3337 98.2885 98.0489 98.2885 101.385V105.28Z" fill="#7759C1"/>
+<path d="M100.894 104.186H83.3677V116.836H100.894V104.186Z" fill="#A888F4"/>
+<path d="M92.1343 111.015C92.8235 111.015 93.3823 110.456 93.3823 109.766C93.3823 109.076 92.8235 108.517 92.1343 108.517C91.445 108.517 90.8862 109.076 90.8862 109.766C90.8862 110.456 91.445 111.015 92.1343 111.015Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M91.792 112.209V110.722H92.474V112.209H91.792Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M87.2401 53.2567V60.9103C87.2401 61.9966 88.1212 62.878 89.2061 62.878H121.061C122.523 62.878 123.709 64.0653 123.709 65.5278V67.1601H123.027V65.5278C123.027 64.4415 122.146 63.5601 121.061 63.5601H89.2061C87.7441 63.5601 86.5581 62.3728 86.5581 60.9103V53.2567H87.2401Z" fill="#171321"/>
+<path d="M123.368 67.735C123.685 67.735 123.942 67.4776 123.942 67.1601C123.942 66.8426 123.685 66.5852 123.368 66.5852C123.051 66.5852 122.793 66.8426 122.793 67.1601C122.793 67.4776 123.051 67.735 123.368 67.735Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M123.368 66.9262C123.239 66.9262 123.134 67.0306 123.134 67.16C123.134 67.2895 123.239 67.3939 123.368 67.3939C123.496 67.3939 123.601 67.2895 123.601 67.16C123.601 67.0306 123.496 66.9262 123.368 66.9262ZM122.452 67.16C122.452 66.6545 122.862 66.2441 123.368 66.2441C123.873 66.2441 124.283 66.6545 124.283 67.16C124.283 67.6656 123.873 68.0759 123.368 68.0759C122.862 68.0759 122.452 67.6656 122.452 67.16Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M167.208 82.5551V84.88C167.208 85.5854 167.778 86.1551 168.482 86.1551H193.305V86.8371H168.482C167.4 86.8371 166.526 85.9616 166.526 84.88V82.5551H167.208Z" fill="#171321"/>
+<path d="M166.867 83.13C167.184 83.13 167.441 82.8726 167.441 82.5551C167.441 82.2376 167.184 81.9802 166.867 81.9802C166.55 81.9802 166.292 82.2376 166.292 82.5551C166.292 82.8726 166.55 83.13 166.867 83.13Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M166.866 82.3209C166.737 82.3209 166.633 82.4254 166.633 82.5548C166.633 82.6842 166.737 82.7887 166.866 82.7887C166.995 82.7887 167.1 82.6842 167.1 82.5548C167.1 82.4255 166.995 82.3209 166.866 82.3209ZM165.951 82.5548C165.951 82.0492 166.36 81.6389 166.866 81.6389C167.372 81.6389 167.782 82.0492 167.782 82.5548C167.782 83.0605 167.372 83.4707 166.866 83.4707C166.36 83.4707 165.951 83.0604 165.951 82.5548Z" fill="#171321"/>
+<path d="M86.9023 37.1553C82.8536 41.5743 77.6099 40.6 77.6099 40.6V48.5768C77.6099 49.962 77.8867 51.3404 78.4796 52.5917C80.8973 57.6918 86.9023 59.5873 86.9023 59.5873C86.9023 59.5873 92.9051 57.6918 95.3251 52.5917C95.918 51.3404 96.1948 49.962 96.1948 48.5768V40.6C96.1948 40.6 90.9511 41.5743 86.9023 37.1553V37.1553Z" fill="#10B1B1"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M90.6411 45.6638L85.4674 50.8415L83.1592 48.5289L83.6419 48.0471L85.4677 49.8764L90.1586 45.1818L90.6411 45.6638Z" fill="#171321"/>
+<path d="M197.955 76.3168C193.902 80.7427 188.651 79.7684 188.651 79.7684V87.7567C188.651 89.1443 188.928 90.5249 189.521 91.7786C191.943 96.8856 197.955 98.7834 197.955 98.7834C197.955 98.7834 203.967 96.8856 206.39 91.7786C206.985 90.5249 207.259 89.1443 207.259 87.7567V79.7684C207.259 79.7684 202.009 80.7427 197.955 76.3168Z" fill="#FC6D26"/>
+<path d="M197.19 83.1044L197.566 88.4584H198.343L198.719 83.1044H197.19Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M196.806 82.7468H199.102L198.676 88.8156H197.232L196.806 82.7468ZM197.572 83.4616L197.898 88.1009H198.009L198.335 83.4616H197.572Z" fill="#171321"/>
+<path d="M198.343 90.2083H197.566V91.1248H198.343V90.2083Z" fill="#171321"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M197.208 89.851H198.7V91.4823H197.208V89.851ZM197.922 90.5657V90.7675H197.985V90.5657H197.922Z" fill="#171321"/>
+</g>
+<defs>
+<filter id="filter0_b_187_122567" x="-50" y="-50" width="380" height="230" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feGaussianBlur in="BackgroundImageFix" stdDeviation="25"/>
+<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_187_122567"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_187_122567" result="shape"/>
+</filter>
+<radialGradient id="paint0_radial_187_122567" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(189.5 -42.5) rotate(89.5818) scale(125.986)">
+<stop stop-color="#7759C2"/>
+<stop offset="1" stop-color="#7759C2" stop-opacity="0"/>
+</radialGradient>
+<radialGradient id="paint1_radial_187_122567" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(-41.5 -97.5) rotate(89.5818) scale(190.176)">
+<stop stop-color="#D64028"/>
+<stop offset="1" stop-color="#D64028" stop-opacity="0"/>
+</radialGradient>
+<radialGradient id="paint2_radial_187_122567" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(309.5 -7.5) rotate(89.5818) scale(116.405)">
+<stop stop-color="#EF76F1"/>
+<stop offset="1" stop-color="#EF76F1" stop-opacity="0"/>
+</radialGradient>
+<clipPath id="clip0_187_122567">
+<rect width="280" height="140" fill="white"/>
+</clipPath>
+<clipPath id="clip1_187_122567">
+<path d="M0 4C0 1.79086 1.79086 0 4 0H276C278.209 0 280 1.79086 280 4V140H0V4Z" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js
index bfe4c3ac271..01ce5fa07ee 100644
--- a/app/assets/javascripts/ide/constants.js
+++ b/app/assets/javascripts/ide/constants.js
@@ -118,3 +118,5 @@ export const DEFAULT_BRANCH = 'main';
// Ping Usage Metrics Keys
export const PING_USAGE_PREVIEW_KEY = 'web_ide_clientside_preview';
export const PING_USAGE_PREVIEW_SUCCESS_KEY = 'web_ide_clientside_preview_success';
+
+export const GITLAB_WEB_IDE_FEEDBACK_ISSUE = 'https://gitlab.com/gitlab-org/gitlab/-/issues/377367';
diff --git a/app/assets/javascripts/ide/init_gitlab_web_ide.js b/app/assets/javascripts/ide/init_gitlab_web_ide.js
index 5d50d2eec17..8a6965b6415 100644
--- a/app/assets/javascripts/ide/init_gitlab_web_ide.js
+++ b/app/assets/javascripts/ide/init_gitlab_web_ide.js
@@ -5,6 +5,7 @@ import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action';
import { createAndSubmitForm } from '~/lib/utils/create_and_submit_form';
import { getBaseConfig } from './lib/gitlab_web_ide/get_base_config';
import { setupRootElement } from './lib/gitlab_web_ide/setup_root_element';
+import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from './constants';
const buildRemoteIdeURL = (ideRemotePath, remoteHost, remotePathArg) => {
const remotePath = cleanLeadingSeparator(remotePathArg);
@@ -31,6 +32,10 @@ export const initGitlabWebIDE = async (el) => {
nonce,
projectPath,
ref,
+ links: {
+ feedbackIssue: GITLAB_WEB_IDE_FEEDBACK_ISSUE,
+ userPreferences: el.dataset.userPreferencesPath,
+ },
async handleStartRemote({ remoteHost, remotePath, connectionToken }) {
const confirmed = await confirmAction(
__('Are you sure you want to leave the Web IDE? All unsaved changes will be lost.'),
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
index d661ce67d88..cf672737254 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -22,8 +22,6 @@ import {
OPERATORS_IS,
OPERATORS_IS_NOT,
OPERATORS_IS_NOT_OR,
- OPTIONS_NONE_ANY,
- TOKEN_TITLE_SEARCH_WITHIN,
TOKEN_TITLE_ASSIGNEE,
TOKEN_TITLE_AUTHOR,
TOKEN_TITLE_CONFIDENTIAL,
@@ -33,6 +31,7 @@ import {
TOKEN_TITLE_MY_REACTION,
TOKEN_TITLE_ORGANIZATION,
TOKEN_TITLE_RELEASE,
+ TOKEN_TITLE_SEARCH_WITHIN,
TOKEN_TITLE_TYPE,
TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_AUTHOR,
@@ -43,8 +42,8 @@ import {
TOKEN_TYPE_MY_REACTION,
TOKEN_TYPE_ORGANIZATION,
TOKEN_TYPE_RELEASE,
- TOKEN_TYPE_TYPE,
TOKEN_TYPE_SEARCH_WITHIN,
+ TOKEN_TYPE_TYPE,
} from '~/vue_shared/components/filtered_search_bar/constants';
import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/constants';
@@ -165,7 +164,7 @@ export default {
eeIsOkrsEnabled: {
type: Boolean,
required: false,
- default: () => false,
+ default: false,
},
},
data() {
@@ -193,10 +192,7 @@ export default {
return data[this.namespace]?.issues.nodes ?? [];
},
result({ data }) {
- if (!data) {
- return;
- }
- this.pageInfo = data[this.namespace]?.issues.pageInfo ?? {};
+ this.pageInfo = data?.[this.namespace]?.issues.pageInfo ?? {};
this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
},
error(error) {
@@ -327,7 +323,6 @@ export default {
title: TOKEN_TITLE_AUTHOR,
icon: 'pencil',
token: AuthorToken,
- dataType: 'user',
defaultAuthors: [],
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
fetchAuthors: this.fetchUsers,
@@ -339,8 +334,6 @@ export default {
title: TOKEN_TITLE_ASSIGNEE,
icon: 'user',
token: AuthorToken,
- dataType: 'user',
- defaultAuthors: OPTIONS_NONE_ANY,
operators: this.hasOrFeature ? OPERATORS_IS_NOT_OR : OPERATORS_IS_NOT,
fetchAuthors: this.fetchUsers,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-assignee`,
@@ -360,7 +353,6 @@ export default {
title: TOKEN_TITLE_LABEL,
icon: 'labels',
token: LabelToken,
- defaultLabels: OPTIONS_NONE_ANY,
fetchLabels: this.fetchLabels,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-label`,
},
@@ -417,7 +409,6 @@ export default {
token: CrmContactToken,
fullPath: this.fullPath,
isProject: this.isProject,
- defaultContacts: OPTIONS_NONE_ANY,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-crm-contacts`,
operators: OPERATORS_IS,
unique: true,
@@ -432,7 +423,6 @@ export default {
token: CrmOrganizationToken,
fullPath: this.fullPath,
isProject: this.isProject,
- defaultOrganizations: OPTIONS_NONE_ANY,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-crm-organizations`,
operators: OPERATORS_IS,
unique: true,
@@ -505,18 +495,17 @@ export default {
eventHub.$off('issuables:toggleBulkEdit', this.toggleBulkEditSidebar);
},
methods: {
- fetchWithCache(path, cacheName, searchKey, search, wrapData = false) {
+ fetchWithCache(path, cacheName, searchKey, search) {
if (this.cache[cacheName]) {
const data = search
? fuzzaldrinPlus.filter(this.cache[cacheName], search, { key: searchKey })
: this.cache[cacheName].slice(0, MAX_LIST_SIZE);
- return wrapData ? Promise.resolve({ data }) : Promise.resolve(data);
+ return Promise.resolve(data);
}
return axios.get(path).then(({ data }) => {
this.cache[cacheName] = data;
- const result = data.slice(0, MAX_LIST_SIZE);
- return wrapData ? { data: result } : result;
+ return data.slice(0, MAX_LIST_SIZE);
});
},
fetchEmojis(search) {
@@ -580,8 +569,7 @@ export default {
const bulkUpdateSidebar = await import('~/issuable');
bulkUpdateSidebar.initBulkUpdateSidebar('issuable_');
- const usersSelect = await import('~/users_select');
- const UsersSelect = usersSelect.default;
+ const UsersSelect = (await import('~/users_select')).default;
new UsersSelect(); // eslint-disable-line no-new
this.hasInitBulkEdit = true;
@@ -594,8 +582,8 @@ export default {
return;
}
- this.pageParams = getInitialPageParams(this.pageSize);
this.state = state;
+ this.pageParams = getInitialPageParams(this.pageSize);
this.$router.push({ query: this.urlParams });
},
@@ -604,7 +592,6 @@ export default {
},
handleFilter(tokens) {
this.setFilterTokens(tokens);
-
this.pageParams = getInitialPageParams(this.pageSize);
this.$router.push({ query: this.urlParams });
@@ -673,8 +660,8 @@ export default {
return;
}
- this.pageParams = getInitialPageParams(this.pageSize);
this.sortKey = sortKey;
+ this.pageParams = getInitialPageParams(this.pageSize);
if (this.isSignedIn) {
this.saveSortPreference(sortKey);
diff --git a/app/assets/javascripts/issues/list/constants.js b/app/assets/javascripts/issues/list/constants.js
index 683a5955465..1e9c5810d38 100644
--- a/app/assets/javascripts/issues/list/constants.js
+++ b/app/assets/javascripts/issues/list/constants.js
@@ -200,9 +200,6 @@ export const filters = {
[OPERATOR_IS]: {
[NORMAL_FILTER]: 'in',
},
- [OPERATOR_NOT]: {
- [NORMAL_FILTER]: 'not[in]',
- },
},
},
[TOKEN_TYPE_ASSIGNEE]: {
diff --git a/app/assets/javascripts/jira_connect/subscriptions/constants.js b/app/assets/javascripts/jira_connect/subscriptions/constants.js
index fc365746b54..01bc5dfc66b 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/constants.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/constants.js
@@ -38,7 +38,7 @@ export const INTEGRATIONS_DOC_LINK = helpPagePath('integration/jira/development_
anchor: 'use-the-integration',
});
export const OAUTH_SELF_MANAGED_DOC_LINK = helpPagePath('integration/jira/connect-app', {
- anchor: 'install-the-gitlabcom-for-jira-cloud-app-for-self-managed-instances',
+ anchor: 'connect-the-gitlabcom-for-jira-cloud-app-for-self-managed-instances',
});
export const GITLAB_COM_BASE_PATH = 'https://gitlab.com';
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index.vue
index 5ff75e19425..7c6ff002014 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index.vue
@@ -5,10 +5,14 @@ import { s__ } from '~/locale';
import { reloadPage, persistBaseUrl, retrieveBaseUrl } from '~/jira_connect/subscriptions/utils';
import { updateInstallation, setApiBaseURL } from '~/jira_connect/subscriptions/api';
-import { I18N_UPDATE_INSTALLATION_ERROR_MESSAGE } from '~/jira_connect/subscriptions/constants';
+import {
+ GITLAB_COM_BASE_PATH,
+ I18N_UPDATE_INSTALLATION_ERROR_MESSAGE,
+} from '~/jira_connect/subscriptions/constants';
import { SET_ALERT } from '~/jira_connect/subscriptions/store/mutation_types';
import SignInOauthButton from '../../../components/sign_in_oauth_button.vue';
+import SetupInstructions from './setup_instructions.vue';
import VersionSelectForm from './version_select_form.vue';
export default {
@@ -16,12 +20,14 @@ export default {
components: {
GlButton,
SignInOauthButton,
+ SetupInstructions,
VersionSelectForm,
},
data() {
return {
gitlabBasePath: null,
loadingVersionSelect: false,
+ showSetupInstructions: false,
};
},
computed: {
@@ -37,6 +43,9 @@ export default {
mounted() {
this.gitlabBasePath = retrieveBaseUrl();
setApiBaseURL(this.gitlabBasePath);
+ if (this.gitlabBasePath !== GITLAB_COM_BASE_PATH) {
+ this.showSetupInstructions = true;
+ }
},
methods: {
...mapMutations({
@@ -61,6 +70,9 @@ export default {
this.loadingVersionSelect = false;
});
},
+ onSetupNext() {
+ this.showSetupInstructions = false;
+ },
onSignInError() {
this.$emit('error');
},
@@ -88,19 +100,23 @@ export default {
@submit="onVersionSelect"
/>
- <div v-else class="gl-text-center">
- <sign-in-oauth-button
- class="gl-mb-5"
- :gitlab-base-path="gitlabBasePath"
- @sign-in="$emit('sign-in-oauth', $event)"
- @error="onSignInError"
- />
+ <template v-else>
+ <setup-instructions v-if="showSetupInstructions" @next="onSetupNext" />
+
+ <div v-else class="gl-text-center">
+ <sign-in-oauth-button
+ class="gl-mb-5"
+ :gitlab-base-path="gitlabBasePath"
+ @sign-in="$emit('sign-in-oauth', $event)"
+ @error="onSignInError"
+ />
- <div>
- <gl-button category="tertiary" variant="confirm" @click="resetGitlabBasePath">
- {{ $options.i18n.changeVersionButtonText }}
- </gl-button>
+ <div>
+ <gl-button category="tertiary" variant="confirm" @click="resetGitlabBasePath">
+ {{ $options.i18n.changeVersionButtonText }}
+ </gl-button>
+ </div>
</div>
- </div>
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions.vue
new file mode 100644
index 00000000000..00fa739b518
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions.vue
@@ -0,0 +1,35 @@
+<script>
+import { GlButton, GlLink } from '@gitlab/ui';
+import { OAUTH_SELF_MANAGED_DOC_LINK } from '~/jira_connect/subscriptions/constants';
+
+export default {
+ components: {
+ GlButton,
+ GlLink,
+ },
+ OAUTH_SELF_MANAGED_DOC_LINK,
+};
+</script>
+
+<template>
+ <div class="gl-max-w-62 gl-mx-auto gl-mt-7">
+ <h3>{{ s__('JiraService|Continue setup in GitLab') }}</h3>
+ <p>
+ {{
+ s__(
+ 'JiraService|In order to complete the set up, you’ll need to complete a few steps in GitLab.',
+ )
+ }}
+ <gl-link
+ class="gl-reset-font-size!"
+ :href="$options.OAUTH_SELF_MANAGED_DOC_LINK"
+ target="_blank"
+ >{{ __('Learn more') }}</gl-link
+ >
+ </p>
+
+ <gl-button variant="confirm" @click="$emit('next')">
+ {{ __('Next') }}
+ </gl-button>
+ </div>
+</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue
index 6b32225ed11..37a65946b3f 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue
@@ -55,7 +55,6 @@ export default {
},
radioOptions: RADIO_OPTIONS,
i18n: {
- title: s__('JiraService|Welcome to GitLab for Jira'),
saasRadioLabel: __('GitLab.com (SaaS)'),
saasRadioHelp: __('Most common'),
selfManagedRadioLabel: __('GitLab (self-managed)'),
diff --git a/app/assets/javascripts/pages/projects/commits/show/index.js b/app/assets/javascripts/pages/projects/commits/show/index.js
index ee74628a994..f5ecf9be591 100644
--- a/app/assets/javascripts/pages/projects/commits/show/index.js
+++ b/app/assets/javascripts/pages/projects/commits/show/index.js
@@ -1,9 +1,10 @@
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import CommitsList from '~/commits';
import GpgBadges from '~/gpg_badges';
-import mountCommits from '~/projects/commits';
+import { mountCommits, initCommitsRefSwitcher } from '~/projects/commits';
new CommitsList(document.querySelector('.js-project-commits-show').dataset.commitsLimit); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new
GpgBadges.fetch();
mountCommits(document.getElementById('js-author-dropdown'));
+initCommitsRefSwitcher();
diff --git a/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js b/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
index 12455497e72..84ff802c268 100644
--- a/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
+++ b/app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
@@ -17,6 +17,7 @@ export default ({ el, router }) => {
const { projectPath, ref, isBlob, webIdeUrl, ...options } = convertObjectPropsToCamelCase(
JSON.parse(el.dataset.options),
);
+ const { webIdePromoPopoverImg } = el.dataset;
// eslint-disable-next-line no-new
new Vue({
@@ -27,6 +28,7 @@ export default ({ el, router }) => {
return h(WebIdeButton, {
props: {
isBlob,
+ webIdePromoPopoverImg,
webIdeUrl: isBlob
? webIdeUrl
: webIDEUrl(
diff --git a/app/assets/javascripts/performance_bar/components/detailed_metric.vue b/app/assets/javascripts/performance_bar/components/detailed_metric.vue
index 0640faae8b7..ea8005e8dfb 100644
--- a/app/assets/javascripts/performance_bar/components/detailed_metric.vue
+++ b/app/assets/javascripts/performance_bar/components/detailed_metric.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlDropdown, GlDropdownItem, GlModal, GlModalDirective } from '@gitlab/ui';
+import { GlButton, GlModal, GlModalDirective, GlCollapsibleListbox } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { sortOrders, sortOrderOptions } from '../constants';
@@ -9,9 +9,8 @@ export default {
components: {
RequestWarning,
GlButton,
- GlDropdown,
- GlDropdownItem,
GlModal,
+ GlCollapsibleListbox,
},
directives: {
'gl-modal': GlModalDirective,
@@ -119,9 +118,6 @@ export default {
itemHasOpenedBacktrace(toggledIndex) {
return this.openedBacktraces.find((openedIndex) => openedIndex === toggledIndex) >= 0;
},
- changeSortOrder(order) {
- this.sortOrder = order;
- },
sortDetailByDuration(a, b) {
return a.duration < b.duration ? 1 : -1;
},
@@ -157,19 +153,14 @@ export default {
</div>
</div>
</div>
- <gl-dropdown
+ <gl-collapsible-listbox
v-if="displaySortOrder"
- :text="$options.sortOrderOptions[sortOrder]"
+ v-model="sortOrder"
+ :toggle-text="$options.sortOrderOptions[sortOrder].text"
+ :items="Object.values($options.sortOrderOptions)"
right
data-testid="performance-bar-sort-order"
- >
- <gl-dropdown-item
- v-for="option in Object.keys($options.sortOrderOptions)"
- :key="option"
- @click="changeSortOrder(option)"
- >{{ $options.sortOrderOptions[option] }}</gl-dropdown-item
- >
- </gl-dropdown>
+ />
</div>
<hr />
<table class="table gl-table">
diff --git a/app/assets/javascripts/performance_bar/constants.js b/app/assets/javascripts/performance_bar/constants.js
index 09745797424..6f4ddd5c242 100644
--- a/app/assets/javascripts/performance_bar/constants.js
+++ b/app/assets/javascripts/performance_bar/constants.js
@@ -6,6 +6,12 @@ export const sortOrders = {
};
export const sortOrderOptions = {
- [sortOrders.DURATION]: s__('PerformanceBar|Sort by duration'),
- [sortOrders.CHRONOLOGICAL]: s__('PerformanceBar|Sort chronologically'),
+ [sortOrders.DURATION]: {
+ value: sortOrders.DURATION,
+ text: s__('PerformanceBar|Sort by duration'),
+ },
+ [sortOrders.CHRONOLOGICAL]: {
+ value: sortOrders.CHRONOLOGICAL,
+ text: s__('PerformanceBar|Sort chronologically'),
+ },
};
diff --git a/app/assets/javascripts/projects/commits/index.js b/app/assets/javascripts/projects/commits/index.js
index 03b94fde0f3..53169f689c9 100644
--- a/app/assets/javascripts/projects/commits/index.js
+++ b/app/assets/javascripts/projects/commits/index.js
@@ -1,11 +1,13 @@
import Vue from 'vue';
import Vuex from 'vuex';
+import { visitUrl } from '~/lib/utils/url_utility';
+import RefSelector from '~/ref/components/ref_selector.vue';
import AuthorSelectApp from './components/author_select.vue';
import store from './store';
Vue.use(Vuex);
-export default (el) => {
+export const mountCommits = (el) => {
if (!el) {
return null;
}
@@ -24,3 +26,30 @@ export default (el) => {
},
});
};
+
+export const initCommitsRefSwitcher = () => {
+ const el = document.getElementById('js-project-commits-ref-switcher');
+ const COMMITS_PATH_REGEX = /^(.*?)\/-\/commits/g;
+
+ if (!el) return false;
+
+ const { projectId, ref, commitsPath } = el.dataset;
+ const commitsPathPrefix = commitsPath.match(COMMITS_PATH_REGEX)?.[0];
+
+ return new Vue({
+ el,
+ render(createElement) {
+ return createElement(RefSelector, {
+ props: {
+ projectId,
+ value: ref,
+ },
+ on: {
+ input(selected) {
+ visitUrl(`${commitsPathPrefix}/${selected}`);
+ },
+ },
+ });
+ },
+ });
+};
diff --git a/app/assets/javascripts/vue_shared/components/web_ide_link.vue b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
index 3934efbc811..74f14dbd5c9 100644
--- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue
+++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
@@ -139,6 +139,11 @@ export default {
required: false,
default: '',
},
+ webIdePromoPopoverImg: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -379,19 +384,37 @@ export default {
v-if="displayVscodeWebIdeCallout"
:target="$options.webIdeButtonId"
:show="shouldShowCallout"
+ :css-classes="['web-ide-promo-popover']"
show-close-button
triggers="manual"
@close-button-clicked="dismiss"
>
- <template #title>
- {{ __('Try out the new Web IDE') }}
- </template>
-
- {{
- __(
- 'VS Code in your browser. View code and make changes from the same UI as in your local IDE 🎉',
- )
- }}
+ <img
+ :src="webIdePromoPopoverImg"
+ class="web-ide-promo-popover-illustration"
+ width="280"
+ height="140"
+ />
+ <div class="gl-mx-2">
+ <h5 class="gl-mt-3 gl-mb-3">{{ __('The new Web IDE') }}</h5>
+ <p>
+ {{
+ __(
+ 'VS Code in your browser. View code and make changes from the same UI as in your local IDE.',
+ )
+ }}
+ </p>
+ <gl-link
+ class="gl-button btn btn-confirm block gl-mb-4 gl-mt-5"
+ variant="confirm"
+ category="primary"
+ target="_blank"
+ :href="webIdeUrl"
+ block
+ >
+ {{ __('Try it out now') }}
+ </gl-link>
+ </div>
</gl-popover>
</div>
</template>
diff --git a/app/assets/stylesheets/page_bundles/tree.scss b/app/assets/stylesheets/page_bundles/tree.scss
index 58e55e11f7e..50d9684c7d2 100644
--- a/app/assets/stylesheets/page_bundles/tree.scss
+++ b/app/assets/stylesheets/page_bundles/tree.scss
@@ -205,3 +205,18 @@
.blob-content-holder {
margin-top: $gl-padding;
}
+
+
+.web-ide-promo-popover {
+ box-shadow: 0 0 18px -1.9px rgba(119, 89, 194, 0.16),
+ 0 0 12.9px -1.7px rgba(119, 89, 194, 0.16), 0 0 9.2px -1.4px rgba(119, 89, 194, 0.16),
+ 0 0 6.4px -1.1px rgba(119, 89, 194, 0.16), 0 0 4.5px -0.8px rgba(119, 89, 194, 0.16),
+ 0 0 3px -0.6px rgba(119, 89, 194, 0.16), 0 0 1.8px -0.3px rgba(119, 89, 194, 0.16),
+ 0 0 0.6px rgba(119, 89, 194, 0.16);
+ z-index: 999;
+}
+
+.web-ide-promo-popover-illustration {
+ width: calc(100% + 24px);
+ margin: -28px -12px 0;
+}
diff --git a/app/controllers/concerns/vscode_cdn_csp.rb b/app/controllers/concerns/vscode_cdn_csp.rb
new file mode 100644
index 00000000000..8446d237f16
--- /dev/null
+++ b/app/controllers/concerns/vscode_cdn_csp.rb
@@ -0,0 +1,17 @@
+# rubocop:disable Naming/FileName
+# frozen_string_literal: true
+
+module VSCodeCDNCSP
+ extend ActiveSupport::Concern
+
+ included do
+ content_security_policy do |policy|
+ next if !Feature.enabled?(:vscode_web_ide) || policy.directives.blank?
+
+ default_src = Array(policy.directives['default-src'] || [])
+ policy.directives['frame-src'] ||= default_src
+ policy.directives['frame-src'].concat(['https://*.vscode-cdn.net/'])
+ end
+ end
+end
+# rubocop:enable Naming/FileName
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index fcf6871d137..8a8c41e65b9 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class IdeController < ApplicationController
+ include VSCodeCDNCSP
include ClientsidePreviewCSP
include StaticObjectExternalStorageCSP
include Gitlab::Utils::StrongMemoize
diff --git a/app/controllers/web_ide/remote_ide_controller.rb b/app/controllers/web_ide/remote_ide_controller.rb
index fd867f4cd9b..fe70e78b1e5 100644
--- a/app/controllers/web_ide/remote_ide_controller.rb
+++ b/app/controllers/web_ide/remote_ide_controller.rb
@@ -4,6 +4,8 @@ require 'uri'
module WebIde
class RemoteIdeController < ApplicationController
+ include VSCodeCDNCSP
+
rescue_from URI::InvalidComponentError, with: :render_404
before_action :allow_remote_ide_content_security_policy
diff --git a/app/graphql/resolvers/ci/runner_projects_resolver.rb b/app/graphql/resolvers/ci/runner_projects_resolver.rb
index af9a67acfda..2a2d63f85de 100644
--- a/app/graphql/resolvers/ci/runner_projects_resolver.rb
+++ b/app/graphql/resolvers/ci/runner_projects_resolver.rb
@@ -40,6 +40,7 @@ module Resolvers
params: project_finder_params(args),
project_ids_relation: project_ids)
.execute
+ projects = apply_lookahead(projects)
Preloaders::ProjectPolicyPreloader.new(projects, current_user).execute
projects_by_id = projects.index_by(&:id)
@@ -58,6 +59,19 @@ module Resolvers
end
# rubocop:enable CodeReuse/ActiveRecord
end
+
+ private
+
+ def unconditional_includes
+ [:project_feature]
+ end
+
+ def preloads
+ super.merge({
+ full_path: [:route, { namespace: [:route] }],
+ web_url: [:route, { namespace: [:route] }]
+ })
+ end
end
end
end
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml
index 9cfc3100078..8f8f0a581f6 100644
--- a/app/views/admin/application_settings/_ci_cd.html.haml
+++ b/app/views/admin/application_settings/_ci_cd.html.haml
@@ -61,7 +61,7 @@
%h4
= s_('AdminSettings|CI/CD limits')
%p
- = s_('AdminSettings|Set limit to 0 to disable it.')
+ = s_('AdminSettings|By default, set a limit to 0 to have no limit.')
.scrolling-tabs-container.inner-page-scroll-tabs
- if @plans.size > 1
%ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs.gl-mb-5
@@ -94,6 +94,7 @@
.form-group
= f.label :ci_needs_size_limit, s_('AdminSettings|Maximum number of DAG dependencies that a job can have')
= f.number_field :ci_needs_size_limit, class: 'form-control gl-form-input'
+ .form-text.text-muted= s_('AdminSettings|This limit cannot be disabled. Set to 0 to block all DAG dependencies.')
.form-group
= f.label :ci_registered_group_runners, s_('AdminSettings|Maximum number of runners registered per group')
= f.number_field :ci_registered_group_runners, class: 'form-control gl-form-input'
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index 8f4cc41822b..cdf25a9348c 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -17,8 +17,7 @@
= clipboard_button(target: '#registration_token', title: _("Copy token"))
.gl-mt-3.gl-mb-3
-= button_to _("Reset registration token"), reset_token_url,
-method: :put, class: 'gl-button btn btn-default',
-data: { confirm: _("Are you sure you want to reset the registration token?") }
+= render Pajamas::ButtonComponent.new(variant: :default, method: :put, href: reset_token_url, button_options: { id: 'Reset registration token', data: { confirm: _("Are you sure you want to reset the registration token?") } }) do
+ = _('Reset registration token')
#js-install-runner
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 765b4e7b615..c129d978e7e 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -10,7 +10,7 @@
.nav-block
.tree-ref-container
.tree-ref-holder
- = render 'shared/ref_switcher', destination: 'commits'
+ #js-project-commits-ref-switcher{ data: { "project-id" => @project.id, "ref" => @ref, "commits_path": project_commits_path(@project) } }
%ul.breadcrumb.repo-breadcrumb
= commits_breadcrumbs
diff --git a/app/views/shared/_web_ide_button.html.haml b/app/views/shared/_web_ide_button.html.haml
index 83646a3c92e..aeaccdfa54b 100644
--- a/app/views/shared/_web_ide_button.html.haml
+++ b/app/views/shared/_web_ide_button.html.haml
@@ -2,4 +2,4 @@
- button_data = web_ide_button_data({ blob: blob })
- fork_options = fork_modal_options(@project, @ref, @path, blob)
-.gl-display-inline-block{ data: { options: button_data.merge(fork_options).to_json }, id: "js-#{type}-web-ide-link" }
+.gl-display-inline-block{ data: { options: button_data.merge(fork_options).to_json, web_ide_promo_popover_img: image_path('web-ide-promo-popover.svg') }, id: "js-#{type}-web-ide-link" }
diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml
index e68de8b11f3..d2d8d90c560 100644
--- a/config/dependency_decisions.yml
+++ b/config/dependency_decisions.yml
@@ -245,7 +245,7 @@
- unicode_utils
- MIT
- :who: Aishwarya Subramanain
- :why: https://github.com/hexorx/countries/blob/master/LICENSE
+ :why: https://github.com/countries/countries/blob/master/LICENSE
:versions: []
:when: 2019-09-11 13:08:28.431132000 Z
- - :permit
diff --git a/config/feature_flags/development/ci_enforce_rate_limits_jobs_api.yml b/config/feature_flags/development/ci_enforce_rate_limits_jobs_api.yml
new file mode 100644
index 00000000000..14c435f294a
--- /dev/null
+++ b/config/feature_flags/development/ci_enforce_rate_limits_jobs_api.yml
@@ -0,0 +1,8 @@
+---
+name: ci_enforce_rate_limits_jobs_api
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104912
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/384186
+milestone: '15.7'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/ci_register_job_temporary_lock.yml b/config/feature_flags/development/ci_register_job_temporary_lock.yml
index f404df8f85b..d839669b2ea 100644
--- a/config/feature_flags/development/ci_register_job_temporary_lock.yml
+++ b/config/feature_flags/development/ci_register_job_temporary_lock.yml
@@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55202
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/323180
milestone: '13.10'
type: development
-group: group::memory
+group: group::pipeline excution
default_enabled: false
diff --git a/config/feature_flags/development/ci_reuse_build_in_seed_context.yml b/config/feature_flags/development/ci_reuse_build_in_seed_context.yml
new file mode 100644
index 00000000000..aa63b8d898f
--- /dev/null
+++ b/config/feature_flags/development/ci_reuse_build_in_seed_context.yml
@@ -0,0 +1,8 @@
+---
+name: ci_reuse_build_in_seed_context
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105492
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/384577
+milestone: '15.7'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/usage_data_diff_searches.yml b/config/feature_flags/development/usage_data_diff_searches.yml
deleted file mode 100644
index 70c053b7a17..00000000000
--- a/config/feature_flags/development/usage_data_diff_searches.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: usage_data_diff_searches
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86603
-rollout_issue_url:
-milestone: '15.0'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/config/initializers/countries.rb b/config/initializers/countries.rb
index 52537b5d885..171c126143c 100644
--- a/config/initializers/countries.rb
+++ b/config/initializers/countries.rb
@@ -8,7 +8,7 @@ end
# This overrides the display name for Ukraine to 'Ukraine (except the Crimea, Donetsk, and Luhansk regions)'
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/374946
# To be removed after https://gitlab.com/gitlab-org/gitlab/issues/14784 is implemented
-# Data fetched is based on https://github.com/hexorx/countries/blob/master/lib/countries/data/countries/UA.yaml
+# Data fetched is based on https://github.com/countries/countries/blob/master/lib/countries/data/countries/UA.yaml
ISO3166::Data.register(
continent: "Europe",
address_format: "|-
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 650f73c5c13..e60ffef86dd 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -131,6 +131,10 @@
- 1
- - delete_user
- 1
+- - dependencies_destroy_export
+ - 1
+- - dependencies_export
+ - 1
- - dependency_proxy
- 1
- - dependency_proxy_blob
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index 433956bb066..826340ad967 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -10,7 +10,7 @@ GitLab has several features based on receiving incoming email messages:
- [Reply by Email](reply_by_email.md): allow GitLab users to comment on issues
and merge requests by replying to notification email.
-- [New issue by email](../user/project/issues/managing_issues.md#by-sending-an-email):
+- [New issue by email](../user/project/issues/create_issues.md#by-sending-an-email):
allow GitLab users to create a new issue by sending an email to a
user-specific email address.
- [New merge request by email](../user/project/merge_requests/creating_merge_requests.md#by-sending-an-email):
diff --git a/doc/administration/index.md b/doc/administration/index.md
index 9c1a95e9419..1059424da27 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -134,7 +134,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- Instances.
- [Auditor users](auditor_users.md): Users with read-only access to all projects, groups, and other resources on the GitLab instance.
- [Incoming email](incoming_email.md): Configure incoming emails to allow
- users to [reply by email](reply_by_email.md), create [issues by email](../user/project/issues/managing_issues.md#by-sending-an-email) and
+ users to [reply by email](reply_by_email.md), create [issues by email](../user/project/issues/create_issues.md#by-sending-an-email) and
[merge requests by email](../user/project/merge_requests/creating_merge_requests.md#by-sending-an-email), and to enable [Service Desk](../user/project/service_desk.md).
- [Postfix for incoming email](reply_by_email_postfix_setup.md): Set up a
basic Postfix mail server with IMAP authentication on Ubuntu for incoming
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
index 129daa95301..b06e16b0cc3 100644
--- a/doc/administration/instance_limits.md
+++ b/doc/administration/instance_limits.md
@@ -581,7 +581,8 @@ limit value. For example, for a maximum frequency of:
- Once per 10 minutes, the limit must be `144`.
- Once per 60 minutes, the limit must be `24`
-There is no limit for self-managed instances by default.
+The minimum value is `24`, or one pipeline per 60 minutes.
+There is no maximum value.
To set this limit to `1440` on a self-managed installation, run the following in the
[GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index 293efb1b7ae..ba095b33bf5 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -301,7 +301,7 @@ sudo gitlab-rake gitlab:exclusive_lease:clear[project_housekeeping:4]
## Display status of database migrations
-See the [upgrade documentation](../../update/index.md#checking-for-background-migrations-before-upgrading)
+See the [background migrations documentation](../../update/background_migrations.md)
for how to check that migrations are complete when upgrading GitLab.
To check the status of specific migrations, you can use the following Rake task:
diff --git a/doc/ci/environments/protected_environments.md b/doc/ci/environments/protected_environments.md
index 356ebcc9125..638bcf77967 100644
--- a/doc/ci/environments/protected_environments.md
+++ b/doc/ci/environments/protected_environments.md
@@ -132,13 +132,13 @@ they have the following privileges:
Users granted access to a protected environment, but not push or merge access
to the branch deployed to it, are only granted access to deploy the environment.
-[Invited groups](../../user/project/members/share_project_with_groups.md#share-a-project-with-a-group-of-users) added
+[Invited groups](../../user/project/members/share_project_with_groups.md#share-a-project-with-a-group) added
to the project with [Reporter role](../../user/permissions.md#project-members-permissions), appear in the dropdown list for deployment-only access.
To add deployment-only access:
1. Create a group with members who are granted to access to the protected environment, if it doesn't exist yet.
-1. [Invite the group](../../user/project/members/share_project_with_groups.md#share-a-project-with-a-group-of-users) to the project with the Reporter role.
+1. [Invite the group](../../user/project/members/share_project_with_groups.md#share-a-project-with-a-group) to the project with the Reporter role.
1. Follow the steps in [Protecting Environments](#protecting-environments).
## Modifying and unprotecting environments
diff --git a/doc/development/database/avoiding_downtime_in_migrations.md b/doc/development/database/avoiding_downtime_in_migrations.md
index d43b5d7db3d..b34c0bbf728 100644
--- a/doc/development/database/avoiding_downtime_in_migrations.md
+++ b/doc/development/database/avoiding_downtime_in_migrations.md
@@ -423,7 +423,7 @@ Check how the migration is performing while it's running. Multiple ways to do th
#### High-level status of batched background migrations
-See how to [check the status of batched background migrations](../../update/index.md#checking-for-background-migrations-before-upgrading).
+See how to [check the status of batched background migrations](../../update/background_migrations.md).
#### Query the database
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 15307dfe06c..8b67be558a1 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -924,6 +924,21 @@ sequence-generated column. To avoid accidental conflicts, specs should also
avoid manually specifying any values in these kinds of columns. Instead, leave
them unspecified, and look up the value after the row is created.
+##### TestProf in migration specs
+
+Because of what is described above, migration specs can't be run inside
+a database transaction. Our test suite uses
+[TestProf](https://github.com/test-prof/test-prof) to improve the runtime of the
+test suite, but `TestProf` uses database transactions to perform these optimizations.
+For this reason, we can't use `TestProf` methods in our migration specs.
+These are the methods that should not be used and should be replaced with
+default RSpec methods instead:
+
+- `let_it_be`: use `let` or `let!` instead.
+- `let_it_be_with_reload`: use `let` or `let!` instead.
+- `let_it_be_with_refind`: use `let` or `let!` instead.
+- `before_all`: use `before` or `before(:all)` instead.
+
#### Redis
GitLab stores two main categories of data in Redis: cached items, and Sidekiq
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index a8b5e9daa14..d0a69028030 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -150,23 +150,23 @@ For more information on:
### Register GitLab in your SAML IdP
-1. Register the GitLab SP in your SAML 2.0 IdP, using the application name specified
- in `issuer`.
+1. Register the GitLab SP in your SAML IdP, using the application name specified in `issuer`.
-To ease configuration, most IdP accept a metadata URL for the application to provide
-configuration information to the IdP. To build the metadata URL for GitLab, append
-`users/auth/saml/metadata` to the HTTPS URL of your GitLab installation, for instance:
+1. To provide configuration information to the IdP, build a metadata URL for the
+ application. To build the metadata URL for GitLab, append `users/auth/saml/metadata`
+ to the HTTPS URL of your GitLab installation. For example:
-```plaintext
-https://gitlab.example.com/users/auth/saml/metadata
-```
+ ```plaintext
+ https://gitlab.example.com/users/auth/saml/metadata
+ ```
-At a minimum the IdP *must* provide a claim containing the user's email address using `email` or `mail`.
-See [configuring assertions](#configure-assertions) for other available claims.
+ At a minimum the IdP **must** provide a claim containing the user's email address
+ using `email` or `mail`. For more information on other available claims, see
+ [configuring assertions](#configure-assertions).
-On the sign in page there should now be a SAML button below the regular sign in form.
-Select the icon to begin the authentication process. If everything goes well the user
-is returned to GitLab and signed in.
+1. On the sign in page there should now be a SAML icon below the regular sign in form.
+ Select the icon to begin the authentication process. If authentication is successful,
+ you are returned to GitLab and signed in.
### Configure SAML on your IdP
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
index 20a81ed0c30..929609cd4a4 100644
--- a/doc/security/rate_limits.md
+++ b/doc/security/rate_limits.md
@@ -141,6 +141,19 @@ This is to mitigate the risk of misuses, such as mass discovery of usernames in
The **rate limit** is 20 calls per minute per IP address.
+### Project Jobs API endpoint
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104912) in GitLab 15.7 [with a flag](../administration/feature_flags.md) named `ci_enforce_rate_limits_jobs_api`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `ci_enforce_rate_limits_jobs_api`.
+The feature is not ready for production use.
+
+There is a rate limit for the endpoint `project/:id/jobs`, which is enforced to reduce timeouts when retrieving jobs.
+
+The **rate limit** is 600 calls per minute per signed-in user.
+
## Troubleshooting
### Rack Attack is denylisting the load balancer
diff --git a/doc/update/background_migrations.md b/doc/update/background_migrations.md
new file mode 100644
index 00000000000..2e0bd1bb348
--- /dev/null
+++ b/doc/update/background_migrations.md
@@ -0,0 +1,461 @@
+---
+stage: Data Stores
+group: Database
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Check for background migrations before upgrading
+
+Certain releases may require different migrations to be
+finished before you update to the newer version.
+
+There are two kinds of migrations:
+
+- [Background migrations](#background-migrations)
+- [Batched background migrations](#batched-background-migrations) (available in GitLab 14.0 and later)
+
+Background migrations and batched migrations are not the same, so you should check that both are
+complete before updating.
+
+Decrease the time required to complete these migrations by increasing the number of
+[Sidekiq workers](../administration/sidekiq/extra_sidekiq_processes.md)
+that can process jobs in the `background_migration` queue.
+
+## Background migrations
+
+### Pending migrations
+
+**For Omnibus installations:**
+
+```shell
+sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
+sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'
+```
+
+**For installations from source:**
+
+```shell
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'
+```
+
+### Failed migrations
+
+**For Omnibus installations:**
+
+For GitLab 14.0-14.9:
+
+```shell
+sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count'
+```
+
+For GitLab 14.10 and later:
+
+```shell
+sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count'
+```
+
+**For installations from source:**
+
+For GitLab 14.0-14.9:
+
+```shell
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count'
+```
+
+For GitLab 14.10 and later:
+
+```shell
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count'
+```
+
+## Batched background migrations **(FREE SELF)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51332) in GitLab 13.11, [behind a feature flag](../user/feature_flags.md), disabled by default.
+> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/329511) in GitLab 13.12.
+> - Enabled on GitLab.com.
+> - Recommended for production use.
+> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-batched-background-migrations).
+
+There can be [risks when disabling released features](../administration/feature_flags.md#risks-when-disabling-released-features).
+Refer to this feature's version history for more details.
+
+To update database tables in batches, GitLab can use batched background migrations. These migrations
+are created by GitLab developers and run automatically on upgrade. However, such migrations are
+limited in scope to help with migrating some `integer` database columns to `bigint`. This is needed to
+prevent integer overflow for some tables.
+
+Some installations [may need to run GitLab 14.0 for at least a day](index.md#1400) to complete the database changes introduced by that upgrade.
+
+Batched background migrations are handled by Sidekiq and [run in isolation](../development/database/batched_background_migrations.md#isolation), so an instance can remain operational while the migrations are processed. However, there may be performance degradation on larger instances that are heavily used while batched background migrations are run, so it's a good idea to [actively monitor the Sidekiq status](../user/admin_area/index.md#background-jobs) until all migrations are completed.
+
+### Check the status of batched background migrations
+
+To check the status of batched background migrations:
+
+1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, select **Monitoring > Background Migrations**.
+
+ ![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png)
+
+All migrations must have a `Finished` status before you upgrade GitLab.
+
+The status of batched background migrations can also be queried directly in the database.
+
+1. Log into a `psql` prompt according to the directions for your instance's installation method
+(for example, `sudo gitlab-psql` for Omnibus installations).
+1. Run the following query in the `psql` session to see details on incomplete batched background migrations:
+
+ ```sql
+ select job_class_name, table_name, column_name, job_arguments from batched_background_migrations where status <> 3;
+ ```
+
+If the migrations are not finished and you try to update to a later version,
+GitLab prompts you with an error:
+
+```plaintext
+Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
+```
+
+If you get this error, [check the batched background migration options](#database-migrations-failing-because-of-batched-background-migration-not-finished) to complete the upgrade.
+
+### Enable or disable batched background migrations
+
+WARNING:
+If you disable this feature flag, GitLab upgrades may fail.
+
+Batched background migrations are under development but ready for production use.
+It is deployed behind a feature flag that is **enabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
+can opt to disable it.
+
+To enable it:
+
+```ruby
+Feature.enable(:execute_batched_migrations_on_schedule)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:execute_batched_migrations_on_schedule)
+```
+
+### Pause batched background migrations in GitLab 14.x
+
+To pause an ongoing batched background migration, use the `disable` command above.
+This command causes the migration to complete the current batch, and then wait to start the next batch.
+
+Use the following database queries to see the state of the current batched background migration:
+
+1. Obtain the ID of the running migration:
+
+ ```sql
+ SELECT
+ id,
+ job_class_name,
+ table_name,
+ column_name,
+ job_arguments
+ FROM batched_background_migrations
+ WHERE status <> 3;
+ ```
+
+1. Run this query, replacing `XX` with the ID you obtained in the previous step,
+ to see the status of the migration:
+
+ ```sql
+ SELECT
+ started_at,
+ finished_at,
+ finished_at - started_at AS duration,
+ min_value,
+ max_value,
+ batch_size,
+ sub_batch_size
+ FROM batched_background_migration_jobs
+ WHERE batched_background_migration_id = XX
+ ORDER BY id DESC
+ limit 10;
+ ```
+
+1. Run the query multiple times within a few minutes to ensure no new row has been added.
+ If no new row has been added, the migration has been paused.
+
+1. After confirming the migration has paused, restart the migration (using the `enable`
+ command above) to proceed with the batch when ready. On larger instances,
+ background migrations can take as long as 48 hours to complete each batch.
+
+### Automatic batch size optimization
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60133)
+> in GitLab 13.12, [behind a feature flag](../user/feature_flags.md),
+> [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/329511).
+> - Enabled on GitLab.com.
+> - Recommended for production use.
+> - For GitLab self-managed instances, GitLab administrators can opt to
+> [disable it](#enable-or-disable-automatic-batch-size-optimization).
+
+There can be [risks when disabling released features](../administration/feature_flags.md#risks-when-disabling-released-features).
+Refer to this feature's version history for more details.
+
+To maximize throughput of batched background migrations (in terms of the number of tuples updated per time unit), batch sizes are automatically adjusted based on how long the previous batches took to complete.
+
+### Enable or disable automatic batch size optimization
+
+Automatic batch size optimization for batched background migrations is under development but ready for production use.
+It is deployed behind a feature flag that is **enabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
+can opt to disable it.
+
+To enable it:
+
+```ruby
+Feature.enable(:optimize_batched_migrations)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:optimize_batched_migrations)
+```
+
+## Troubleshooting
+
+### Database migrations failing because of batched background migration not finished
+
+When updating to GitLab 14.2 or later there might be a database migration failing with a message like:
+
+```plaintext
+StandardError: An error has occurred, all later migrations canceled:
+
+Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
+ {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", :table_name=>"push_event_payloads", :column_name=>"event_id", :job_arguments=>[["event_id"], ["event_id_convert_to_bigint"]]}
+```
+
+First, check if you have followed the [version-specific upgrade instructions for 14.2](../update/index.md#1420).
+If you have, you can [manually finish the batched background migration](#manually-finishing-a-batched-background-migration).
+If you haven't, choose one of the following methods:
+
+1. [Rollback and upgrade](#roll-back-and-follow-the-required-upgrade-path) through one of the required
+versions before updating to 14.2+.
+1. [Roll forward](#roll-forward-and-finish-the-migrations-on-the-upgraded-version), staying on the current
+version and manually ensuring that the batched migrations complete successfully.
+
+#### Roll back and follow the required upgrade path
+
+1. [Rollback and restore the previously installed version](../raketasks/backup_restore.md)
+1. Update to either 14.0.5 or 14.1 **before** updating to 14.2+
+1. [Check the status](#check-the-status-of-batched-background-migrations) of the batched background migrations and
+make sure they are all marked as finished before attempting to upgrade again. If any remain marked as active,
+you can [manually finish them](#manually-finishing-a-batched-background-migration).
+
+#### Roll forward and finish the migrations on the upgraded version
+
+##### For a deployment with downtime
+
+To run all the batched background migrations, it can take a significant amount of time
+depending on the size of your GitLab installation.
+
+1. [Check the status](#check-the-status-of-batched-background-migrations) of the batched background migrations in the
+database, and [manually run them](#manually-finishing-a-batched-background-migration) with the appropriate
+arguments until the status query returns no rows.
+1. When the status of all of all them is marked as complete, re-run migrations for your installation.
+1. [Complete the database migrations](../administration/raketasks/maintenance.md#run-incomplete-database-migrations) from your GitLab upgrade:
+
+ ```plaintext
+ sudo gitlab-rake db:migrate
+ ```
+
+1. Run a reconfigure:
+
+ ```plaintext
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Finish the upgrade for your installation.
+
+##### For a no-downtime deployment
+
+As the failing migrations are post-deployment migrations, you can remain on a running instance of the upgraded
+version and wait for the batched background migrations to finish normally.
+
+1. [Check the status](#check-the-status-of-batched-background-migrations) of the batched background migration from
+the error message, and make sure it is listed as finished. If it is still active, either wait until it is done,
+or [manually finish it](#manually-finishing-a-batched-background-migration).
+1. Re-run migrations for your installation, so the remaining post-deployment migrations finish.
+
+### Manually finishing a batched background migration
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62634) in GitLab 14.1
+
+If you need to manually finish a batched background migration due to an
+error, you can run:
+
+```shell
+sudo gitlab-rake gitlab:background_migrations:finalize[<job_class_name>,<table_name>,<column_name>,'<job_arguments>']
+```
+
+Replace the values in angle brackets with the correct
+arguments. For example, if you receive an error similar to this:
+
+```plaintext
+StandardError: An error has occurred, all later migrations canceled:
+
+Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
+ {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", :table_name=>"push_event_payloads", :column_name=>"event_id", :job_arguments=>[["event_id"], ["event_id_convert_to_bigint"]]}
+```
+
+Plug the arguments from the error message into the command:
+
+```shell
+sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,push_event_payloads,event_id,'[["event_id"]\, ["event_id_convert_to_bigint"]]']
+```
+
+If you need to manually run a batched background migration to continue an upgrade, you can
+[check the status](#check-the-status-of-batched-background-migrations) in the database and get the
+arguments from the query results. For example, if the query returns this:
+
+```plaintext
+ job_class_name | table_name | column_name | job_arguments
+---------------------------------------+------------+-------------+------------------------------------
+ CopyColumnUsingBackgroundMigrationJob | events | id | [["id"], ["id_convert_to_bigint"]]
+ ```
+
+The results from the query can be plugged into the command:
+
+```shell
+sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[["id"]\, ["id_convert_to_bigint"]]']
+```
+
+### The `BackfillNamespaceIdForNamespaceRoute` batched migration job fails
+
+In GitLab 14.8, the `BackfillNamespaceIdForNamespaceRoute` batched background migration job
+may fail to complete. When retried, a `500 Server Error` is returned. This issue was
+[resolved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82387) in GitLab 14.9.
+
+To resolve this issue, [upgrade GitLab](../update/index.md) from 14.8 to 14.9.
+You can ignore the failed batch migration until after you update to GitLab 14.9.
+
+### Background migrations remain in the Sidekiq queue
+
+WARNING:
+The following operations can disrupt your GitLab performance. They run a number of Sidekiq jobs that perform various database or file updates.
+
+Run the following check. If it returns non-zero and the count does not decrease over time, follow the rest of the steps in this section.
+
+```shell
+# For Omnibus installations:
+sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
+
+# For installations from source:
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
+```
+
+It is safe to re-execute the following commands, especially if you have 1000+ pending jobs which would likely overflow your runtime memory.
+
+**For Omnibus installations**
+
+```shell
+# Start the rails console
+sudo gitlab-rails c
+
+# Execute the following in the rails console
+scheduled_queue = Sidekiq::ScheduledSet.new
+pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
+pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }
+```
+
+**For installations from source**
+
+```shell
+# Start the rails console
+sudo -u git -H bundle exec rails RAILS_ENV=production
+
+# Execute the following in the rails console
+scheduled_queue = Sidekiq::ScheduledSet.new
+pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
+pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }
+```
+
+### Background migrations stuck in 'pending' state
+
+WARNING:
+The following operations can disrupt your GitLab performance. They run a number
+of Sidekiq jobs that perform various database or file updates.
+
+- GitLab 13.6 introduced an issue where a background migration named
+ `BackfillJiraTrackerDeploymentType2` can be permanently stuck in a
+ **pending** state across upgrades. To clean up this stuck migration, see the
+ [13.6.0 version-specific instructions](index.md#1360).
+- GitLab 14.2 introduced an issue where a background migration named
+ `BackfillDraftStatusOnMergeRequests` can be permanently stuck in a
+ **pending** state across upgrades when the instance lacks records that match
+ the migration's target. To clean up this stuck migration, see the
+ [14.2.0 version-specific instructions](index.md#1420).
+- GitLab 14.4 introduced an issue where a background migration named
+ `PopulateTopicsTotalProjectsCountCache` can be permanently stuck in a
+ **pending** state across upgrades when the instance lacks records that match
+ the migration's target. To clean up this stuck migration, see the
+ [14.4.0 version-specific instructions](index.md#1440).
+- GitLab 14.5 introduced an issue where a background migration named
+ `UpdateVulnerabilityOccurrencesLocation` can be permanently stuck in a
+ **pending** state across upgrades when the instance lacks records that match
+ the migration's target. To clean up this stuck migration, see the
+ [14.5.0 version-specific instructions](index.md#1450).
+- GitLab 14.8 introduced an issue where a background migration named
+ `PopulateTopicsNonPrivateProjectsCount` can be permanently stuck in a
+ **pending** state across upgrades. To clean up this stuck migration, see the
+ [14.8.0 version-specific instructions](index.md#1480).
+- GitLab 14.9 introduced an issue where a background migration named
+ `ResetDuplicateCiRunnersTokenValuesOnProjects` can be permanently stuck in a
+ **pending** state across upgrades when the instance lacks records that match
+ the migration's target. To clean up this stuck migration, see the
+ [14.9.0 version-specific instructions](index.md#1490).
+
+For other background migrations stuck in pending, run the following check. If
+it returns non-zero and the count does not decrease over time, follow the rest
+of the steps in this section.
+
+```shell
+# For Omnibus installations:
+sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
+
+# For installations from source:
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
+```
+
+It is safe to re-attempt these migrations to clear them out from a pending status:
+
+**For Omnibus installations**
+
+```shell
+# Start the rails console
+sudo gitlab-rails c
+
+# Execute the following in the rails console
+Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
+ puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
+ result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
+ puts "Result: #{result}"
+end
+```
+
+**For installations from source**
+
+```shell
+# Start the rails console
+sudo -u git -H bundle exec rails RAILS_ENV=production
+
+# Execute the following in the rails console
+Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
+ puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
+ result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
+ puts "Result: #{result}"
+end
+```
diff --git a/doc/update/index.md b/doc/update/index.md
index 380ec371e8e..8dda96c56c5 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -73,210 +73,12 @@ from the chart version to GitLab version to determine the [upgrade path](#upgrad
See the guide to [plan your GitLab upgrade](plan_your_upgrade.md).
-## Checking for background migrations before upgrading
+## Check for background migrations before upgrading
Certain releases may require different migrations to be
finished before you update to the newer version.
-[Batched migrations](#batched-background-migrations) are a migration type available in GitLab 14.0 and later.
-Background migrations and batched migrations are not the same, so you should check that both are
-complete before updating.
-
-Decrease the time required to complete these migrations by increasing the number of
-[Sidekiq workers](../administration/sidekiq/extra_sidekiq_processes.md)
-that can process jobs in the `background_migration` queue.
-
-### Background migrations
-
-#### Pending migrations
-
-**For Omnibus installations:**
-
-```shell
-sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
-sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'
-```
-
-**For installations from source:**
-
-```shell
-cd /home/git/gitlab
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'
-```
-
-#### Failed migrations
-
-**For Omnibus installations:**
-
-For GitLab 14.0-14.9:
-
-```shell
-sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count'
-```
-
-For GitLab 14.10 and later:
-
-```shell
-sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count'
-```
-
-**For installations from source:**
-
-For GitLab 14.0-14.9:
-
-```shell
-cd /home/git/gitlab
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.failed.count'
-```
-
-For GitLab 14.10 and later:
-
-```shell
-cd /home/git/gitlab
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.with_status(:failed).count'
-```
-
-### Batched background migrations
-
-GitLab 14.0 introduced [batched background migrations](../user/admin_area/monitoring/background_migrations.md).
-
-Some installations [may need to run GitLab 14.0 for at least a day](#1400) to complete the database changes introduced by that upgrade.
-
-Batched background migrations are handled by Sidekiq and [run in isolation](../development/database/batched_background_migrations.md#isolation), so an instance can remain operational while the migrations are processed. However, there may be performance degradation on larger instances that are heavily used while batched background migrations are run, so it's a good idea to [actively monitor the Sidekiq status](../user/admin_area/index.md#background-jobs) until all migrations are completed.
-
-#### Check the status of batched background migrations
-
-To check the status of batched background migrations:
-
-1. On the top bar, select **Main menu > Admin**.
-1. On the left sidebar, select **Monitoring > Background Migrations**.
-
- ![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png)
-
-All migrations must have a `Finished` status before you upgrade GitLab.
-
-The status of batched background migrations can also be queried directly in the database.
-
-1. Log into a `psql` prompt according to the directions for your instance's installation method
-(for example, `sudo gitlab-psql` for Omnibus installations).
-1. Run the following query in the `psql` session to see details on incomplete batched background migrations:
-
- ```sql
- select job_class_name, table_name, column_name, job_arguments from batched_background_migrations where status <> 3;
- ```
-
-If the migrations are not finished and you try to update to a later version,
-GitLab prompts you with an error:
-
-```plaintext
-Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
-```
-
-If you get this error, [check the batched background migration options](../user/admin_area/monitoring/background_migrations.md#database-migrations-failing-because-of-batched-background-migration-not-finished) to complete the upgrade.
-
-### What do you do if your background migrations are stuck?
-
-WARNING:
-The following operations can disrupt your GitLab performance. They run a number of Sidekiq jobs that perform various database or file updates.
-
-#### Background migrations remain in the Sidekiq queue
-
-Run the following check. If it returns non-zero and the count does not decrease over time, follow the rest of the steps in this section.
-
-```shell
-# For Omnibus installations:
-sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
-
-# For installations from source:
-cd /home/git/gitlab
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
-```
-
-It is safe to re-execute the following commands, especially if you have 1000+ pending jobs which would likely overflow your runtime memory.
-
-**For Omnibus installations**
-
-```shell
-# Start the rails console
-sudo gitlab-rails c
-
-# Execute the following in the rails console
-scheduled_queue = Sidekiq::ScheduledSet.new
-pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
-pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }
-```
-
-**For installations from source**
-
-```shell
-# Start the rails console
-sudo -u git -H bundle exec rails RAILS_ENV=production
-
-# Execute the following in the rails console
-scheduled_queue = Sidekiq::ScheduledSet.new
-pending_job_classes = scheduled_queue.select { |job| job["class"] == "BackgroundMigrationWorker" }.map { |job| job["args"].first }.uniq
-pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }
-```
-
-#### Background migrations stuck in 'pending' state
-
-GitLab 13.6 introduced an issue where a background migration named `BackfillJiraTrackerDeploymentType2` can be permanently stuck in a **pending** state across upgrades. To clean up this stuck migration, see the [13.6.0 version-specific instructions](#1360).
-
-GitLab 14.2 introduced an issue where a background migration named `BackfillDraftStatusOnMergeRequests` can be permanently stuck in a **pending** state across upgrades when the instance lacks records that match the migration's target. To clean up this stuck migration, see the [14.2.0 version-specific instructions](#1420).
-
-GitLab 14.4 introduced an issue where a background migration named `PopulateTopicsTotalProjectsCountCache` can be permanently stuck in a **pending** state across upgrades when the instance lacks records that match the migration's target. To clean up this stuck migration, see the [14.4.0 version-specific instructions](#1440).
-
-GitLab 14.5 introduced an issue where a background migration named `UpdateVulnerabilityOccurrencesLocation` can be permanently stuck in a **pending** state across upgrades when the instance lacks records that match the migration's target. To clean up this stuck migration, see the [14.5.0 version-specific instructions](#1450).
-
-GitLab 14.8 introduced an issue where a background migration named `PopulateTopicsNonPrivateProjectsCount` can be permanently stuck in a **pending** state across upgrades. To clean up this stuck migration, see the [14.8.0 version-specific instructions](#1480).
-
-GitLab 14.9 introduced an issue where a background migration named `ResetDuplicateCiRunnersTokenValuesOnProjects` can be permanently stuck in a **pending** state across upgrades when the instance lacks records that match the migration's target. To clean up this stuck migration, see the [14.9.0 version-specific instructions](#1490).
-
-For other background migrations stuck in pending, run the following check. If it returns non-zero and the count does not decrease over time, follow the rest of the steps in this section.
-
-```shell
-# For Omnibus installations:
-sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
-
-# For installations from source:
-cd /home/git/gitlab
-sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
-```
-
-It is safe to re-attempt these migrations to clear them out from a pending status:
-
-**For Omnibus installations**
-
-```shell
-# Start the rails console
-sudo gitlab-rails c
-
-# Execute the following in the rails console
-Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
- puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
- result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
- puts "Result: #{result}"
-end
-```
-
-**For installations from source**
-
-```shell
-# Start the rails console
-sudo -u git -H bundle exec rails RAILS_ENV=production
-
-# Execute the following in the rails console
-Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
- puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
- result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
- puts "Result: #{result}"
-end
-```
-
-#### Batched migrations (GitLab 14.0 and later)
-
-See [troubleshooting batched background migrations](../user/admin_area/monitoring/background_migrations.md#troubleshooting).
+For more information, see [background migrations](background_migrations.md).
## Dealing with running CI/CD pipelines and jobs
@@ -360,7 +162,7 @@ A *major* upgrade requires the following steps:
1. Upgrade to the "dot zero" release of the next major version (`X.0.Z`).
1. Optional. Follow the [upgrade path](#upgrade-paths), and proceed with upgrading to newer releases of that major version.
-It's also important to ensure that any [background migrations have been fully completed](#checking-for-background-migrations-before-upgrading)
+It's also important to ensure that any [background migrations have been fully completed](background_migrations.md)
before upgrading to a new major version.
If you have enabled the [Elasticsearch integration](../integration/advanced_search/elasticsearch.md) **(PREMIUM SELF)**, then
@@ -477,7 +279,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
To upgrade to this version, no records with a `NULL` `work_item_type_id` should exist on the `issues` table.
There are multiple `BackfillWorkItemTypeIdForIssues` background migrations that will be finalized with
the `EnsureWorkItemTypeBackfillMigrationFinished` post-deploy migration.
-- GitLab 15.4.0 introduced a [batched background migration](#batched-background-migrations) to
+- GitLab 15.4.0 introduced a [batched background migration](background_migrations.md#batched-background-migrations) to
[backfill `namespace_id` values on issues table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91921). This
migration might take multiple hours or days to complete on larger GitLab instances. Please make sure the migration
has completed successfully before upgrading to 15.7.0.
@@ -515,6 +317,20 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
- You should use one of the [officially supported PostgreSQL versions](../administration/package_information/postgresql_versions.md). Some database migrations can cause stability and performance issues with older PostgreSQL versions.
- Git 2.37.0 and later is required by Gitaly. For installations from source, we recommend you use the [Git version provided by Gitaly](../install/installation.md#git).
+- A database change to modify the behavior of four indexes fails on instances
+ where these indexes do not exist:
+
+ ```plaintext
+ Caused by:
+ PG::UndefinedTable: ERROR: relation "index_issues_on_title_trigram" does not exist
+ ```
+
+ The other three indexes are: `index_merge_requests_on_title_trigram`, `index_merge_requests_on_description_trigram`,
+ and `index_issues_on_description_trigram`.
+
+ This issue was [fixed in GitLab 15.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105375) and backported
+ to GitLab 15.6.2. The issue can also be worked around:
+ [read about how to create these indexes](https://gitlab.com/gitlab-org/gitlab/-/issues/378343#note_1199863087).
### 15.5.0
@@ -538,7 +354,7 @@ A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706)
### 15.4.0
-- GitLab 15.4.0 includes a [batched background migration](#batched-background-migrations) to [remove incorrect values from `expire_at` in `ci_job_artifacts` table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89318).
+- GitLab 15.4.0 includes a [batched background migration](background_migrations.md#batched-background-migrations) to [remove incorrect values from `expire_at` in `ci_job_artifacts` table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89318).
This migration might take hours or days to complete on larger GitLab instances.
- By default, Gitaly and Praefect nodes use the time server at `pool.ntp.org`. If your instance can not connect to `pool.ntp.org`, [configure the `NTP_HOST` variable](../administration/gitaly/praefect.md#customize-time-server-setting).
- GitLab 15.4.0 introduced a default [Sidekiq routing rule](../administration/sidekiq/extra_sidekiq_routing.md) that routes all jobs to the `default` queue. For instances using [queue selectors](../administration/sidekiq/processing_specific_job_classes.md#queue-selectors), this will cause [performance problems](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1991) as some Sidekiq processes will be idle.
@@ -556,7 +372,7 @@ A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706)
In a highly available or GitLab Geo environment, secrets need to be the same on all nodes.
If you're manually syncing the secrets file across nodes, or manually specifying secrets in
`/etc/gitlab/gitlab.rb`, make sure `/etc/gitlab/gitlab-secrets.json` is the same on all nodes.
-- GitLab 15.4.0 introduced a [batched background migration](#batched-background-migrations) to
+- GitLab 15.4.0 introduced a [batched background migration](background_migrations.md#batched-background-migrations) to
[backfill `namespace_id` values on issues table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91921). This
migration might take multiple hours or days to complete on larger GitLab instances. Please make sure the migration
has completed successfully before upgrading to 15.7.0 or later.
@@ -712,11 +528,11 @@ A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706)
### 14.9.0
- Database changes made by the upgrade to GitLab 14.9 can take hours or days to complete on larger GitLab instances.
- These [batched background migrations](#batched-background-migrations) update whole database tables to ensure corresponding
+ These [batched background migrations](background_migrations.md#batched-background-migrations) update whole database tables to ensure corresponding
records in `namespaces` table for each record in `projects` table.
After you update to 14.9.0 or a later 14.9 patch version,
- [batched background migrations must finish](#batched-background-migrations)
+ [batched background migrations must finish](background_migrations.md#batched-background-migrations)
before you update to a later version.
If the migrations are not finished and you try to update to a later version,
@@ -792,7 +608,7 @@ that may remain stuck permanently in a **pending** state.
[an issue with job retries](https://gitlab.com/gitlab-org/gitlab/-/issues/357822), first upgrade
to GitLab 14.7.x and make sure all batched migrations have finished.
- If upgrading from version 14.3.0 or later, you might notice a failed
- [batched migration](../user/admin_area/monitoring/background_migrations.md) named
+ [batched migration](background_migrations.md#batched-background-migrations) named
`BackfillNamespaceIdForNamespaceRoute`. You can [ignore](https://gitlab.com/gitlab-org/gitlab/-/issues/357822)
this. Retry it after you upgrade to version 14.9.x.
- If you run external PostgreSQL, particularly AWS RDS,
@@ -915,7 +731,7 @@ that may remain stuck permanently in a **pending** state when the instance lacks
### 14.3.0
- [Instances running 14.0.0 - 14.0.4 should not upgrade directly to GitLab 14.2 or later](#upgrading-to-later-14y-releases).
-- Ensure [batched background migrations finish](#batched-background-migrations) before upgrading
+- Ensure [batched background migrations finish](background_migrations.md#batched-background-migrations) before upgrading
to 14.3.Z from earlier GitLab 14 releases.
- Ruby 2.7.4 is required. Refer to [the Ruby installation instructions](../install/installation.md#2-ruby)
for how to proceed.
@@ -977,7 +793,7 @@ for how to proceed.
### 14.2.0
- [Instances running 14.0.0 - 14.0.4 should not upgrade directly to GitLab 14.2 or later](#upgrading-to-later-14y-releases).
-- Ensure [batched background migrations finish](#batched-background-migrations) before upgrading
+- Ensure [batched background migrations finish](background_migrations.md#batched-background-migrations) before upgrading
to 14.2.Z from earlier GitLab 14 releases.
- GitLab 14.2.0 contains background migrations to [address Primary Key overflow risk for tables with an integer PK](https://gitlab.com/groups/gitlab-org/-/epics/4785) for the tables listed below:
- [`ci_build_needs`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65216)
@@ -1021,7 +837,7 @@ for how to proceed.
It is not required for instances already running 14.0.5 (or later) to stop at 14.1.Z.
14.1 is included on the upgrade path for the broadest compatibility
with self-managed installations, and ensure 14.0.0-14.0.4 installations do not
- encounter issues with [batched background migrations](#batched-background-migrations).
+ encounter issues with [batched background migrations](background_migrations.md#batched-background-migrations).
- Upgrading to GitLab [14.5](#1450) (or later) may take a lot longer if you do not upgrade to at least 14.1
first. The 14.1 merge request diff commits database migration can take hours to run, but runs in the
@@ -1043,14 +859,14 @@ Prerequisites:
Long running batched background database migrations:
- Database changes made by the upgrade to GitLab 14.0 can take hours or days to complete on larger GitLab instances.
- These [batched background migrations](#batched-background-migrations) update whole database tables to mitigate primary key overflow and must be finished before upgrading to GitLab 14.2 or later.
+ These [batched background migrations](background_migrations.md#batched-background-migrations) update whole database tables to mitigate primary key overflow and must be finished before upgrading to GitLab 14.2 or later.
- Due to an issue where `BatchedBackgroundMigrationWorkers` were
[not working](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/2785#note_614738345)
for self-managed instances, a [fix was created](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65106)
that requires an update to at least 14.0.5. The fix was also released in [14.1.0](#1410).
After you update to 14.0.5 or a later 14.0 patch version,
- [batched background migrations must finish](#batched-background-migrations)
+ [batched background migrations must finish](background_migrations.md#batched-background-migrations)
before you update to a later version.
If the migrations are not finished and you try to update to a later version,
@@ -1060,7 +876,7 @@ Long running batched background database migrations:
Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
```
- See how to [resolve this error](../user/admin_area/monitoring/background_migrations.md#database-migrations-failing-because-of-batched-background-migration-not-finished).
+ See how to [resolve this error](background_migrations.md#database-migrations-failing-because-of-batched-background-migration-not-finished).
Other issues:
@@ -1075,11 +891,11 @@ Other issues:
#### Upgrading to later 14.Y releases
- Instances running 14.0.0 - 14.0.4 should not upgrade directly to GitLab 14.2 or later,
- because of [batched background migrations](#batched-background-migrations).
+ because of [batched background migrations](background_migrations.md#batched-background-migrations).
1. Upgrade first to either:
- 14.0.5 or a later 14.0.Z patch release.
- 14.1.0 or a later 14.1.Z patch release.
- 1. [Batched background migrations must finish](#batched-background-migrations)
+ 1. [Batched background migrations must finish](background_migrations.md#batched-background-migrations)
before you update to a later version [and may take longer than usual](#1400).
### 13.12.0
@@ -1182,7 +998,7 @@ See [Maintenance mode issue in GitLab 13.9 to 14.4](#maintenance-mode-issue-in-g
### 13.8.8
-GitLab 13.8 includes a background migration to address [an issue with duplicate service records](https://gitlab.com/gitlab-org/gitlab/-/issues/290008). If duplicate services are present, this background migration must complete before a unique index is applied to the services table, which was [introduced in GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52563). Upgrades from GitLab 13.8 and earlier to later versions must include an intermediate upgrade to GitLab 13.8.8 and [must wait until the background migrations complete](#checking-for-background-migrations-before-upgrading) before proceeding.
+GitLab 13.8 includes a background migration to address [an issue with duplicate service records](https://gitlab.com/gitlab-org/gitlab/-/issues/290008). If duplicate services are present, this background migration must complete before a unique index is applied to the services table, which was [introduced in GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52563). Upgrades from GitLab 13.8 and earlier to later versions must include an intermediate upgrade to GitLab 13.8.8 and [must wait until the background migrations complete](background_migrations.md) before proceeding.
If duplicate services are still present, an upgrade to 13.9.x or later results in a failed upgrade with the following error:
diff --git a/doc/update/package/index.md b/doc/update/package/index.md
index e0dc3304c82..575194793c2 100644
--- a/doc/update/package/index.md
+++ b/doc/update/package/index.md
@@ -16,7 +16,7 @@ GitLab package.
- If you are upgrading from a non-package installation to a GitLab package installation, see
[Upgrading from a non-package installation to a GitLab package installation](https://docs.gitlab.com/omnibus/update/convert_to_omnibus.html).
- Ensure that any
- [background migrations](../index.md#checking-for-background-migrations-before-upgrading)
+ [background migrations](../background_migrations.md)
are fully completed. Upgrading
before background migrations have finished can lead to data corruption.
We recommend performing upgrades between major and minor releases no more than once per
diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md
index e0c0cdf31f9..efbe1bc7fcd 100644
--- a/doc/update/patch_versions.md
+++ b/doc/update/patch_versions.md
@@ -136,5 +136,5 @@ If all items are green, then congratulations upgrade complete!
### 11. Make sure background migrations are finished
-[Check the status of background migrations](../user/admin_area/monitoring/background_migrations.md#check-the-status-of-background-migrations)
+[Check the status of background migrations](../update/background_migrations.md)
and make sure they are finished.
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
index 8169645e278..667ed37af02 100644
--- a/doc/update/plan_your_upgrade.md
+++ b/doc/update/plan_your_upgrade.md
@@ -126,7 +126,7 @@ to your instance and then upgrade it for any relevant features you're using.
- Account for any [version-specific changes](package/index.md#version-specific-changes).
- Check the [OS compatibility with the target GitLab version](../administration/package_information/supported_os.md).
- Due to background migrations, plan to pause before any further upgrades.
- [All migrations must finish running](index.md#checking-for-background-migrations-before-upgrading)
+ [All migrations must finish running](background_migrations.md)
before the next upgrade.
- If available in your starting version, consider
[turning on maintenance mode](../administration/maintenance_mode/index.md) during the
@@ -173,7 +173,7 @@ If you have Kubernetes clusters connected with GitLab, [upgrade your GitLab agen
#### Elasticsearch
Before updating GitLab, confirm Advanced Search migrations are complete by
-[checking for pending advanced search migrations](index.md#checking-for-pending-advanced-search-migrations).
+[checking for pending advanced search migrations](background_migrations.md).
After updating GitLab, you may have to upgrade
[Elasticsearch if the new version breaks compatibility](../integration/advanced_search/elasticsearch.md#version-requirements).
diff --git a/doc/update/upgrading_from_source.md b/doc/update/upgrading_from_source.md
index f5b85330f3b..852b54c7339 100644
--- a/doc/update/upgrading_from_source.md
+++ b/doc/update/upgrading_from_source.md
@@ -29,7 +29,7 @@ to identify the ideal upgrade path.
Before upgrading to a new major version, you should ensure that any background
migration jobs from previous releases have been completed. To see the current size of the `background_migration` queue,
-[Check for background migrations before upgrading](index.md#checking-for-background-migrations-before-upgrading).
+[Check for background migrations before upgrading](background_migrations.md).
## Guidelines for all versions
diff --git a/doc/update/zero_downtime.md b/doc/update/zero_downtime.md
index e3bf9e7e123..deda12145da 100644
--- a/doc/update/zero_downtime.md
+++ b/doc/update/zero_downtime.md
@@ -54,12 +54,12 @@ Certain major/minor releases may require a set of background migrations to be
finished. To guarantee this, such a release processes any remaining jobs
before continuing the upgrading procedure. While this doesn't require downtime
(if the above conditions are met) we require that you
-[wait for background migrations to complete](index.md#checking-for-background-migrations-before-upgrading)
+[wait for background migrations to complete](background_migrations.md)
between each major/minor release upgrade.
The time necessary to complete these migrations can be reduced by
increasing the number of Sidekiq workers that can process jobs in the
`background_migration` queue. To see the size of this queue,
-[Check for background migrations before upgrading](index.md#checking-for-background-migrations-before-upgrading).
+[Check for background migrations before upgrading](background_migrations.md).
As a guideline, any database smaller than 10 GB doesn't take too much time to
upgrade; perhaps an hour at most per minor release. Larger databases however may
diff --git a/doc/user/admin_area/monitoring/background_migrations.md b/doc/user/admin_area/monitoring/background_migrations.md
index 1d9d72c152b..b4a6f7f66fb 100644
--- a/doc/user/admin_area/monitoring/background_migrations.md
+++ b/doc/user/admin_area/monitoring/background_migrations.md
@@ -1,244 +1,11 @@
---
-stage: Data Stores
-group: Database
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+redirect_to: '../../../update/background_migrations.md'
+remove_date: '2023-03-11'
---
-# Batched background migrations **(FREE SELF)**
+This document was moved to [another location](../../../update/background_migrations.md).
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51332) in GitLab 13.11.
-> - [Deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/329511) in GitLab 13.12.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-batched-background-migrations).
-
-There can be [risks when disabling released features](../../../administration/feature_flags.md#risks-when-disabling-released-features).
-Refer to this feature's version history for more details.
-
-To update database tables in batches, GitLab can use batched background migrations. These migrations
-are created by GitLab developers and run automatically on upgrade. However, such migrations are
-limited in scope to help with migrating some `integer` database columns to `bigint`. This is needed to
-prevent integer overflow for some tables.
-
-## Check the status of background migrations
-
-All migrations must have a `Finished` status before you [upgrade GitLab](../../../update/index.md).
-You can [check the status of existing migrations](../../../update/index.md#batched-background-migrations).
-
-## Enable or disable batched background migrations
-
-WARNING:
-If you disable this feature flag, GitLab upgrades may fail.
-
-Batched background migrations are under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:execute_batched_migrations_on_schedule)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:execute_batched_migrations_on_schedule)
-```
-
-### Pause batched background migrations in GitLab 14.x
-
-To pause an ongoing batched background migration, use the `disable` command above.
-This command causes the migration to complete the current batch, and then wait to start the next batch.
-
-Use the following database queries to see the state of the current batched background migration:
-
-1. Obtain the ID of the running migration:
-
- ```sql
- SELECT
- id,
- job_class_name,
- table_name,
- column_name,
- job_arguments
- FROM batched_background_migrations
- WHERE status <> 3;
- ```
-
-1. Run this query, replacing `XX` with the ID you obtained in the previous step,
- to see the status of the migration:
-
- ```sql
- SELECT
- started_at,
- finished_at,
- finished_at - started_at AS duration,
- min_value,
- max_value,
- batch_size,
- sub_batch_size
- FROM batched_background_migration_jobs
- WHERE batched_background_migration_id = XX
- ORDER BY id DESC
- limit 10;
- ```
-
-1. Run the query multiple times within a few minutes to ensure no new row has been added.
- If no new row has been added, the migration has been paused.
-
-1. After confirming the migration has paused, restart the migration (using the `enable`
- command above) to proceed with the batch when ready. On larger instances,
- background migrations can take as long as 48 hours to complete each batch.
-
-## Automatic batch size optimization
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60133) in GitLab 13.12.
-> - [Deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/329511) in GitLab 13.12.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-automatic-batch-size-optimization).
-
-There can be [risks when disabling released features](../../../administration/feature_flags.md#risks-when-disabling-released-features).
-Refer to this feature's version history for more details.
-
-To maximize throughput of batched background migrations (in terms of the number of tuples updated per time unit), batch sizes are automatically adjusted based on how long the previous batches took to complete.
-
-## Enable or disable automatic batch size optimization
-
-Automatic batch size optimization for batched background migrations is under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:optimize_batched_migrations)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:optimize_batched_migrations)
-```
-
-## Troubleshooting
-
-### Database migrations failing because of batched background migration not finished
-
-When updating to GitLab 14.2 or later there might be a database migration failing with a message like:
-
-```plaintext
-StandardError: An error has occurred, all later migrations canceled:
-
-Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
- {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", :table_name=>"push_event_payloads", :column_name=>"event_id", :job_arguments=>[["event_id"], ["event_id_convert_to_bigint"]]}
-```
-
-First, check if you have followed the [version-specific upgrade instructions for 14.2](../../../update/index.md#1420).
-If you have, you can [manually finish the batched background migration](#manually-finishing-a-batched-background-migration).
-If you haven't, choose one of the following methods:
-
-1. [Rollback and upgrade](#roll-back-and-follow-the-required-upgrade-path) through one of the required
-versions before updating to 14.2+.
-1. [Roll forward](#roll-forward-and-finish-the-migrations-on-the-upgraded-version), staying on the current
-version and manually ensuring that the batched migrations complete successfully.
-
-#### Roll back and follow the required upgrade path
-
-1. [Rollback and restore the previously installed version](../../../raketasks/backup_restore.md)
-1. Update to either 14.0.5 or 14.1 **before** updating to 14.2+
-1. [Check the status](#check-the-status-of-background-migrations) of the batched background migrations and
-make sure they are all marked as finished before attempting to upgrade again. If any remain marked as active,
-you can [manually finish them](#manually-finishing-a-batched-background-migration).
-
-#### Roll forward and finish the migrations on the upgraded version
-
-##### For a deployment with downtime
-
-To run all the batched background migrations, it can take a significant amount of time
-depending on the size of your GitLab installation.
-
-1. [Check the status](#check-the-status-of-background-migrations) of the batched background migrations in the
-database, and [manually run them](#manually-finishing-a-batched-background-migration) with the appropriate
-arguments until the status query returns no rows.
-1. When the status of all of all them is marked as complete, re-run migrations for your installation.
-1. [Complete the database migrations](../../../administration/raketasks/maintenance.md#run-incomplete-database-migrations) from your GitLab upgrade:
-
- ```plaintext
- sudo gitlab-rake db:migrate
- ```
-
-1. Run a reconfigure:
-
- ```plaintext
- sudo gitlab-ctl reconfigure
- ```
-
-1. Finish the upgrade for your installation.
-
-##### For a no-downtime deployment
-
-As the failing migrations are post-deployment migrations, you can remain on a running instance of the upgraded
-version and wait for the batched background migrations to finish normally.
-
-1. [Check the status](#check-the-status-of-background-migrations) of the batched background migration from
-the error message, and make sure it is listed as finished. If it is still active, either wait until it is done,
-or [manually finish it](#manually-finishing-a-batched-background-migration).
-1. Re-run migrations for your installation, so the remaining post-deployment migrations finish.
-
-### Manually finishing a batched background migration
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62634) in GitLab 14.1
-
-If you need to manually finish a batched background migration due to an
-error, you can run:
-
-```shell
-sudo gitlab-rake gitlab:background_migrations:finalize[<job_class_name>,<table_name>,<column_name>,'<job_arguments>']
-```
-
-Replace the values in angle brackets with the correct
-arguments. For example, if you receive an error similar to this:
-
-```plaintext
-StandardError: An error has occurred, all later migrations canceled:
-
-Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
- {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", :table_name=>"push_event_payloads", :column_name=>"event_id", :job_arguments=>[["event_id"], ["event_id_convert_to_bigint"]]}
-```
-
-Plug the arguments from the error message into the command:
-
-```shell
-sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,push_event_payloads,event_id,'[["event_id"]\, ["event_id_convert_to_bigint"]]']
-```
-
-If you need to manually run a batched background migration to continue an upgrade, you can
-[check the status](#check-the-status-of-background-migrations) in the database and get the
-arguments from the query results. For example, if the query returns this:
-
-```plaintext
- job_class_name | table_name | column_name | job_arguments
----------------------------------------+------------+-------------+------------------------------------
- CopyColumnUsingBackgroundMigrationJob | events | id | [["id"], ["id_convert_to_bigint"]]
- ```
-
-The results from the query can be plugged into the command:
-
-```shell
-sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[["id"]\, ["id_convert_to_bigint"]]']
-```
-
-### The `BackfillNamespaceIdForNamespaceRoute` batched migration job fails
-
-In GitLab 14.8, the `BackfillNamespaceIdForNamespaceRoute` batched background migration job
-may fail to complete. When retried, a `500 Server Error` is returned. This issue was
-[resolved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82387) in GitLab 14.9.
-
-To resolve this issue, [upgrade GitLab](../../../update/index.md) from 14.8 to 14.9.
-You can ignore the failed batch migration until after you update to GitLab 14.9.
+<!-- This redirect file can be deleted after <2023-03-11>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/infrastructure/iac/terraform_template_recipes.md b/doc/user/infrastructure/iac/terraform_template_recipes.md
index a86ab35e9c6..fc03833ce8d 100644
--- a/doc/user/infrastructure/iac/terraform_template_recipes.md
+++ b/doc/user/infrastructure/iac/terraform_template_recipes.md
@@ -58,3 +58,126 @@ state-list:
resource_group: ${TF_STATE_NAME}
script: gitlab-terraform state list
```
+
+## Add custom debug tools to jobs
+
+The default image used by Terraform template jobs contains only minimal tooling.
+However, you might want to add additional tools for debugging.
+
+To add an additional tool:
+
+1. Install the tool in the `before_script` of a job or pipeline.
+1. Use the tool in the `script` or `after_script` block.
+ - If you use the `script` block, be sure to re-add the template job commands.
+
+For example, the following snippet installs `bash` and `jq` in the `before_script` for all
+jobs in the pipeline:
+
+```yaml
+include:
+ - template: Terraform.latest.gitlab-ci.yml
+
+default:
+ before_script: apk add --update bash jq
+```
+
+To add it to only the `build` and `deploy` jobs, add it to those jobs directly:
+
+```yaml
+include:
+ - template: Terraform.latest.gitlab-ci.yml
+
+build:
+ before_script: apk add --update bash jq
+
+deploy:
+ before_script: apk add --update bash jq
+```
+
+## Add custom container images
+
+For debug tools and simple installations, you should
+[add a custom debug tool to your job](#add-custom-debug-tools-to-jobs).
+If your tool is complex or benefits from caching,
+you can create a custom container image based on the
+[`gitlab-terraform`](https://gitlab.com/gitlab-org/terraform-images) images.
+You can use your custom image in subsequent Terraform jobs.
+
+To define a custom container image:
+
+1. Define a new `Dockerfile` with custom tooling. For example, install `bash` and `jq` in `.gitlab/ci/Dockerfile`:
+
+ ```dockerfile
+ FROM registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+
+ RUN apk add --update bash jq
+ ```
+
+1. In a new job, define a `prepare` stage that builds the image whenever the `Dockerfile` changes.
+ - The built image is pushed to the [GitLab Container Registry](../../packages/container_registry). A tag is applied to indicate whether the image was built from a merge request or from the default branch.
+1. Use your image in your Terraform jobs, such as `build` and `deploy`.
+ - You can combine your image with specialized `before_script` configurations to perform setup commands, like to generate inputs for Terraform.
+
+For example, a fully functioning pipeline configuration might look like:
+
+```yaml
+include:
+ - template: Terraform.latest.gitlab-ci.yml
+
+variables:
+ IMAGE_TAG: latest
+
+workflow:
+ rules:
+ - if: $CI_MERGE_REQUEST_IID
+ changes:
+ - .gitlab/ci/Dockerfile
+ variables:
+ IMAGE_TAG: ${CI_COMMIT_REF_SLUG}
+ - when: always
+
+stages:
+ - prepare
+ - validate
+ - test
+ - build
+ - deploy
+ - cleanup
+
+prepare:image:
+ needs: []
+ stage: prepare
+ image:
+ name: gcr.io/kaniko-project/executor:v1.9.0-debug
+ entrypoint: [""]
+ rules:
+ # Tag with the commit SHA if we're in an MR
+ - if: $CI_MERGE_REQUEST_IID
+ changes:
+ - .gitlab/ci/Dockerfile
+ variables:
+ DOCKER_TAG: $CI_COMMIT_REF_SLUG
+ # If we're on our main branch, tag with "latest"
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+ changes:
+ - .gitlab/ci/Dockerfile
+ variables:
+ DOCKER_TAG: latest
+ before_script:
+ # Authenticate to the docker registry and dependency proxy
+ - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"},\"$CI_DEPENDENCY_PROXY_SERVER\"}}" > /kaniko/.docker/config.json
+ script:
+ - /kaniko/executor
+ --context "${CI_PROJECT_DIR}/.gitlab/ci"
+ --cache=true
+ --dockerfile "${CI_PROJECT_DIR}/.gitlab/ci/Dockerfile"
+ --destination "${CI_REGISTRY_IMAGE}:${DOCKER_TAG}"
+
+build:
+ image: ${CI_REGISTRY_IMAGE}:${IMAGE_TAG}
+
+deploy:
+ image: ${CI_REGISTRY_IMAGE}:${IMAGE_TAG}
+```
+
+For an example repository, see the [GitLab Terraform template usage project](https://gitlab.com/gitlab-org/configure/examples/terraform-template-usage).
diff --git a/doc/user/project/description_templates.md b/doc/user/project/description_templates.md
index 7774b567e8b..ffbe7447aa8 100644
--- a/doc/user/project/description_templates.md
+++ b/doc/user/project/description_templates.md
@@ -40,7 +40,7 @@ To create an issue description template:
where `mytemplate` is the name of your issue template.
1. Commit to your default branch.
-To check if this has worked correctly, [create a new issue](issues/managing_issues.md#create-an-issue)
+To check if this has worked correctly, [create a new issue](issues/create_issues.md)
and see if you can find your description template in the **Choose a template** dropdown list.
## Create a merge request template
@@ -81,7 +81,7 @@ To discard any changes to the description you've made after selecting the templa
NOTE:
You can create shortcut links to create an issue using a designated template.
-For example: `https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Feature%20proposal`. Read more about [creating issues using a URL with prefilled values](issues/managing_issues.md#using-a-url-with-prefilled-values).
+For example: `https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Feature%20proposal`. Read more about [creating issues using a URL with prefilled values](issues/create_issues.md#using-a-url-with-prefilled-values).
### Supported variables in merge request templates
diff --git a/doc/user/project/issues/create_issues.md b/doc/user/project/issues/create_issues.md
new file mode 100644
index 00000000000..3c2e20c1250
--- /dev/null
+++ b/doc/user/project/issues/create_issues.md
@@ -0,0 +1,221 @@
+---
+stage: Plan
+group: Project Management
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Create an issue **(FREE)**
+
+When you create an issue, you are prompted to enter the fields of the issue.
+If you know the values you want to assign to an issue, you can use
+[quick actions](../quick_actions.md) to enter them.
+
+You can create an issue in many ways in GitLab:
+
+- [From a project](#from-a-project)
+- [From a group](#from-a-group)
+- [From another issue or incident](#from-another-issue-or-incident)
+- [From an issue board](#from-an-issue-board)
+- [By sending an email](#by-sending-an-email)
+- [Using a URL with prefilled values](#using-a-url-with-prefilled-values)
+- [Using Service Desk](#using-service-desk)
+
+## From a project
+
+Prerequisites:
+
+- You must have at least the Guest role for the project.
+
+To create an issue:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. Either:
+
+ - On the left sidebar, select **Issues**, and then, in the top right corner, select **New issue**.
+ - On the top bar, select the plus sign (**{plus-square}**) and then, under **This project**,
+ select **New issue**.
+
+1. Complete the [fields](#fields-in-the-new-issue-form).
+1. Select **Create issue**.
+
+The newly created issue opens.
+
+## From a group
+
+Issues belong to projects, but when you're in a group, you can access and create issues that belong
+to the projects in the group.
+
+Prerequisites:
+
+- You must have at least the Guest role for the project in the group.
+
+To create an issue from a group:
+
+1. On the top bar, select **Main menu > Groups** and find your group.
+1. On the left sidebar, select **Issues**.
+1. In the top right corner, select **Select project to create issue**.
+1. Select the project you'd like to create an issue for. The button now reflects the selected
+ project.
+1. Select **New issue in `<project name>`**.
+1. Complete the [fields](#fields-in-the-new-issue-form).
+1. Select **Create issue**.
+
+The newly created issue opens.
+
+The project you selected most recently becomes the default for your next visit.
+This can save you a lot of time, if you mostly create issues for the same project.
+
+## From another issue or incident
+
+> - New issue becoming linked to the issue of origin [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68226) in GitLab 14.3.
+> - **Relate to…** checkbox [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198494) in GitLab 14.9.
+
+You can create a new issue from an existing one. The two issues can then be marked as related.
+
+Prerequisites:
+
+- You must have at least the Guest role for the project.
+
+To create an issue from another issue:
+
+1. In an existing issue, select the vertical ellipsis (**{ellipsis_v}**).
+1. Select **New related issue**.
+1. Complete the [fields](#fields-in-the-new-issue-form).
+ The new issue form has a **Relate to issue #123** checkbox, where `123` is the ID of the
+ issue of origin. If you keep this checkbox checked, the two issues become
+ [linked](related_issues.md).
+1. Select **Create issue**.
+
+The newly created issue opens.
+
+## From an issue board
+
+You can create a new issue from an [issue board](../issue_board.md).
+
+Prerequisites:
+
+- You must have at least the Guest role for the project.
+
+To create an issue from a project issue board:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. Select **Issues > Boards**.
+1. At the top of a board list, select **New issue** (**{plus-square}**).
+1. Enter the issue's title.
+1. Select **Create issue**.
+
+To create an issue from a group issue board:
+
+1. On the top bar, select **Main menu > Groups** and find your group.
+1. Select **Issues > Boards**.
+1. At the top of a board list, select **New issue** (**{plus-square}**).
+1. Enter the issue's title.
+1. Under **Projects**, select the project in the group that the issue should belong to.
+1. Select **Create issue**.
+
+The issue is created and shows up in the board list. It shares the list's characteristic, so, for
+example, if the list is scoped to a label `Frontend`, the new issue also has this label.
+
+## By sending an email
+
+> - Generated email address format changed in GitLab 11.7.
+> - The older format is still supported, so existing aliases and contacts still work.
+
+You can send an email to create an issue in a project on the project's
+**Issues List** page.
+
+Prerequisites:
+
+- Your GitLab instance must have [incoming email](../../../administration/incoming_email.md)
+ configured.
+- There must be at least one issue in the issue list.
+- You must have at least the Guest role for the project.
+
+To email an issue to a project:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. Select **Issues**.
+1. At the bottom of the page, select **Email a new issue to this project**.
+1. To copy the email address, select **Copy** (**{copy-to-clipboard}**).
+1. From your email client, send an email to this address.
+ The subject is used as the title of the new issue, and the email body becomes the description.
+ You can use [Markdown](../../markdown.md) and [quick actions](../quick_actions.md).
+
+A new issue is created, with your user as the author.
+You can save this address as a contact in your email client to use it again.
+
+WARNING:
+The email address you see is a private email address, generated just for you.
+**Keep it to yourself**, because anyone who knows it can create issues or merge requests as if they
+were you.
+
+To regenerate the email address:
+
+1. On the issues list, select **Email a new issue to this project**.
+1. Select **reset this token**.
+
+## Using a URL with prefilled values
+
+> - Ability to use both `issuable_template` and `issue[description]` in the same URL [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80554) in GitLab 14.9.
+> - Ability to specify `add_related_issue` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198494) in GitLab 14.9.
+
+To link directly to the new issue page with prefilled fields, use query
+string parameters in a URL. You can embed a URL in an external
+HTML page to create issues with certain fields prefilled.
+
+| Field | URL parameter | Notes |
+| -------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
+| Title | `issue[title]` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
+| Issue type | `issue[issue_type]` | Either `incident` or `issue`. |
+| Description template | `issuable_template` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
+| Description | `issue[description]` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). If used in combination with `issuable_template` or a [default issue template](../description_templates.md#set-a-default-template-for-merge-requests-and-issues), the `issue[description]` value is appended to the template. |
+| Confidential | `issue[confidential]` | If `true`, the issue is marked as confidential. |
+| Relate to… | `add_related_issue` | A numeric issue ID. If present, the issue form shows a [**Relate to…** checkbox](#from-another-issue-or-incident) to optionally link the new issue to the specified existing issue. |
+
+Adapt these examples to form your new issue URL with prefilled fields.
+To create an issue in the GitLab project:
+
+- With a prefilled title and description:
+
+ ```plaintext
+ https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Whoa%2C%20we%27re%20half-way%20there&issue[description]=Whoa%2C%20livin%27%20in%20a%20URL
+ ```
+
+- With a prefilled title and description template:
+
+ ```plaintext
+ https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Validate%20new%20concept&issuable_template=Feature%20Proposal%20-%20basic
+ ```
+
+- With a prefilled title, description, and marked as confidential:
+
+ ```plaintext
+ https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Validate%20new%20concept&issue[description]=Research%20idea&issue[confidential]=true
+ ```
+
+## Using Service Desk
+
+To offer email support, enable [Service Desk](../service_desk.md) for your project.
+
+Now, when your customer sends a new email, a new issue can be created in
+the appropriate project and followed up from there.
+
+### Fields in the new issue form
+
+> - Adding the new issue to an epic [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13847) in GitLab 13.1.
+> - Iteration field [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233517) in GitLab 15.6.
+
+When you're creating a new issue, you can complete the following fields:
+
+- Title
+- Type: either issue (default) or incident
+- [Description template](../description_templates.md): overwrites anything in the Description text box
+- Description: you can use [Markdown](../../markdown.md) and [quick actions](../quick_actions.md)
+- Checkbox to make the issue [confidential](confidential_issues.md)
+- [Assignees](managing_issues.md#assignee)
+- [Weight](issue_weight.md)
+- [Epic](../../group/epics/index.md)
+- [Due date](due_dates.md)
+- [Milestone](../milestones/index.md)
+- [Labels](../labels.md)
+- [Iteration](../../group/iterations/index.md)
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index 09067b69696..6c9a645d817 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -29,7 +29,7 @@ To learn how the GitLab Strategic Marketing department uses GitLab issues with [
## Related topics
-- [Create issues](managing_issues.md#create-an-issue)
+- [Create issues](create_issues.md)
- [Create an issue from a template](../../project/description_templates.md#use-the-templates)
- [Edit issues](managing_issues.md#edit-an-issue)
- [Move issues](managing_issues.md#move-an-issue)
diff --git a/doc/user/project/issues/issue_weight.md b/doc/user/project/issues/issue_weight.md
index 1ba5a4415e0..d852ad3262b 100644
--- a/doc/user/project/issues/issue_weight.md
+++ b/doc/user/project/issues/issue_weight.md
@@ -36,7 +36,7 @@ When you change the weight of an issue, the new value overwrites the previous va
### When you create an issue
-To set the issue weight when you [create an issue](managing_issues.md#create-an-issue), enter a
+To set the issue weight when you [create an issue](create_issues.md), enter a
number under **Weight**.
### From an existing issue
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index a6a0dad344f..ea90dda88f6 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -6,224 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Manage issues **(FREE)**
-[GitLab Issues](index.md) are the fundamental medium for collaborating on ideas and
-planning work in GitLab.
-
-## Create an issue
-
-When you create an issue, you are prompted to enter the fields of the issue.
-If you know the values you want to assign to an issue, you can use
-[quick actions](../quick_actions.md) to enter them.
-
-You can create an issue in many ways in GitLab:
-
-- [From a project](#from-a-project)
-- [From a group](#from-a-group)
-- [From another issue or incident](#from-another-issue-or-incident)
-- [From an issue board](#from-an-issue-board)
-- [By sending an email](#by-sending-an-email)
-- [Using a URL with prefilled values](#using-a-url-with-prefilled-values)
-- [Using Service Desk](#using-service-desk)
-
-### From a project
-
-Prerequisites:
-
-- You must have at least the Guest role for the project.
-
-To create an issue:
-
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. Either:
-
- - On the left sidebar, select **Issues**, and then, in the top right corner, select **New issue**.
- - On the top bar, select the plus sign (**{plus-square}**) and then, under **This project**,
- select **New issue**.
-
-1. Complete the [fields](#fields-in-the-new-issue-form).
-1. Select **Create issue**.
-
-The newly created issue opens.
-
-### From a group
-
-Issues belong to projects, but when you're in a group, you can access and create issues that belong
-to the projects in the group.
-
-Prerequisites:
-
-- You must have at least the Guest role for the project in the group.
-
-To create an issue from a group:
-
-1. On the top bar, select **Main menu > Groups** and find your group.
-1. On the left sidebar, select **Issues**.
-1. In the top right corner, select **Select project to create issue**.
-1. Select the project you'd like to create an issue for. The button now reflects the selected
- project.
-1. Select **New issue in `<project name>`**.
-1. Complete the [fields](#fields-in-the-new-issue-form).
-1. Select **Create issue**.
-
-The newly created issue opens.
-
-The project you selected most recently becomes the default for your next visit.
-This can save you a lot of time, if you mostly create issues for the same project.
-
-### From another issue or incident
-
-> - New issue becoming linked to the issue of origin [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68226) in GitLab 14.3.
-> - **Relate to…** checkbox [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198494) in GitLab 14.9.
-
-You can create a new issue from an existing one. The two issues can then be marked as related.
-
-Prerequisites:
-
-- You must have at least the Guest role for the project.
-
-To create an issue from another issue:
-
-1. In an existing issue, select the vertical ellipsis (**{ellipsis_v}**).
-1. Select **New related issue**.
-1. Complete the [fields](#fields-in-the-new-issue-form).
- The new issue form has a **Relate to issue #123** checkbox, where `123` is the ID of the
- issue of origin. If you keep this checkbox checked, the two issues become
- [linked](related_issues.md).
-1. Select **Create issue**.
-
-The newly created issue opens.
-
-### From an issue board
-
-You can create a new issue from an [issue board](../issue_board.md).
-
-Prerequisites:
-
-- You must have at least the Guest role for the project.
-
-To create an issue from a project issue board:
-
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. Select **Issues > Boards**.
-1. At the top of a board list, select **New issue** (**{plus-square}**).
-1. Enter the issue's title.
-1. Select **Create issue**.
-
-To create an issue from a group issue board:
-
-1. On the top bar, select **Main menu > Groups** and find your group.
-1. Select **Issues > Boards**.
-1. At the top of a board list, select **New issue** (**{plus-square}**).
-1. Enter the issue's title.
-1. Under **Projects**, select the project in the group that the issue should belong to.
-1. Select **Create issue**.
-
-The issue is created and shows up in the board list. It shares the list's characteristic, so, for
-example, if the list is scoped to a label `Frontend`, the new issue also has this label.
-
-### By sending an email
-
-> - Generated email address format changed in GitLab 11.7.
-> - The older format is still supported, so existing aliases and contacts still work.
-
-You can send an email to create an issue in a project on the project's
-**Issues List** page.
-
-Prerequisites:
-
-- Your GitLab instance must have [incoming email](../../../administration/incoming_email.md)
- configured.
-- There must be at least one issue in the issue list.
-- You must have at least the Guest role for the project.
-
-To email an issue to a project:
-
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. Select **Issues**.
-1. At the bottom of the page, select **Email a new issue to this project**.
-1. To copy the email address, select **Copy** (**{copy-to-clipboard}**).
-1. From your email client, send an email to this address.
- The subject is used as the title of the new issue, and the email body becomes the description.
- You can use [Markdown](../../markdown.md) and [quick actions](../quick_actions.md).
-
-A new issue is created, with your user as the author.
-You can save this address as a contact in your email client to use it again.
-
-WARNING:
-The email address you see is a private email address, generated just for you.
-**Keep it to yourself**, because anyone who knows it can create issues or merge requests as if they
-were you.
-
-To regenerate the email address:
-
-1. On the issues list, select **Email a new issue to this project**.
-1. Select **reset this token**.
-
-### Using a URL with prefilled values
-
-> - Ability to use both `issuable_template` and `issue[description]` in the same URL [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80554) in GitLab 14.9.
-> - Ability to specify `add_related_issue` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198494) in GitLab 14.9.
-
-To link directly to the new issue page with prefilled fields, use query
-string parameters in a URL. You can embed a URL in an external
-HTML page to create issues with certain fields prefilled.
-
-| Field | URL parameter | Notes |
-| -------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
-| Title | `issue[title]` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
-| Issue type | `issue[issue_type]` | Either `incident` or `issue`. |
-| Description template | `issuable_template` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
-| Description | `issue[description]` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). If used in combination with `issuable_template` or a [default issue template](../description_templates.md#set-a-default-template-for-merge-requests-and-issues), the `issue[description]` value is appended to the template. |
-| Confidential | `issue[confidential]` | If `true`, the issue is marked as confidential. |
-| Relate to… | `add_related_issue` | A numeric issue ID. If present, the issue form shows a [**Relate to…** checkbox](#from-another-issue-or-incident) to optionally link the new issue to the specified existing issue. |
-
-Adapt these examples to form your new issue URL with prefilled fields.
-To create an issue in the GitLab project:
-
-- With a prefilled title and description:
-
- ```plaintext
- https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Whoa%2C%20we%27re%20half-way%20there&issue[description]=Whoa%2C%20livin%27%20in%20a%20URL
- ```
-
-- With a prefilled title and description template:
-
- ```plaintext
- https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Validate%20new%20concept&issuable_template=Feature%20Proposal%20-%20basic
- ```
-
-- With a prefilled title, description, and marked as confidential:
-
- ```plaintext
- https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Validate%20new%20concept&issue[description]=Research%20idea&issue[confidential]=true
- ```
-
-### Using Service Desk
-
-To offer email support, enable [Service Desk](../service_desk.md) for your project.
-
-Now, when your customer sends a new email, a new issue can be created in
-the appropriate project and followed up from there.
-
-### Fields in the new issue form
-
-> - Adding the new issue to an epic [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13847) in GitLab 13.1.
-> - Iteration field [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233517) in GitLab 15.6.
-
-When you're creating a new issue, you can complete the following fields:
-
-- Title
-- Type: either issue (default) or incident
-- [Description template](../description_templates.md): overwrites anything in the Description text box
-- Description: you can use [Markdown](../../markdown.md) and [quick actions](../quick_actions.md)
-- Checkbox to make the issue [confidential](confidential_issues.md)
-- [Assignees](#assignee)
-- [Weight](issue_weight.md)
-- [Epic](../../group/epics/index.md)
-- [Due date](due_dates.md)
-- [Milestone](../milestones/index.md)
-- [Labels](../labels.md)
-- [Iteration](../../group/iterations/index.md)
+After you create an issue, you can start working with it.
## Edit an issue
@@ -239,27 +22,7 @@ To edit an issue:
1. Edit the available fields.
1. Select **Save changes**.
-### Reorder list items in the issue description
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15260) in GitLab 15.0.
-
-When you view an issue that has a list in the description, you can also reorder the list items.
-
-Prerequisites:
-
-- You must have at least the Reporter role for the project, be the author of the issue, or be
- assigned to the issue.
-- The issue's description must have an [ordered, unordered](../../markdown.md#lists), or
- [task](../../markdown.md#task-lists) list.
-
-To reorder list items, when viewing an issue:
-
-1. Hover over the list item row to make the drag icon (**{drag-vertical}**) visible.
-1. Select and hold the drag icon.
-1. Drag the row to the new position in the list.
-1. Release the drag icon.
-
-### Bulk edit issues from a project
+## Bulk edit issues from a project
> - Assigning epic [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210470) in GitLab 13.2.
> - Editing health status [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218395) in GitLab 13.2.
@@ -283,7 +46,7 @@ To edit multiple issues at the same time:
When bulk editing issues in a project, you can edit the following attributes:
- Status (open or closed)
-- [Assignees](#assignee)
+- [Assignees](managing_issues.md#assignee)
- [Epic](../../group/epics/index.md)
- [Milestone](../milestones/index.md)
- [Labels](../labels.md)
@@ -396,6 +159,26 @@ To do it:
1. To exit the Rails console, enter `quit`.
+## Reorder list items in the issue description
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15260) in GitLab 15.0.
+
+When you view an issue that has a list in the description, you can also reorder the list items.
+
+Prerequisites:
+
+- You must have at least the Reporter role for the project, be the author of the issue, or be
+ assigned to the issue.
+- The issue's description must have an [ordered, unordered](../../markdown.md#lists), or
+ [task](../../markdown.md#task-lists) list.
+
+To reorder list items, when viewing an issue:
+
+1. Hover over the list item row to make the drag icon (**{drag-vertical}**) visible.
+1. Select and hold the drag icon.
+1. Drag the row to the new position in the list.
+1. Release the drag icon.
+
## Close an issue
When you decide that an issue is resolved or no longer needed, you can close it.
diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md
index 73c255f19d5..b9887212be0 100644
--- a/doc/user/project/members/share_project_with_groups.md
+++ b/doc/user/project/members/share_project_with_groups.md
@@ -17,14 +17,14 @@ When a project is shared with a group:
- All group members, including members of subgroups or projects that belong to the group,
are assigned the same role in the project.
-This role is displayed in the Max role column of the Project members list.
+Each member's role is displayed in **Project information > Members > Max role**.
- The group is listed in the **Groups** tab.
- The project is listed on the group dashboard.
-Be aware of the restrictions that apply when sharing projects with:
+Be aware of the restrictions that apply when you share projects with:
- [Groups with a more restrictive visibility level](#share-projects-with-groups-with-a-more-restrictive-visibility-level).
-- [Group lock](#share-project-with-group-lock).
+- [Restricted sharing](#prevent-project-sharing).
## Share projects with groups with a more restrictive visibility level
@@ -41,7 +41,7 @@ For example, you can share:
This restriction applies to subgroups as well. For example, `group/subgroup01/project`:
-- Can not be shared with `group`.
+- Can't be shared with `group`.
- Can be shared with `group/subgroup02` or `group/subgroup01/subgroup03`.
When you share a project with a group that has a more restrictive visibility level than the project:
@@ -51,7 +51,7 @@ When you share a project with a group that has a more restrictive visibility lev
- Project members who are direct or indirect members of the group can see
group members listed in addition to members of the project.
-## Share a project with a group of users
+## Share a project with a group
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 from a form to a modal
window [with a flag](../../feature_flags.md). Disabled by default.
@@ -76,10 +76,10 @@ To share a project with a group:
1. Optional. Select an **Access expiration date**.
1. Select **Invite**.
-## Share project with group lock
+## Prevent project sharing
-It is possible to prevent projects in a group from
+You can prevent members of a group from
[sharing a project with another group](../members/share_project_with_groups.md).
-This allows for tighter control over project access.
+This restriction allows for tighter control over project access.
-Learn more about [Share with group lock](../../group/access_and_permissions.md#prevent-a-project-from-being-shared-with-groups).
+For more information, see [Prevent a project from being shared with groups](../../group/access_and_permissions.md#prevent-a-project-from-being-shared-with-groups).
diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md
index e09a1318981..5f81db10cf4 100644
--- a/doc/user/project/merge_requests/approvals/rules.md
+++ b/doc/user/project/merge_requests/approvals/rules.md
@@ -182,7 +182,7 @@ granting them push access:
1. [Create a new group](../../../group/manage.md#create-a-group).
1. [Add the user to the group](../../../group/manage.md#add-users-to-a-group),
and select the Reporter role for the user.
-1. [Share the project with your group](../../members/share_project_with_groups.md#share-a-project-with-a-group-of-users),
+1. [Share the project with your group](../../members/share_project_with_groups.md#share-a-project-with-a-group),
based on the Reporter role.
1. Go to your project and select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval rules**, and either:
diff --git a/jest.config.base.js b/jest.config.base.js
index 77267f7375e..de9bff774e1 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -1,6 +1,7 @@
const IS_EE = require('./config/helpers/is_ee_env');
const isESLint = require('./config/helpers/is_eslint');
const IS_JH = require('./config/helpers/is_jh_env');
+const { TEST_HOST } = require('./spec/frontend/__helpers__/test_constants');
module.exports = (path, options = {}) => {
const {
@@ -156,6 +157,7 @@ module.exports = (path, options = {}) => {
'dateformat',
'lowlight',
'vscode-languageserver-types',
+ 'yaml',
...gfmParserDependencies,
];
@@ -186,11 +188,16 @@ module.exports = (path, options = {}) => {
'^.+\\.(md|zip|png|yml|yaml)$': './spec/frontend/__helpers__/raw_transformer.js',
},
transformIgnorePatterns: [`node_modules/(?!(${transformIgnoreNodeModules.join('|')}))`],
- timers: 'legacy',
+ fakeTimers: {
+ enableGlobally: true,
+ doNotFake: ['nextTick', 'setImmediate'],
+ legacyFakeTimers: true,
+ },
testEnvironment: '<rootDir>/spec/frontend/environment.js',
testEnvironmentOptions: {
IS_EE,
IS_JH,
+ url: TEST_HOST,
},
testRunner: 'jest-jasmine2',
};
diff --git a/jest.config.integration.js b/jest.config.integration.js
index e2ce32218e0..0693a500990 100644
--- a/jest.config.integration.js
+++ b/jest.config.integration.js
@@ -24,6 +24,8 @@ module.exports = {
'^jh_else_ce_test_helpers(/.*)$': '<rootDir>/jh/spec/frontend_integration/test_helpers$1',
},
}),
- timers: 'real',
+ fakeTimers: {
+ enableGlobally: false,
+ },
testTimeout: process.env.CI ? 20000 : 7000,
};
diff --git a/lib/api/ci/jobs.rb b/lib/api/ci/jobs.rb
index 87d41b93851..bb57a717f7c 100644
--- a/lib/api/ci/jobs.rb
+++ b/lib/api/ci/jobs.rb
@@ -49,6 +49,8 @@ module API
end
# rubocop: disable CodeReuse/ActiveRecord
get ':id/jobs', urgency: :low, feature_category: :continuous_integration do
+ check_rate_limit!(:jobs_index, scope: current_user) if enforce_jobs_api_rate_limits(@project)
+
authorize_read_builds!
builds = user_project.builds.order('id DESC')
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 86763b2cd67..0b5a471ea12 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -167,6 +167,10 @@ module API
current_authenticated_job.project == project
end
+ def enforce_jobs_api_rate_limits(project)
+ ::Feature.enabled?(:ci_enforce_rate_limits_jobs_api, project)
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def find_group(id)
if id.to_s =~ INTEGER_ID_REGEX
diff --git a/lib/api/integrations/jira_connect/subscriptions.rb b/lib/api/integrations/jira_connect/subscriptions.rb
index 7b959893360..cc2199e0ef6 100644
--- a/lib/api/integrations/jira_connect/subscriptions.rb
+++ b/lib/api/integrations/jira_connect/subscriptions.rb
@@ -27,8 +27,6 @@ module API
requires :namespace_path, type: String, desc: 'Path for the namespace that should be subscribed'
end
post do
- not_found! unless Feature.enabled?(:jira_connect_oauth, current_user)
-
jwt = Atlassian::JiraConnect::Jwt::Symmetric.new(params[:jwt])
installation = JiraConnectInstallation.find_by_client_key(jwt.iss_claim)
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index 1e4bacd2960..5b1bf99e297 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -54,7 +54,8 @@ module Gitlab
phone_verification_send_code: { threshold: 10, interval: 1.hour },
phone_verification_verify_code: { threshold: 10, interval: 10.minutes },
namespace_exists: { threshold: 20, interval: 1.minute },
- fetch_google_ip_list: { threshold: 10, interval: 1.minute }
+ fetch_google_ip_list: { threshold: 10, interval: 1.minute },
+ jobs_index: { threshold: 600, interval: 1.minute }
}.freeze
end
diff --git a/lib/gitlab/ci/build/context/build.rb b/lib/gitlab/ci/build/context/build.rb
index a1a8e9288c7..1025e1cc2d7 100644
--- a/lib/gitlab/ci/build/context/build.rb
+++ b/lib/gitlab/ci/build/context/build.rb
@@ -9,25 +9,29 @@ module Gitlab
attr_reader :attributes
- def initialize(pipeline, attributes = {})
+ def initialize(pipeline, attributes = {}, build = nil)
super(pipeline)
+ @build = build
@attributes = attributes
end
def variables
- strong_memoize(:variables) do
- # This is a temporary piece of technical debt to allow us access
- # to the CI variables to evaluate rules before we persist a Build
- # with the result. We should refactor away the extra Build.new,
- # but be able to get CI Variables directly from the Seed::Build.
- stub_build.scoped_variables
- end
+ build.scoped_variables
end
+ strong_memoize_attr :variables
private
+ def build
+ @build || stub_build
+ end
+
def stub_build
+ # This is a temporary piece of technical debt to allow us access
+ # to the CI variables to evaluate rules before we persist a Build
+ # with the result. We should refactor away the extra Build.new,
+ # but be able to get CI Variables directly from the Seed::Build.
::Ci::Build.new(build_attributes)
end
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index 2e4267e986b..440f4af0296 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -9,12 +9,13 @@ module Gitlab
delegate :dig, to: :@seed_attributes
- def initialize(context, attributes, stages_for_needs_lookup = [])
+ def initialize(context, attributes, stages_for_needs_lookup, stage)
@context = context
@pipeline = context.pipeline
@seed_attributes = attributes
@stages_for_needs_lookup = stages_for_needs_lookup.compact
@needs_attributes = dig(:needs_attributes)
+ @stage = stage
@resource_group_key = attributes.delete(:resource_group_key)
@job_variables = @seed_attributes.delete(:job_variables)
@root_variables_inheritance = @seed_attributes.delete(:root_variables_inheritance) { true }
@@ -33,6 +34,8 @@ module Gitlab
.new(attributes.delete(:cache), @pipeline)
calculate_yaml_variables!
+
+ @processable = initialize_processable
end
def name
@@ -40,36 +43,41 @@ module Gitlab
end
def included?
- strong_memoize(:inclusion) do
- logger.instrument(:pipeline_seed_build_inclusion) do
- if @using_rules
- rules_result.pass?
- elsif @using_only || @using_except
- all_of_only? && none_of_except?
- else
- true
- end
+ logger.instrument(:pipeline_seed_build_inclusion) do
+ if @using_rules
+ rules_result.pass?
+ elsif @using_only || @using_except
+ all_of_only? && none_of_except?
+ else
+ true
end
end
end
+ strong_memoize_attr :included?, :inclusion
def errors
- strong_memoize(:errors) do
- # We check rules errors before checking "included?" because rules affects its inclusion status.
- next rules_errors if rules_errors
- next unless included?
+ # We check rules errors before checking "included?" because rules affects its inclusion status.
+ return rules_errors if rules_errors
+ return unless included?
- [needs_errors, variable_expansion_errors].compact.flatten
- end
+ [needs_errors, variable_expansion_errors].compact.flatten
end
+ strong_memoize_attr :errors
+ # TODO: Method used only in specs. Replace with `to_resource.attributes` when
+ # the feature flag ci_reuse_build_in_seed_context is removed.
+ # Then remove this method.
def attributes
- @seed_attributes
- .deep_merge(pipeline_attributes)
- .deep_merge(rules_attributes)
- .deep_merge(allow_failure_criteria_attributes)
- .deep_merge(@cache.cache_attributes)
- .deep_merge(runner_tags)
+ if reuse_build_in_seed_context?
+ initial_attributes.deep_merge(evaluated_attributes)
+ else
+ @seed_attributes
+ .deep_merge(pipeline_attributes)
+ .deep_merge(rules_attributes)
+ .deep_merge(allow_failure_criteria_attributes)
+ .deep_merge(@cache.cache_attributes)
+ .deep_merge(runner_tags)
+ end
end
def bridge?
@@ -80,12 +88,28 @@ module Gitlab
end
def to_resource
- strong_memoize(:resource) do
- initialize_processable
+ if reuse_build_in_seed_context?
+ # The `options` attribute need to be entirely reassigned because they may
+ # be overridden by evaluated_attributes.
+ # We also don't want to reassign all the `initial_attributes` since those
+ # can affect performance. We only want to assign what's changed.
+ assignable_attributes = initial_attributes.slice(:options)
+ .deep_merge(evaluated_attributes)
+ processable.assign_attributes(assignable_attributes)
+ processable
+ else
+ legacy_initialize_processable
end
end
+ strong_memoize_attr :to_resource
- def initialize_processable
+ private
+
+ attr_reader :processable
+
+ delegate :logger, to: :@context
+
+ def legacy_initialize_processable
if bridge?
::Ci::Bridge.new(attributes)
else
@@ -93,9 +117,28 @@ module Gitlab
end
end
- private
+ def initialize_processable
+ return unless reuse_build_in_seed_context?
- delegate :logger, to: :@context
+ if bridge?
+ ::Ci::Bridge.new(initial_attributes)
+ else
+ ::Ci::Build.new(initial_attributes)
+ end
+ end
+
+ def initial_attributes
+ @seed_attributes
+ .deep_merge(pipeline_attributes)
+ .deep_merge(ci_stage: @stage)
+ .deep_merge(@cache.cache_attributes)
+ end
+
+ def evaluated_attributes
+ rules_attributes
+ .deep_merge(allow_failure_criteria_attributes)
+ .deep_merge(runner_tags)
+ end
def all_of_only?
@only.all? { |spec| spec.satisfied_by?(@pipeline, evaluate_context) }
@@ -155,40 +198,39 @@ module Gitlab
end
def rules_attributes
- strong_memoize(:rules_attributes) do
- next {} unless @using_rules
+ return {} unless @using_rules
- rules_variables_result = ::Gitlab::Ci::Variables::Helpers.merge_variables(
- @seed_attributes[:yaml_variables], rules_result.variables
- )
+ rules_variables_result = ::Gitlab::Ci::Variables::Helpers.merge_variables(
+ @seed_attributes[:yaml_variables], rules_result.variables
+ )
- rules_result.build_attributes.merge(yaml_variables: rules_variables_result)
- end
+ rules_result.build_attributes.merge(yaml_variables: rules_variables_result)
end
+ strong_memoize_attr :rules_attributes
def rules_result
- strong_memoize(:rules_result) do
- @rules.evaluate(@pipeline, evaluate_context)
- end
+ @rules.evaluate(@pipeline, evaluate_context)
end
+ strong_memoize_attr :rules_result
def rules_errors
- strong_memoize(:rules_errors) do
- ["Failed to parse rule for #{name}: #{rules_result.errors.join(', ')}"] if rules_result.errors.present?
- end
+ ["Failed to parse rule for #{name}: #{rules_result.errors.join(', ')}"] if rules_result.errors.present?
end
+ strong_memoize_attr :rules_errors
def evaluate_context
- strong_memoize(:evaluate_context) do
+ if reuse_build_in_seed_context?
+ Gitlab::Ci::Build::Context::Build.new(@pipeline, @seed_attributes, processable)
+ else
Gitlab::Ci::Build::Context::Build.new(@pipeline, @seed_attributes)
end
end
+ strong_memoize_attr :evaluate_context
def runner_tags
- strong_memoize(:runner_tags) do
- { tag_list: evaluate_runner_tags }.compact
- end
+ { tag_list: evaluate_runner_tags }.compact
end
+ strong_memoize_attr :runner_tags
def evaluate_runner_tags
@seed_attributes.delete(:tag_list)&.map do |tag|
@@ -211,6 +253,11 @@ module Gitlab
from: @context.root_variables, to: @job_variables, inheritance: @root_variables_inheritance
)
end
+
+ def reuse_build_in_seed_context?
+ Feature.enabled?(:ci_reuse_build_in_seed_context, @pipeline.project)
+ end
+ strong_memoize_attr :reuse_build_in_seed_context?, :reuse_build_in_seed_context
end
end
end
diff --git a/lib/gitlab/ci/pipeline/seed/stage.rb b/lib/gitlab/ci/pipeline/seed/stage.rb
index 1c4247bd5ee..c3e94529634 100644
--- a/lib/gitlab/ci/pipeline/seed/stage.rb
+++ b/lib/gitlab/ci/pipeline/seed/stage.rb
@@ -10,54 +10,49 @@ module Gitlab
delegate :size, to: :seeds
delegate :dig, to: :seeds
- def initialize(context, attributes, previous_stages)
- @context = context
- @pipeline = context.pipeline
- @attributes = attributes
- @previous_stages = previous_stages
-
- @builds = attributes.fetch(:builds).map do |attributes|
- Seed::Build.new(context, attributes, previous_stages + [self])
+ attr_reader :attributes
+
+ def initialize(context, stage_attributes, previous_stages)
+ pipeline = context.pipeline
+ @attributes = {
+ name: stage_attributes.fetch(:name),
+ position: stage_attributes.fetch(:index),
+ pipeline: pipeline,
+ project: pipeline.project,
+ partition_id: pipeline.partition_id
+ }
+
+ @stage = ::Ci::Stage.new(@attributes)
+
+ @builds = stage_attributes.fetch(:builds).map do |build_attributes|
+ Seed::Build.new(context, build_attributes, previous_stages + [self], @stage)
end
end
- def attributes
- { name: @attributes.fetch(:name),
- position: @attributes.fetch(:index),
- pipeline: @pipeline,
- project: @pipeline.project,
- partition_id: @pipeline.partition_id }
- end
-
def seeds
- strong_memoize(:seeds) do
- @builds.select(&:included?)
- end
+ @builds.select(&:included?)
end
+ strong_memoize_attr :seeds
def errors
- strong_memoize(:errors) do
- @builds.flat_map(&:errors).compact
- end
+ @builds.flat_map(&:errors).compact
end
+ strong_memoize_attr :errors
def seeds_names
- strong_memoize(:seeds_names) do
- seeds.map(&:name).to_set
- end
+ seeds.map(&:name).to_set
end
+ strong_memoize_attr :seeds_names
def included?
seeds.any?
end
def to_resource
- strong_memoize(:stage) do
- ::Ci::Stage.new(attributes).tap do |stage|
- stage.statuses = seeds.map(&:to_resource)
- end
- end
+ @stage.statuses = seeds.map(&:to_resource)
+ @stage
end
+ strong_memoize_attr :to_resource
end
end
end
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index f8bca3d22d9..7a42ffca779 100644
--- a/lib/gitlab/i18n.rb
+++ b/lib/gitlab/i18n.rb
@@ -50,24 +50,24 @@ module Gitlab
'eo' => 0,
'es' => 35,
'fil_PH' => 0,
- 'fr' => 85,
+ 'fr' => 94,
'gl_ES' => 0,
'id_ID' => 0,
'it' => 1,
'ja' => 30,
- 'ko' => 21,
- 'nb_NO' => 25,
+ 'ko' => 20,
+ 'nb_NO' => 24,
'nl_NL' => 0,
'pl_PL' => 3,
- 'pt_BR' => 58,
- 'ro_RO' => 98,
- 'ru' => 25,
+ 'pt_BR' => 57,
+ 'ro_RO' => 96,
+ 'ru' => 26,
'si_LK' => 11,
'tr_TR' => 11,
'uk' => 52,
- 'zh_CN' => 98,
+ 'zh_CN' => 97,
'zh_HK' => 1,
- 'zh_TW' => 100
+ 'zh_TW' => 99
}.freeze
private_constant :TRANSLATION_LEVELS
diff --git a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml
index 0bd809f8aa5..7cd19ec60d6 100644
--- a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml
+++ b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml
@@ -256,7 +256,6 @@
redis_slot: code_review
category: code_review
aggregation: weekly
- feature_flag: usage_data_diff_searches
- name: i_code_review_total_suggestions_applied
redis_slot: code_review
category: code_review
diff --git a/lib/tasks/gitlab/feature_categories.rake b/lib/tasks/gitlab/feature_categories.rake
new file mode 100644
index 00000000000..cecfaf3cb36
--- /dev/null
+++ b/lib/tasks/gitlab/feature_categories.rake
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+namespace :gitlab do
+ namespace :feature_categories do
+ desc 'GitLab | Feature categories | Build index page for groups'
+ task index: :environment do
+ require 'pathname'
+
+ controller_actions = Gitlab::RequestEndpoints
+ .all_controller_actions
+ .each_with_object({}) do |(controller, action), hash|
+ feature_category = controller.feature_category_for_action(action).to_s
+
+ hash[feature_category] ||= []
+ hash[feature_category] << {
+ klass: controller.to_s,
+ action: action,
+ source_location: source_location(controller, action)
+ }
+ end
+
+ endpoints = Gitlab::RequestEndpoints.all_api_endpoints.each_with_object({}) do |route, hash|
+ klass = route.app.options[:for]
+ path = API::Base.path_for_app(route.app)
+ feature_category = klass.feature_category_for_action(path).to_s
+
+ hash[feature_category] ||= []
+ hash[feature_category] << {
+ klass: klass.to_s,
+ action: path,
+ source_location: source_location(klass)
+ }
+ end
+
+ workers = Gitlab::SidekiqConfig.workers_for_all_queues_yml.flatten.each_with_object({}) do |worker, hash|
+ feature_category = worker.get_feature_category.to_s
+
+ next unless worker.klass.name
+
+ hash[feature_category] ||= []
+ hash[feature_category] << {
+ klass: worker.klass.name,
+ source_location: source_location(worker.klass.name)
+ }
+ end
+
+ database_tables = Dir['db/docs/*.yml'].each_with_object({}) do |file, hash|
+ yaml = YAML.safe_load(File.read(file))
+ table_name = yaml['table_name']
+
+ yaml['feature_categories'].each do |feature_category|
+ hash[feature_category] ||= []
+ hash[feature_category] << table_name
+ end
+ end
+
+ puts YAML.dump('controller_actions' => controller_actions,
+ 'api_endpoints' => endpoints,
+ 'sidekiq_workers' => workers,
+ 'database_tables' => database_tables)
+ end
+
+ def source_location(klass, method = nil)
+ file, line =
+ if method && klass.method_defined?(method)
+ klass.instance_method(method).source_location
+ else
+ Kernel.const_source_location(klass.to_s)
+ end
+
+ relative = Pathname.new(file).relative_path_from(Rails.root).to_s
+
+ if relative.starts_with?('../') || relative.starts_with?('/')
+ nil
+ else
+ [relative, line]
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5481b5142b5..3fe421ef573 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2755,6 +2755,9 @@ msgstr ""
msgid "AdminSettings|Auto DevOps domain"
msgstr ""
+msgid "AdminSettings|By default, set a limit to 0 to have no limit."
+msgstr ""
+
msgid "AdminSettings|CI/CD limits"
msgstr ""
@@ -2998,9 +3001,6 @@ msgstr ""
msgid "AdminSettings|Set a CI/CD template as the required pipeline configuration for all projects in the instance. Project CI/CD configuration merges into the required pipeline configuration when the pipeline runs. %{link_start}What is a required pipeline configuration?%{link_end}"
msgstr ""
-msgid "AdminSettings|Set limit to 0 to disable it."
-msgstr ""
-
msgid "AdminSettings|Set the expiration time of authentication tokens of newly registered group runners."
msgstr ""
@@ -3046,6 +3046,9 @@ msgstr ""
msgid "AdminSettings|There are Advanced Search migrations pending that require indexing to pause. Indexing must remain paused until GitLab completes the migrations."
msgstr ""
+msgid "AdminSettings|This limit cannot be disabled. Set to 0 to block all DAG dependencies."
+msgstr ""
+
msgid "AdminSettings|To enable Registration Features, first enable Service Ping."
msgstr ""
@@ -23423,6 +23426,9 @@ msgstr ""
msgid "JiraService|Change GitLab version"
msgstr ""
+msgid "JiraService|Continue setup in GitLab"
+msgstr ""
+
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
@@ -23471,6 +23477,9 @@ msgstr ""
msgid "JiraService|If different from Web URL."
msgstr ""
+msgid "JiraService|In order to complete the set up, you’ll need to complete a few steps in GitLab."
+msgstr ""
+
msgid "JiraService|Issues created from vulnerabilities in this project will be Jira issues, even if GitLab issues are enabled."
msgstr ""
@@ -41383,6 +41392,9 @@ msgstr ""
msgid "The name of the Jenkins project. Copy the name from the end of the URL to the project."
msgstr ""
+msgid "The new Web IDE"
+msgstr ""
+
msgid "The number of changes to fetch from GitLab when cloning a repository. Lower values can speed up pipeline execution. Set to %{code_open}0%{code_close} or blank to fetch all branches and tags for each job"
msgstr ""
@@ -43633,13 +43645,13 @@ msgstr ""
msgid "Try grouping with different labels"
msgstr ""
-msgid "Try logging in using your username or email. If you have forgotten your password, try recovering it"
+msgid "Try it out now"
msgstr ""
-msgid "Try out GitLab Pipelines"
+msgid "Try logging in using your username or email. If you have forgotten your password, try recovering it"
msgstr ""
-msgid "Try out the new Web IDE"
+msgid "Try out GitLab Pipelines"
msgstr ""
msgid "Try the troubleshooting steps here."
@@ -45111,7 +45123,7 @@ msgstr ""
msgid "Using the %{codeStart}needs%{codeEnd} keyword makes jobs run before their stage is reached. Jobs run as soon as their %{codeStart}needs%{codeEnd} relationships are met, which speeds up your pipelines."
msgstr ""
-msgid "VS Code in your browser. View code and make changes from the same UI as in your local IDE 🎉"
+msgid "VS Code in your browser. View code and make changes from the same UI as in your local IDE."
msgstr ""
msgid "Valid From"
diff --git a/package.json b/package.json
index c5a8f83a800..f1fe4b54d93 100644
--- a/package.json
+++ b/package.json
@@ -212,13 +212,13 @@
"@gitlab/stylelint-config": "4.1.0",
"@graphql-eslint/eslint-plugin": "3.12.0",
"@testing-library/dom": "^7.16.2",
- "@types/jest": "^27.5.1",
+ "@types/jest": "^28.1.3",
"@vue/test-utils": "1.3.0",
- "@vue/vue2-jest": "^27.0.0",
+ "@vue/vue2-jest": "^28.1.0",
"ajv": "^8.10.0",
"ajv-formats": "^2.1.1",
"axios-mock-adapter": "^1.15.0",
- "babel-jest": "^27.5.1",
+ "babel-jest": "^28.1.3",
"chalk": "^2.4.1",
"cheerio": "^1.0.0-rc.9",
"commander": "^2.20.3",
@@ -235,13 +235,13 @@
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-reports": "^3.0.0",
- "jest": "^27.5.1",
- "jest-canvas-mock": "^2.1.2",
- "jest-diff": "^27.5.1",
- "jest-environment-jsdom": "^27.5.1",
- "jest-jasmine2": "^27.5.1",
- "jest-junit": "^12.0.0",
- "jest-util": "^27.5.1",
+ "jest": "^28.1.3",
+ "jest-canvas-mock": "^2.4.0",
+ "jest-diff": "^28.1.3",
+ "jest-environment-jsdom": "^28.1.3",
+ "jest-jasmine2": "^28.1.3",
+ "jest-junit": "^12.3.0",
+ "jest-util": "^28.1.3",
"jsonlint": "^1.6.3",
"markdownlint-cli": "0.32.2",
"miragejs": "^0.1.40",
diff --git a/rubocop/cop/rspec/avoid_test_prof.rb b/rubocop/cop/rspec/avoid_test_prof.rb
new file mode 100644
index 00000000000..fb4b162f125
--- /dev/null
+++ b/rubocop/cop/rspec/avoid_test_prof.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'rubocop-rspec'
+
+module RuboCop
+ module Cop
+ module RSpec
+ # This cop checks for the usage of TestProf methods in migration specs.
+ #
+ # @example
+ #
+ # # bad
+ # let_it_be(:user) { table(:users).create(username: 'test') }
+ # let_it_be_with_reload(:user) { table(:users).create(username: 'test') }
+ # let_it_be_with_refind(:user) { table(:users).create(username: 'test') }
+ #
+ # before_all do
+ # do_something
+ # end
+ #
+ # # good
+ # let(:user) { table(:users).create(username: 'test') }
+ # let!(:user) { table(:users).create(username: 'test') }
+ #
+ # before(:all) do
+ # do_something
+ # end
+ #
+ # before do
+ # do_something
+ # end
+ class AvoidTestProf < RuboCop::Cop::Base
+ MESSAGE = "Prefer %{alternatives} over `%{method}` in migration specs. " \
+ 'See ' \
+ 'https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#testprof-in-migration-specs'
+
+ LET_ALTERNATIVES = %w[`let` `let!`].freeze
+ ALTERNATIVES = {
+ let_it_be: LET_ALTERNATIVES,
+ let_it_be_with_reload: LET_ALTERNATIVES,
+ let_it_be_with_refind: LET_ALTERNATIVES,
+ before_all: %w[`before` `before(:all)`]
+ }.freeze
+
+ FORBIDDEN_METHODS = ALTERNATIVES.keys.map(&:inspect).join(' ')
+ RESTRICT_ON_SEND = ALTERNATIVES.keys
+
+ def_node_matcher :forbidden_method_usage, <<~PATTERN
+ (send nil? ${#{FORBIDDEN_METHODS}} ...)
+ PATTERN
+
+ def on_send(node)
+ method = forbidden_method_usage(node)
+ return unless method
+
+ alternatives = ALTERNATIVES.fetch(method).join(' or ')
+
+ add_offense(
+ node,
+ message: format(MESSAGE, method: method, alternatives: alternatives)
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/scripts/review_apps/base-config.yaml b/scripts/review_apps/base-config.yaml
index b080e7f710c..f845dd04e8f 100644
--- a/scripts/review_apps/base-config.yaml
+++ b/scripts/review_apps/base-config.yaml
@@ -16,10 +16,6 @@ global:
secret: shared-gitlab-initial-root-password
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
certmanager:
install: false
@@ -37,10 +33,6 @@ gitlab:
storageClass: ssd
nodeSelector:
preemptible: "false"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-false
podAnnotations:
<<: *safe-to-evict
@@ -139,10 +131,6 @@ gitlab-runner:
memory: 150Mi
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
podAnnotations:
<<: *safe-to-evict
@@ -156,10 +144,6 @@ minio:
memory: 280Mi
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
podAnnotations:
<<: *safe-to-evict
@@ -182,10 +166,6 @@ nginx-ingress:
timeoutSeconds: 5
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
defaultBackend:
resources:
requests:
@@ -196,10 +176,6 @@ nginx-ingress:
memory: 24Mi
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
postgresql:
metrics:
@@ -214,10 +190,6 @@ postgresql:
master:
nodeSelector:
preemptible: "false"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-false
podAnnotations:
<<: *safe-to-evict
@@ -237,10 +209,6 @@ redis:
master:
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
podAnnotations:
<<: *safe-to-evict
@@ -257,7 +225,3 @@ registry:
memory: 45Mi
nodeSelector:
preemptible: "true"
- # TODO: Remove me as soon as the old nodepools are deleted
- #
- # See https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/issues/40
- cloud.google.com/gke-nodepool: containerd-preemptible-true
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 9c0712bba11..e4d4375a138 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe 'Commits', feature_category: :source_code_management do
set_cookie('new_repo', 'true')
visit project_commits_path(project, branch_name)
- expect(find('.js-project-refs-dropdown')).to have_content branch_name
+ expect(find('.ref-selector')).to have_content branch_name
end
end
diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb
index d3437b4af18..791f626b8d9 100644
--- a/spec/features/projects/commits/user_browses_commits_spec.rb
+++ b/spec/features/projects/commits/user_browses_commits_spec.rb
@@ -208,6 +208,10 @@ RSpec.describe 'User browses commits', feature_category: :source_code_management
expect(page).not_to have_link 'Create merge request'
end
+ it 'shows ref switcher with correct text', :js do
+ expect(find('.ref-selector')).to have_text('master')
+ end
+
context 'when click the compare tab' do
before do
wait_for_requests
@@ -220,9 +224,18 @@ RSpec.describe 'User browses commits', feature_category: :source_code_management
end
end
- context 'feature branch' do
+ context 'feature branch', :js do
let(:visit_commits_page) do
- visit project_commits_path(project, 'feature')
+ visit project_commits_path(project)
+
+ find('.ref-selector').click
+ wait_for_requests
+
+ page.within('.ref-selector') do
+ fill_in 'Search by Git revision', with: 'feature'
+ wait_for_requests
+ find('li', text: 'feature', match: :prefer_exact).click
+ end
end
context 'when project does not have open merge requests' do
@@ -230,6 +243,10 @@ RSpec.describe 'User browses commits', feature_category: :source_code_management
visit_commits_page
end
+ it 'shows ref switcher with correct text' do
+ expect(find('.ref-selector')).to have_text('feature')
+ end
+
it 'renders project commits' do
commit = project.repository.commit('0b4bc9a')
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index 8db522f9ac1..37973c9b8d6 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -165,7 +165,7 @@ RSpec.describe "Projects > Settings > Pipelines settings", feature_category: :pr
let(:page_token) { find('#registration_token').text }
before do
- click_button 'Reset registration token'
+ click_link 'Reset registration token'
end
it 'changes registration token' do
diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb
index 67d2aa1c82c..e2166854ba3 100644
--- a/spec/features/projects/show/user_interacts_with_stars_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe 'Projects > Show > User interacts with project stars', feature_ca
let(:user) { create(:user) }
before do
+ stub_feature_flags(vscode_web_ide: false)
sign_in(user)
visit(project_path(project))
end
diff --git a/spec/features/projects/show/user_manages_notifications_spec.rb b/spec/features/projects/show/user_manages_notifications_spec.rb
index a72d2ffc92b..8f6535fd4f0 100644
--- a/spec/features/projects/show/user_manages_notifications_spec.rb
+++ b/spec/features/projects/show/user_manages_notifications_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'Projects > Show > User manages notifications', :js, feature_cate
let(:project) { create(:project, :public, :repository) }
before do
+ stub_feature_flags(vscode_web_ide: false)
sign_in(project.first_owner)
end
diff --git a/spec/frontend/__helpers__/graphql_transformer.js b/spec/frontend/__helpers__/graphql_transformer.js
index e776e2ea6ac..f26b63dadfd 100644
--- a/spec/frontend/__helpers__/graphql_transformer.js
+++ b/spec/frontend/__helpers__/graphql_transformer.js
@@ -3,6 +3,8 @@ const loader = require('graphql-tag/loader');
module.exports = {
process(src) {
- return loader.call({ cacheable() {} }, src);
+ return {
+ code: loader.call({ cacheable() {} }, src),
+ };
},
};
diff --git a/spec/frontend/__helpers__/raw_transformer.js b/spec/frontend/__helpers__/raw_transformer.js
index 09101b7a64f..3b0bed14e8d 100644
--- a/spec/frontend/__helpers__/raw_transformer.js
+++ b/spec/frontend/__helpers__/raw_transformer.js
@@ -1,6 +1,6 @@
/* eslint-disable import/no-commonjs */
module.exports = {
process: (content) => {
- return `module.exports = ${JSON.stringify(content)}`;
+ return { code: `module.exports = ${JSON.stringify(content)}` };
},
};
diff --git a/spec/frontend/__helpers__/web_worker_transformer.js b/spec/frontend/__helpers__/web_worker_transformer.js
index 767ab3f5675..86be856f7b7 100644
--- a/spec/frontend/__helpers__/web_worker_transformer.js
+++ b/spec/frontend/__helpers__/web_worker_transformer.js
@@ -1,18 +1,22 @@
/* eslint-disable import/no-commonjs */
-const babelJestTransformer = require('babel-jest');
+const { createTransformer } = require('babel-jest');
// This Jest will transform the code of a WebWorker module into a FakeWebWorker subclass.
// This is meant to mirror Webpack's [`worker-loader`][1].
// [1]: https://webpack.js.org/loaders/worker-loader/
module.exports = {
process: (contentArg, filename, ...args) => {
- const { code: content } = babelJestTransformer.default.process(contentArg, filename, ...args);
+ const { code: content } = createTransformer().process(contentArg, filename, ...args);
- return `const { FakeWebWorker } = require("helpers/web_worker_fake");
+ const jestTransformedWorkerCode = `const { FakeWebWorker } = require("helpers/web_worker_fake");
module.exports = class JestTransformedWorker extends FakeWebWorker {
constructor() {
super(${JSON.stringify(filename)}, ${JSON.stringify(content)});
}
};`;
+
+ return {
+ code: jestTransformedWorkerCode,
+ };
},
};
diff --git a/spec/frontend/__helpers__/yaml_transformer.js b/spec/frontend/__helpers__/yaml_transformer.js
index a23f9b1f715..e0b4d01f542 100644
--- a/spec/frontend/__helpers__/yaml_transformer.js
+++ b/spec/frontend/__helpers__/yaml_transformer.js
@@ -6,6 +6,6 @@ module.exports = {
process: (sourceContent) => {
const jsonContent = JsYaml.load(sourceContent);
const json = JSON.stringify(jsonContent);
- return `module.exports = ${json}`;
+ return { code: `module.exports = ${json}` };
},
};
diff --git a/spec/frontend/ci/runner/components/runner_status_badge_spec.js b/spec/frontend/ci/runner/components/runner_status_badge_spec.js
index 7d3064c2aef..45b410df2d4 100644
--- a/spec/frontend/ci/runner/components/runner_status_badge_spec.js
+++ b/spec/frontend/ci/runner/components/runner_status_badge_spec.js
@@ -37,12 +37,12 @@ describe('RunnerTypeBadge', () => {
};
beforeEach(() => {
- jest.useFakeTimers('modern');
+ jest.useFakeTimers({ legacyFakeTimers: false });
jest.setSystemTime(new Date('2021-01-01T00:00:00Z'));
});
afterEach(() => {
- jest.useFakeTimers('legacy');
+ jest.useFakeTimers({ legacyFakeTimers: true });
wrapper.destroy();
});
diff --git a/spec/frontend/ci/runner/group_runners/group_runners_app_spec.js b/spec/frontend/ci/runner/group_runners/group_runners_app_spec.js
index c3493b3c9fd..1e5bb828dbf 100644
--- a/spec/frontend/ci/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/ci/runner/group_runners/group_runners_app_spec.js
@@ -448,13 +448,15 @@ describe('GroupRunnersApp', () => {
it('navigates to the next page', async () => {
await findRunnerPaginationNext().trigger('click');
- expect(mockGroupRunnersHandler).toHaveBeenLastCalledWith({
- groupFullPath: mockGroupFullPath,
- membership: MEMBERSHIP_DESCENDANTS,
- sort: CREATED_DESC,
- first: RUNNER_PAGE_SIZE,
- after: pageInfo.endCursor,
- });
+ expect(mockGroupRunnersHandler).toHaveBeenLastCalledWith(
+ expect.objectContaining({
+ groupFullPath: mockGroupFullPath,
+ membership: MEMBERSHIP_DESCENDANTS,
+ sort: CREATED_DESC,
+ first: RUNNER_PAGE_SIZE,
+ after: pageInfo.endCursor,
+ }),
+ );
});
});
diff --git a/spec/frontend/deploy_freeze/store/actions_spec.js b/spec/frontend/deploy_freeze/store/actions_spec.js
index ce0c924bed2..9b96ce5d252 100644
--- a/spec/frontend/deploy_freeze/store/actions_spec.js
+++ b/spec/frontend/deploy_freeze/store/actions_spec.js
@@ -4,7 +4,7 @@ import Api from '~/api';
import * as actions from '~/deploy_freeze/store/actions';
import * as types from '~/deploy_freeze/store/mutation_types';
import getInitialState from '~/deploy_freeze/store/state';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import * as logger from '~/lib/logger';
import axios from '~/lib/utils/axios_utils';
import { freezePeriodsFixture } from '../helpers';
@@ -99,8 +99,8 @@ describe('deploy freeze store actions', () => {
});
describe('addFreezePeriod', () => {
- it('dispatch correct actions on adding a freeze period', () => {
- testAction(
+ it('dispatch correct actions on adding a freeze period', async () => {
+ await testAction(
actions.addFreezePeriod,
{},
state,
@@ -110,32 +110,33 @@ describe('deploy freeze store actions', () => {
{ type: 'receiveFreezePeriodSuccess' },
{ type: 'fetchFreezePeriods' },
],
- () =>
- expect(Api.createFreezePeriod).toHaveBeenCalledWith(state.projectId, {
- freeze_start: state.freezeStartCron,
- freeze_end: state.freezeEndCron,
- cron_timezone: state.selectedTimezoneIdentifier,
- }),
);
+
+ expect(Api.createFreezePeriod).toHaveBeenCalledWith(state.projectId, {
+ freeze_start: state.freezeStartCron,
+ freeze_end: state.freezeEndCron,
+ cron_timezone: state.selectedTimezoneIdentifier,
+ });
});
- it('should show flash error and set error in state on add failure', () => {
+ it('should show alert and set error in state on add failure', async () => {
Api.createFreezePeriod.mockRejectedValue();
- testAction(
+ await testAction(
actions.addFreezePeriod,
{},
state,
[],
[{ type: 'requestFreezePeriod' }, { type: 'receiveFreezePeriodError' }],
- () => expect(createFlash).toHaveBeenCalled(),
);
+
+ expect(createAlert).toHaveBeenCalled();
});
});
describe('updateFreezePeriod', () => {
- it('dispatch correct actions on updating a freeze period', () => {
- testAction(
+ it('dispatch correct actions on updating a freeze period', async () => {
+ await testAction(
actions.updateFreezePeriod,
{},
state,
@@ -145,33 +146,34 @@ describe('deploy freeze store actions', () => {
{ type: 'receiveFreezePeriodSuccess' },
{ type: 'fetchFreezePeriods' },
],
- () =>
- expect(Api.updateFreezePeriod).toHaveBeenCalledWith(state.projectId, {
- id: state.selectedId,
- freeze_start: state.freezeStartCron,
- freeze_end: state.freezeEndCron,
- cron_timezone: state.selectedTimezoneIdentifier,
- }),
);
+
+ expect(Api.updateFreezePeriod).toHaveBeenCalledWith(state.projectId, {
+ id: state.selectedId,
+ freeze_start: state.freezeStartCron,
+ freeze_end: state.freezeEndCron,
+ cron_timezone: state.selectedTimezoneIdentifier,
+ });
});
- it('should show flash error and set error in state on add failure', () => {
+ it('should show alert and set error in state on add failure', async () => {
Api.updateFreezePeriod.mockRejectedValue();
- testAction(
+ await testAction(
actions.updateFreezePeriod,
{},
state,
[],
[{ type: 'requestFreezePeriod' }, { type: 'receiveFreezePeriodError' }],
- () => expect(createFlash).toHaveBeenCalled(),
);
+
+ expect(createAlert).toHaveBeenCalled();
});
});
describe('fetchFreezePeriods', () => {
it('dispatch correct actions on fetchFreezePeriods', () => {
- testAction(
+ return testAction(
actions.fetchFreezePeriods,
{},
state,
@@ -183,26 +185,26 @@ describe('deploy freeze store actions', () => {
);
});
- it('should show flash error and set error in state on fetch variables failure', () => {
+ it('should show alert and set error in state on fetch variables failure', async () => {
Api.freezePeriods.mockRejectedValue();
- testAction(
+ await testAction(
actions.fetchFreezePeriods,
{},
state,
[{ type: types.REQUEST_FREEZE_PERIODS }],
[],
- () =>
- expect(createFlash).toHaveBeenCalledWith({
- message: 'There was an error fetching the deploy freezes.',
- }),
);
+
+ expect(createAlert).toHaveBeenCalledWith({
+ message: 'There was an error fetching the deploy freezes.',
+ });
});
});
describe('deleteFreezePeriod', () => {
- it('dispatch correct actions on deleting a freeze period', () => {
- testAction(
+ it('dispatch correct actions on deleting a freeze period', async () => {
+ await testAction(
actions.deleteFreezePeriod,
freezePeriodFixture,
state,
@@ -211,20 +213,17 @@ describe('deploy freeze store actions', () => {
{ type: 'RECEIVE_DELETE_FREEZE_PERIOD_SUCCESS', payload: freezePeriodFixture.id },
],
[],
- () =>
- expect(Api.deleteFreezePeriod).toHaveBeenCalledWith(
- state.projectId,
- freezePeriodFixture.id,
- ),
);
+
+ expect(Api.deleteFreezePeriod).toHaveBeenCalledWith(state.projectId, freezePeriodFixture.id);
});
- it('should show flash error and set error in state on delete failure', () => {
+ it('should show alert and set error in state on delete failure', async () => {
jest.spyOn(logger, 'logError').mockImplementation();
const error = new Error();
Api.deleteFreezePeriod.mockRejectedValue(error);
- testAction(
+ await testAction(
actions.deleteFreezePeriod,
freezePeriodFixture,
state,
@@ -233,12 +232,11 @@ describe('deploy freeze store actions', () => {
{ type: 'RECEIVE_DELETE_FREEZE_PERIOD_ERROR', payload: freezePeriodFixture.id },
],
[],
- () => {
- expect(createFlash).toHaveBeenCalled();
-
- expect(logger.logError).toHaveBeenCalledWith('Unable to delete deploy freeze', error);
- },
);
+
+ expect(createAlert).toHaveBeenCalled();
+
+ expect(logger.logError).toHaveBeenCalledWith('Unable to delete deploy freeze', error);
});
});
});
diff --git a/spec/frontend/environment.js b/spec/frontend/environment.js
index 1c84350bd8e..82e3b50aeb8 100644
--- a/spec/frontend/environment.js
+++ b/spec/frontend/environment.js
@@ -1,7 +1,7 @@
/* eslint-disable import/no-commonjs, max-classes-per-file */
const path = require('path');
-const JSDOMEnvironment = require('jest-environment-jsdom');
+const { TestEnvironment } = require('jest-environment-jsdom');
const { ErrorWithStack } = require('jest-util');
const {
setGlobalDateToFakeDate,
@@ -11,10 +11,10 @@ const { TEST_HOST } = require('./__helpers__/test_constants');
const ROOT_PATH = path.resolve(__dirname, '../..');
-class CustomEnvironment extends JSDOMEnvironment {
- constructor(config, context) {
+class CustomEnvironment extends TestEnvironment {
+ constructor({ globalConfig, projectConfig }, context) {
// Setup testURL so that window.location is setup properly
- super({ ...config, testURL: TEST_HOST }, context);
+ super({ globalConfig, projectConfig: { ...projectConfig, testURL: TEST_HOST } }, context);
// Fake the `Date` for `jsdom` which fixes things like document.cookie
// https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39496#note_503084332
@@ -39,8 +39,7 @@ class CustomEnvironment extends JSDOMEnvironment {
},
});
- const { testEnvironmentOptions } = config;
- const { IS_EE } = testEnvironmentOptions;
+ const { IS_EE } = projectConfig.testEnvironmentOptions;
this.global.gon = {
ee: IS_EE,
};
diff --git a/spec/frontend/ide/init_gitlab_web_ide_spec.js b/spec/frontend/ide/init_gitlab_web_ide_spec.js
index 3b5b1ede28c..a4421855f10 100644
--- a/spec/frontend/ide/init_gitlab_web_ide_spec.js
+++ b/spec/frontend/ide/init_gitlab_web_ide_spec.js
@@ -1,4 +1,5 @@
import { start } from '@gitlab/web-ide';
+import { GITLAB_WEB_IDE_FEEDBACK_ISSUE } from '~/ide/constants';
import { initGitlabWebIDE } from '~/ide/init_gitlab_web_ide';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action';
import { createAndSubmitForm } from '~/lib/utils/create_and_submit_form';
@@ -14,6 +15,7 @@ const TEST_NONCE = 'test123nonce';
const TEST_PROJECT_PATH = 'group1/project1';
const TEST_BRANCH_NAME = '12345-foo-patch';
const TEST_GITLAB_URL = 'https://test-gitlab/';
+const TEST_USER_PREFERENCES_PATH = '/user/preferences';
const TEST_GITLAB_WEB_IDE_PUBLIC_PATH = 'test/webpack/assets/gitlab-web-ide/public/path';
const TEST_IDE_REMOTE_PATH = '/-/ide/remote/:remote_host/:remote_path';
const TEST_START_REMOTE_PARAMS = {
@@ -35,6 +37,7 @@ describe('ide/init_gitlab_web_ide', () => {
el.dataset.cspNonce = TEST_NONCE;
el.dataset.branchName = TEST_BRANCH_NAME;
el.dataset.ideRemotePath = TEST_IDE_REMOTE_PATH;
+ el.dataset.userPreferencesPath = TEST_USER_PREFERENCES_PATH;
document.body.append(el);
};
@@ -74,6 +77,10 @@ describe('ide/init_gitlab_web_ide', () => {
ref: TEST_BRANCH_NAME,
gitlabUrl: TEST_GITLAB_URL,
nonce: TEST_NONCE,
+ links: {
+ userPreferences: TEST_USER_PREFERENCES_PATH,
+ feedbackIssue: GITLAB_WEB_IDE_FEEDBACK_ISSUE,
+ },
handleStartRemote: expect.any(Function),
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index_spec.js b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index_spec.js
index 10696d25f17..e98c6ff1054 100644
--- a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index_spec.js
@@ -1,12 +1,14 @@
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import SetupInstructions from '~/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions.vue';
import SignInGitlabMultiversion from '~/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/index.vue';
-import VersionSelectForm from '~/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue';
import SignInOauthButton from '~/jira_connect/subscriptions/components/sign_in_oauth_button.vue';
+import VersionSelectForm from '~/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/version_select_form.vue';
import { updateInstallation } from '~/jira_connect/subscriptions/api';
import { reloadPage, persistBaseUrl, retrieveBaseUrl } from '~/jira_connect/subscriptions/utils';
+import { GITLAB_COM_BASE_PATH } from '~/jira_connect/subscriptions/constants';
jest.mock('~/jira_connect/subscriptions/api', () => {
return {
@@ -21,8 +23,9 @@ describe('SignInGitlabMultiversion', () => {
const mockBasePath = 'gitlab.mycompany.com';
- const findVersionSelectForm = () => wrapper.findComponent(VersionSelectForm);
+ const findSetupInstructions = () => wrapper.findComponent(SetupInstructions);
const findSignInOauthButton = () => wrapper.findComponent(SignInOauthButton);
+ const findVersionSelectForm = () => wrapper.findComponent(VersionSelectForm);
const findSubtitle = () => wrapper.findByTestId('subtitle');
const createComponent = () => {
@@ -59,15 +62,48 @@ describe('SignInGitlabMultiversion', () => {
});
describe('when version is selected', () => {
- beforeEach(() => {
- retrieveBaseUrl.mockReturnValue(mockBasePath);
- createComponent();
+ describe('when on self-managed', () => {
+ beforeEach(() => {
+ retrieveBaseUrl.mockReturnValue(mockBasePath);
+ createComponent();
+ });
+
+ it('renders correct subtitle', () => {
+ expect(findSubtitle().text()).toBe(SignInGitlabMultiversion.i18n.signInSubtitle);
+ });
+
+ it('renders setup instructions', () => {
+ expect(findSetupInstructions().exists()).toBe(true);
+ });
+
+ describe('when SetupInstructions emits `next` event', () => {
+ beforeEach(async () => {
+ findSetupInstructions().vm.$emit('next');
+ await nextTick();
+ });
+
+ it('renders sign in button', () => {
+ expect(findSignInOauthButton().props('gitlabBasePath')).toBe(mockBasePath);
+ });
+
+ it('hides setup instructions', () => {
+ expect(findSetupInstructions().exists()).toBe(false);
+ });
+ });
});
- describe('sign in button', () => {
+ describe('when on GitLab.com', () => {
+ beforeEach(() => {
+ retrieveBaseUrl.mockReturnValue(GITLAB_COM_BASE_PATH);
+ createComponent();
+ });
+
+ it('does not render setup instructions', () => {
+ expect(findSetupInstructions().exists()).toBe(false);
+ });
+
it('renders sign in button', () => {
- expect(findSignInOauthButton().exists()).toBe(true);
- expect(findSignInOauthButton().props('gitlabBasePath')).toBe(mockBasePath);
+ expect(findSignInOauthButton().props('gitlabBasePath')).toBe(GITLAB_COM_BASE_PATH);
});
describe('when button emits `sign-in` event', () => {
@@ -90,9 +126,5 @@ describe('SignInGitlabMultiversion', () => {
});
});
});
-
- it('renders correct subtitle', () => {
- expect(findSubtitle().text()).toBe(SignInGitlabMultiversion.i18n.signInSubtitle);
- });
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions_spec.js b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions_spec.js
new file mode 100644
index 00000000000..5496cf008c5
--- /dev/null
+++ b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions_spec.js
@@ -0,0 +1,35 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlLink } from '@gitlab/ui';
+
+import { OAUTH_SELF_MANAGED_DOC_LINK } from '~/jira_connect/subscriptions/constants';
+import SetupInstructions from '~/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_multiversion/setup_instructions.vue';
+
+describe('SetupInstructions', () => {
+ let wrapper;
+
+ const findGlButton = () => wrapper.findComponent(GlButton);
+ const findGlLink = () => wrapper.findComponent(GlLink);
+
+ const createComponent = () => {
+ wrapper = shallowMount(SetupInstructions);
+ };
+
+ describe('template', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders "Learn more" link to documentation', () => {
+ expect(findGlLink().attributes('href')).toBe(OAUTH_SELF_MANAGED_DOC_LINK);
+ });
+
+ describe('when button is clicked', () => {
+ it('emits "next" event', () => {
+ expect(wrapper.emitted('next')).toBeUndefined();
+ findGlButton().vm.$emit('click');
+
+ expect(wrapper.emitted('next')).toHaveLength(1);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/utils_spec.js b/spec/frontend/monitoring/utils_spec.js
index 6c6c3d6b90f..348825c334a 100644
--- a/spec/frontend/monitoring/utils_spec.js
+++ b/spec/frontend/monitoring/utils_spec.js
@@ -435,6 +435,7 @@ describe('monitoring/utils', () => {
describe('setCustomVariablesFromUrl', () => {
beforeEach(() => {
+ window.history.pushState = jest.fn();
jest.spyOn(urlUtils, 'updateHistory');
});
diff --git a/spec/frontend/performance_bar/components/detailed_metric_spec.js b/spec/frontend/performance_bar/components/detailed_metric_spec.js
index 437d51e02ba..5ab2c9abe5d 100644
--- a/spec/frontend/performance_bar/components/detailed_metric_spec.js
+++ b/spec/frontend/performance_bar/components/detailed_metric_spec.js
@@ -1,5 +1,4 @@
import { shallowMount } from '@vue/test-utils';
-import { GlDropdownItem } from '@gitlab/ui';
import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
@@ -31,12 +30,8 @@ describe('detailedMetric', () => {
const findExpandedBacktraceBtnAtIndex = (index) => findExpandBacktraceBtns().at(index);
const findDetailsLabel = () => wrapper.findByTestId('performance-bar-details-label');
const findSortOrderDropdown = () => wrapper.findByTestId('performance-bar-sort-order');
- const clickSortOrderDropdownItem = (sortOrder) =>
- findSortOrderDropdown()
- .findAllComponents(GlDropdownItem)
- .filter((item) => item.text() === sortOrderOptions[sortOrder])
- .at(0)
- .vm.$emit('click');
+ const selectSortOrder = (sortOrder) =>
+ findSortOrderDropdown().vm.$emit('select', sortOrderOptions[sortOrder].value);
const findEmptyDetailNotice = () => wrapper.findByTestId('performance-bar-empty-detail-notice');
const findAllDetailDurations = () =>
wrapper.findAllByTestId('performance-item-duration').wrappers.map((w) => w.text());
@@ -334,11 +329,11 @@ describe('detailedMetric', () => {
});
it('changes sortOrder on select', async () => {
- clickSortOrderDropdownItem(sortOrders.CHRONOLOGICAL);
+ selectSortOrder(sortOrders.CHRONOLOGICAL);
await nextTick();
expect(findAllDetailDurations()).toEqual(['23ms', '100ms', '75ms']);
- clickSortOrderDropdownItem(sortOrders.DURATION);
+ selectSortOrder(sortOrders.DURATION);
await nextTick();
expect(findAllDetailDurations()).toEqual(['100ms', '75ms', '23ms']);
});
diff --git a/spec/frontend_integration/content_editor/content_editor_integration_spec.js b/spec/frontend_integration/content_editor/content_editor_integration_spec.js
index 2fa491196ff..8521e85a971 100644
--- a/spec/frontend_integration/content_editor/content_editor_integration_spec.js
+++ b/spec/frontend_integration/content_editor/content_editor_integration_spec.js
@@ -114,8 +114,6 @@ This reference tag is a mix of letters and numbers [^footnote].
});
it('renders table of contents', async () => {
- jest.useFakeTimers();
-
renderMarkdown.mockResolvedValueOnce(`
<ul class="section-nav">
</ul>
diff --git a/spec/lib/gitlab/ci/cron_parser_spec.rb b/spec/lib/gitlab/ci/cron_parser_spec.rb
index 33474865a93..4b750cf3bcf 100644
--- a/spec/lib/gitlab/ci/cron_parser_spec.rb
+++ b/spec/lib/gitlab/ci/cron_parser_spec.rb
@@ -358,4 +358,22 @@ RSpec.describe Gitlab::Ci::CronParser do
end
end
end
+
+ describe '#match?' do
+ let(:run_date) { Time.zone.local(2021, 3, 2, 1, 0) }
+
+ subject(:matched) { described_class.new(cron, Gitlab::Ci::CronParser::VALID_SYNTAX_SAMPLE_TIME_ZONE).match?(run_date) }
+
+ context 'when cron matches up' do
+ let(:cron) { '0 1 2 3 *' }
+
+ it { is_expected.to eq(true) }
+ end
+
+ context 'when cron does not match' do
+ let(:cron) { '5 4 3 2 1' }
+
+ it { is_expected.to eq(false) }
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
index 5433f03fb09..1f7f800e238 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
@@ -11,861 +11,954 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build, feature_category: :pipeline_au
let(:seed_context) { Gitlab::Ci::Pipeline::Seed::Context.new(pipeline, root_variables: root_variables) }
let(:attributes) { { name: 'rspec', ref: 'master', scheduling_type: :stage, when: 'on_success' } }
let(:previous_stages) { [] }
- let(:current_stage) { double(seeds_names: [attributes[:name]]) }
+ let(:current_stage) { instance_double(Gitlab::Ci::Pipeline::Seed::Stage, seeds_names: [attributes[:name]]) }
+ let(:current_ci_stage) { build(:ci_stage, pipeline: pipeline) }
- let(:seed_build) { described_class.new(seed_context, attributes, previous_stages + [current_stage]) }
+ let(:seed_build) { described_class.new(seed_context, attributes, previous_stages + [current_stage], current_ci_stage) }
- describe '#attributes' do
- subject { seed_build.attributes }
+ shared_examples 'build seed' do
+ describe '#attributes' do
+ subject { seed_build.attributes }
- it { is_expected.to be_a(Hash) }
- it { is_expected.to include(:name, :project, :ref) }
+ it { is_expected.to be_a(Hash) }
+ it { is_expected.to include(:name, :project, :ref) }
- context 'with job:when' do
- let(:attributes) { { name: 'rspec', ref: 'master', when: 'on_failure' } }
+ context 'with job:when' do
+ let(:attributes) { { name: 'rspec', ref: 'master', when: 'on_failure' } }
- it { is_expected.to include(when: 'on_failure') }
- end
-
- context 'with job:when:delayed' do
- let(:attributes) { { name: 'rspec', ref: 'master', when: 'delayed', start_in: '3 hours' } }
-
- it { is_expected.to include(when: 'delayed', start_in: '3 hours') }
- end
-
- context 'with job:rules:[when:]' do
- context 'is matched' do
- let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR == null', when: 'always' }] } }
-
- it { is_expected.to include(when: 'always') }
+ it { is_expected.to include(when: 'on_failure') }
end
- context 'is not matched' do
- let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR != null', when: 'always' }] } }
-
- it { is_expected.to include(when: 'never') }
- end
- end
-
- context 'with job:rules:[when:delayed]' do
- context 'is matched' do
- let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR == null', when: 'delayed', start_in: '3 hours' }] } }
+ context 'with job:when:delayed' do
+ let(:attributes) { { name: 'rspec', ref: 'master', when: 'delayed', options: { start_in: '3 hours' } } }
it { is_expected.to include(when: 'delayed', options: { start_in: '3 hours' }) }
end
- context 'is not matched' do
- let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR != null', when: 'delayed', start_in: '3 hours' }] } }
-
- it { is_expected.to include(when: 'never') }
- end
- end
-
- context 'with job: rules but no explicit when:' do
- let(:base_attributes) { { name: 'rspec', ref: 'master' } }
-
- context 'with a manual job' do
- context 'with a matched rule' do
- let(:attributes) { base_attributes.merge(when: 'manual', rules: [{ if: '$VAR == null' }]) }
+ context 'with job:rules:[when:]' do
+ context 'is matched' do
+ let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR == null', when: 'always' }] } }
- it { is_expected.to include(when: 'manual') }
+ it { is_expected.to include(when: 'always') }
end
context 'is not matched' do
- let(:attributes) { base_attributes.merge(when: 'manual', rules: [{ if: '$VAR != null' }]) }
+ let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR != null', when: 'always' }] } }
it { is_expected.to include(when: 'never') }
end
end
- context 'with an automatic job' do
+ context 'with job:rules:[when:delayed]' do
context 'is matched' do
- let(:attributes) { base_attributes.merge(when: 'on_success', rules: [{ if: '$VAR == null' }]) }
+ let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR == null', when: 'delayed', start_in: '3 hours' }] } }
- it { is_expected.to include(when: 'on_success') }
+ it { is_expected.to include(when: 'delayed', options: { start_in: '3 hours' }) }
end
context 'is not matched' do
- let(:attributes) { base_attributes.merge(when: 'on_success', rules: [{ if: '$VAR != null' }]) }
+ let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$VAR != null', when: 'delayed', start_in: '3 hours' }] } }
it { is_expected.to include(when: 'never') }
end
end
- end
- context 'with job:rules:[variables:]' do
- let(:attributes) do
- { name: 'rspec',
- ref: 'master',
- job_variables: [{ key: 'VAR1', value: 'var 1' },
- { key: 'VAR2', value: 'var 2' }],
- rules: [{ if: '$VAR == null', variables: { VAR1: 'new var 1', VAR3: 'var 3' } }] }
- end
+ context 'with job: rules but no explicit when:' do
+ let(:base_attributes) { { name: 'rspec', ref: 'master' } }
- it do
- is_expected.to include(yaml_variables: [{ key: 'VAR1', value: 'new var 1' },
- { key: 'VAR3', value: 'var 3' },
- { key: 'VAR2', value: 'var 2' }])
- end
- end
+ context 'with a manual job' do
+ context 'with a matched rule' do
+ let(:attributes) { base_attributes.merge(when: 'manual', rules: [{ if: '$VAR == null' }]) }
- context 'with job:tags' do
- let(:attributes) do
- {
- name: 'rspec',
- ref: 'master',
- job_variables: [{ key: 'VARIABLE', value: 'value' }],
- tag_list: ['static-tag', '$VARIABLE', '$NO_VARIABLE']
- }
- end
+ it { is_expected.to include(when: 'manual') }
+ end
- it { is_expected.to include(tag_list: ['static-tag', 'value', '$NO_VARIABLE']) }
- it { is_expected.to include(yaml_variables: [{ key: 'VARIABLE', value: 'value' }]) }
- end
+ context 'is not matched' do
+ let(:attributes) { base_attributes.merge(when: 'manual', rules: [{ if: '$VAR != null' }]) }
- context 'with cache:key' do
- let(:attributes) do
- {
- name: 'rspec',
- ref: 'master',
- cache: [{
- key: 'a-value'
- }]
- }
- end
+ it { is_expected.to include(when: 'never') }
+ end
+ end
+
+ context 'with an automatic job' do
+ context 'is matched' do
+ let(:attributes) { base_attributes.merge(when: 'on_success', rules: [{ if: '$VAR == null' }]) }
- it { is_expected.to include(options: { cache: [a_hash_including(key: 'a-value')] }) }
+ it { is_expected.to include(when: 'on_success') }
+ end
- context 'with cache:key:files' do
+ context 'is not matched' do
+ let(:attributes) { base_attributes.merge(when: 'on_success', rules: [{ if: '$VAR != null' }]) }
+
+ it { is_expected.to include(when: 'never') }
+ end
+ end
+ end
+
+ context 'with job:rules:[variables:]' do
let(:attributes) do
- {
- name: 'rspec',
+ { name: 'rspec',
ref: 'master',
- cache: [{
- key: {
- files: ['VERSION']
- }
- }]
- }
+ job_variables: [{ key: 'VAR1', value: 'var 1' },
+ { key: 'VAR2', value: 'var 2' }],
+ rules: [{ if: '$VAR == null', variables: { VAR1: 'new var 1', VAR3: 'var 3' } }] }
end
- it 'includes cache options' do
- cache_options = {
- options: {
- cache: [a_hash_including(key: '0-f155568ad0933d8358f66b846133614f76dd0ca4')]
- }
- }
+ it do
+ is_expected.to include(yaml_variables: [{ key: 'VAR1', value: 'new var 1' },
+ { key: 'VAR3', value: 'var 3' },
+ { key: 'VAR2', value: 'var 2' }])
+ end
- is_expected.to include(cache_options)
+ it 'expects the same results on to_resource' do
+ expect(seed_build.to_resource.yaml_variables).to include({ key: 'VAR1', value: 'new var 1' },
+ { key: 'VAR3', value: 'var 3' },
+ { key: 'VAR2', value: 'var 2' })
end
end
- context 'with cache:key:prefix' do
+ context 'with job:tags' do
let(:attributes) do
{
name: 'rspec',
ref: 'master',
- cache: [{
- key: {
- prefix: 'something'
- }
- }]
+ job_variables: [{ key: 'VARIABLE', value: 'value' }],
+ tag_list: ['static-tag', '$VARIABLE', '$NO_VARIABLE']
}
end
- it { is_expected.to include(options: { cache: [a_hash_including( key: 'something-default' )] }) }
+ it { is_expected.to include(tag_list: ['static-tag', 'value', '$NO_VARIABLE']) }
+ it { is_expected.to include(yaml_variables: [{ key: 'VARIABLE', value: 'value' }]) }
end
- context 'with cache:key:files and prefix' do
+ context 'with cache:key' do
let(:attributes) do
{
name: 'rspec',
ref: 'master',
cache: [{
- key: {
- files: ['VERSION'],
- prefix: 'something'
- }
+ key: 'a-value'
}]
}
end
- it 'includes cache options' do
- cache_options = {
- options: {
- cache: [a_hash_including(key: 'something-f155568ad0933d8358f66b846133614f76dd0ca4')]
+ it { is_expected.to include(options: { cache: [a_hash_including(key: 'a-value')] }) }
+
+ context 'with cache:key:files' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ ref: 'master',
+ cache: [{
+ key: {
+ files: ['VERSION']
+ }
+ }]
}
- }
+ end
- is_expected.to include(cache_options)
- end
- end
- end
+ it 'includes cache options' do
+ cache_options = {
+ options: {
+ cache: [a_hash_including(key: '0-f155568ad0933d8358f66b846133614f76dd0ca4')]
+ }
+ }
- context 'with empty cache' do
- let(:attributes) do
- {
- name: 'rspec',
- ref: 'master',
- cache: {}
- }
- end
+ is_expected.to include(cache_options)
+ end
+ end
- it { is_expected.to include({}) }
- end
+ context 'with cache:key:prefix' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ ref: 'master',
+ cache: [{
+ key: {
+ prefix: 'something'
+ }
+ }]
+ }
+ end
- context 'with allow_failure' do
- let(:options) do
- { allow_failure_criteria: { exit_codes: [42] } }
- end
+ it { is_expected.to include(options: { cache: [a_hash_including( key: 'something-default' )] }) }
+ end
- let(:rules) do
- [{ if: '$VAR == null', when: 'always' }]
- end
+ context 'with cache:key:files and prefix' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ ref: 'master',
+ cache: [{
+ key: {
+ files: ['VERSION'],
+ prefix: 'something'
+ }
+ }]
+ }
+ end
- let(:attributes) do
- {
- name: 'rspec',
- ref: 'master',
- options: options,
- rules: rules
- }
- end
+ it 'includes cache options' do
+ cache_options = {
+ options: {
+ cache: [a_hash_including(key: 'something-f155568ad0933d8358f66b846133614f76dd0ca4')]
+ }
+ }
- context 'when rules does not override allow_failure' do
- it { is_expected.to match a_hash_including(options: options) }
+ is_expected.to include(cache_options)
+ end
+ end
end
- context 'when rules set allow_failure to true' do
- let(:rules) do
- [{ if: '$VAR == null', when: 'always', allow_failure: true }]
+ context 'with empty cache' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ ref: 'master',
+ cache: {}
+ }
end
- it { is_expected.to match a_hash_including(options: { allow_failure_criteria: nil }) }
+ it { is_expected.to include({}) }
end
- context 'when rules set allow_failure to false' do
- let(:rules) do
- [{ if: '$VAR == null', when: 'always', allow_failure: false }]
+ context 'with allow_failure' do
+ let(:options) do
+ { allow_failure_criteria: { exit_codes: [42] } }
end
- it { is_expected.to match a_hash_including(options: { allow_failure_criteria: nil }) }
- end
- end
-
- context 'with workflow:rules:[variables:]' do
- let(:attributes) do
- { name: 'rspec',
- ref: 'master',
- yaml_variables: [{ key: 'VAR2', value: 'var 2' },
- { key: 'VAR3', value: 'var 3' }],
- job_variables: [{ key: 'VAR2', value: 'var 2' },
- { key: 'VAR3', value: 'var 3' }],
- root_variables_inheritance: root_variables_inheritance }
- end
+ let(:rules) do
+ [{ if: '$VAR == null', when: 'always' }]
+ end
- context 'when the pipeline has variables' do
- let(:root_variables) do
- [{ key: 'VAR1', value: 'var overridden pipeline 1' },
- { key: 'VAR2', value: 'var pipeline 2' },
- { key: 'VAR3', value: 'var pipeline 3' },
- { key: 'VAR4', value: 'new var pipeline 4' }]
+ let(:attributes) do
+ {
+ name: 'rspec',
+ ref: 'master',
+ options: options,
+ rules: rules
+ }
end
- context 'when root_variables_inheritance is true' do
- let(:root_variables_inheritance) { true }
+ context 'when rules does not override allow_failure' do
+ it { is_expected.to match a_hash_including(options: options) }
+ end
- it 'returns calculated yaml variables' do
- expect(subject[:yaml_variables]).to match_array(
- [{ key: 'VAR1', value: 'var overridden pipeline 1' },
- { key: 'VAR2', value: 'var 2' },
- { key: 'VAR3', value: 'var 3' },
- { key: 'VAR4', value: 'new var pipeline 4' }]
- )
+ context 'when rules set allow_failure to true' do
+ let(:rules) do
+ [{ if: '$VAR == null', when: 'always', allow_failure: true }]
end
- end
- context 'when root_variables_inheritance is false' do
- let(:root_variables_inheritance) { false }
+ it { is_expected.to match a_hash_including(options: { allow_failure_criteria: nil }) }
- it 'returns job variables' do
- expect(subject[:yaml_variables]).to match_array(
- [{ key: 'VAR2', value: 'var 2' },
- { key: 'VAR3', value: 'var 3' }]
- )
- end
- end
+ context 'when options contain other static values' do
+ let(:options) do
+ { image: 'busybox', allow_failure_criteria: { exit_codes: [42] } }
+ end
- context 'when root_variables_inheritance is an array' do
- let(:root_variables_inheritance) { %w(VAR1 VAR2 VAR3) }
+ it { is_expected.to match a_hash_including(options: { image: 'busybox', allow_failure_criteria: nil }) }
- it 'returns calculated yaml variables' do
- expect(subject[:yaml_variables]).to match_array(
- [{ key: 'VAR1', value: 'var overridden pipeline 1' },
- { key: 'VAR2', value: 'var 2' },
- { key: 'VAR3', value: 'var 3' }]
- )
+ it 'deep merges options when exporting to_resource' do
+ expect(seed_build.to_resource.options).to match a_hash_including(
+ image: 'busybox', allow_failure_criteria: nil
+ )
+ end
end
end
- end
- context 'when the pipeline has not a variable' do
- let(:root_variables_inheritance) { true }
+ context 'when rules set allow_failure to false' do
+ let(:rules) do
+ [{ if: '$VAR == null', when: 'always', allow_failure: false }]
+ end
- it 'returns seed yaml variables' do
- expect(subject[:yaml_variables]).to match_array(
- [{ key: 'VAR2', value: 'var 2' },
- { key: 'VAR3', value: 'var 3' }])
+ it { is_expected.to match a_hash_including(options: { allow_failure_criteria: nil }) }
end
end
- end
- context 'when the job rule depends on variables' do
- let(:attributes) do
- { name: 'rspec',
- ref: 'master',
- yaml_variables: [{ key: 'VAR1', value: 'var 1' }],
- job_variables: [{ key: 'VAR1', value: 'var 1' }],
- root_variables_inheritance: root_variables_inheritance,
- rules: rules }
- end
+ context 'with workflow:rules:[variables:]' do
+ let(:attributes) do
+ { name: 'rspec',
+ ref: 'master',
+ yaml_variables: [{ key: 'VAR2', value: 'var 2' },
+ { key: 'VAR3', value: 'var 3' }],
+ job_variables: [{ key: 'VAR2', value: 'var 2' },
+ { key: 'VAR3', value: 'var 3' }],
+ root_variables_inheritance: root_variables_inheritance }
+ end
+
+ context 'when the pipeline has variables' do
+ let(:root_variables) do
+ [{ key: 'VAR1', value: 'var overridden pipeline 1' },
+ { key: 'VAR2', value: 'var pipeline 2' },
+ { key: 'VAR3', value: 'var pipeline 3' },
+ { key: 'VAR4', value: 'new var pipeline 4' }]
+ end
- let(:root_variables_inheritance) { true }
+ context 'when root_variables_inheritance is true' do
+ let(:root_variables_inheritance) { true }
- context 'when the rules use job variables' do
- let(:rules) do
- [{ if: '$VAR1 == "var 1"', variables: { VAR1: 'overridden var 1', VAR2: 'new var 2' } }]
+ it 'returns calculated yaml variables' do
+ expect(subject[:yaml_variables]).to match_array(
+ [{ key: 'VAR1', value: 'var overridden pipeline 1' },
+ { key: 'VAR2', value: 'var 2' },
+ { key: 'VAR3', value: 'var 3' },
+ { key: 'VAR4', value: 'new var pipeline 4' }]
+ )
+ end
+ end
+
+ context 'when root_variables_inheritance is false' do
+ let(:root_variables_inheritance) { false }
+
+ it 'returns job variables' do
+ expect(subject[:yaml_variables]).to match_array(
+ [{ key: 'VAR2', value: 'var 2' },
+ { key: 'VAR3', value: 'var 3' }]
+ )
+ end
+ end
+
+ context 'when root_variables_inheritance is an array' do
+ let(:root_variables_inheritance) { %w(VAR1 VAR2 VAR3) }
+
+ it 'returns calculated yaml variables' do
+ expect(subject[:yaml_variables]).to match_array(
+ [{ key: 'VAR1', value: 'var overridden pipeline 1' },
+ { key: 'VAR2', value: 'var 2' },
+ { key: 'VAR3', value: 'var 3' }]
+ )
+ end
+ end
end
- it 'recalculates the variables' do
- expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'overridden var 1' },
- { key: 'VAR2', value: 'new var 2' })
+ context 'when the pipeline has not a variable' do
+ let(:root_variables_inheritance) { true }
+
+ it 'returns seed yaml variables' do
+ expect(subject[:yaml_variables]).to match_array(
+ [{ key: 'VAR2', value: 'var 2' },
+ { key: 'VAR3', value: 'var 3' }])
+ end
end
end
- context 'when the rules use root variables' do
- let(:root_variables) do
- [{ key: 'VAR2', value: 'var pipeline 2' }]
+ context 'when the job rule depends on variables' do
+ let(:attributes) do
+ { name: 'rspec',
+ ref: 'master',
+ yaml_variables: [{ key: 'VAR1', value: 'var 1' }],
+ job_variables: [{ key: 'VAR1', value: 'var 1' }],
+ root_variables_inheritance: root_variables_inheritance,
+ rules: rules }
end
- let(:rules) do
- [{ if: '$VAR2 == "var pipeline 2"', variables: { VAR1: 'overridden var 1', VAR2: 'overridden var 2' } }]
- end
+ let(:root_variables_inheritance) { true }
+
+ context 'when the rules use job variables' do
+ let(:rules) do
+ [{ if: '$VAR1 == "var 1"', variables: { VAR1: 'overridden var 1', VAR2: 'new var 2' } }]
+ end
- it 'recalculates the variables' do
- expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'overridden var 1' },
- { key: 'VAR2', value: 'overridden var 2' })
+ it 'recalculates the variables' do
+ expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'overridden var 1' },
+ { key: 'VAR2', value: 'new var 2' })
+ end
end
- context 'when the root_variables_inheritance is false' do
- let(:root_variables_inheritance) { false }
+ context 'when the rules use root variables' do
+ let(:root_variables) do
+ [{ key: 'VAR2', value: 'var pipeline 2' }]
+ end
- it 'does not recalculate the variables' do
- expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'var 1' })
+ let(:rules) do
+ [{ if: '$VAR2 == "var pipeline 2"', variables: { VAR1: 'overridden var 1', VAR2: 'overridden var 2' } }]
+ end
+
+ it 'recalculates the variables' do
+ expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'overridden var 1' },
+ { key: 'VAR2', value: 'overridden var 2' })
end
- end
- end
- end
- end
- describe '#bridge?' do
- subject { seed_build.bridge? }
+ context 'when the root_variables_inheritance is false' do
+ let(:root_variables_inheritance) { false }
- context 'when job is a downstream bridge' do
- let(:attributes) do
- { name: 'rspec', ref: 'master', options: { trigger: 'my/project' } }
+ it 'does not recalculate the variables' do
+ expect(subject[:yaml_variables]).to contain_exactly({ key: 'VAR1', value: 'var 1' })
+ end
+ end
+ end
end
+ end
- it { is_expected.to be_truthy }
+ describe '#bridge?' do
+ subject { seed_build.bridge? }
- context 'when trigger definition is empty' do
+ context 'when job is a downstream bridge' do
let(:attributes) do
- { name: 'rspec', ref: 'master', options: { trigger: '' } }
+ { name: 'rspec', ref: 'master', options: { trigger: 'my/project' } }
end
- it { is_expected.to be_falsey }
- end
- end
+ it { is_expected.to be_truthy }
- context 'when job is an upstream bridge' do
- let(:attributes) do
- { name: 'rspec', ref: 'master', options: { bridge_needs: { pipeline: 'my/project' } } }
- end
+ context 'when trigger definition is empty' do
+ let(:attributes) do
+ { name: 'rspec', ref: 'master', options: { trigger: '' } }
+ end
- it { is_expected.to be_truthy }
+ it { is_expected.to be_falsey }
+ end
+ end
- context 'when upstream definition is empty' do
+ context 'when job is an upstream bridge' do
let(:attributes) do
- { name: 'rspec', ref: 'master', options: { bridge_needs: { pipeline: '' } } }
+ { name: 'rspec', ref: 'master', options: { bridge_needs: { pipeline: 'my/project' } } }
end
- it { is_expected.to be_falsey }
- end
- end
+ it { is_expected.to be_truthy }
- context 'when job is not a bridge' do
- it { is_expected.to be_falsey }
- end
- end
+ context 'when upstream definition is empty' do
+ let(:attributes) do
+ { name: 'rspec', ref: 'master', options: { bridge_needs: { pipeline: '' } } }
+ end
- describe '#to_resource' do
- subject { seed_build.to_resource }
+ it { is_expected.to be_falsey }
+ end
+ end
- it 'memoizes a resource object' do
- expect(subject.object_id).to eq seed_build.to_resource.object_id
+ context 'when job is not a bridge' do
+ it { is_expected.to be_falsey }
+ end
end
- it 'can not be persisted without explicit assignment' do
- pipeline.save!
+ describe '#to_resource' do
+ subject { seed_build.to_resource }
- expect(subject).not_to be_persisted
- end
- end
+ it 'memoizes a resource object' do
+ expect(subject.object_id).to eq seed_build.to_resource.object_id
+ end
- describe 'applying job inclusion policies' do
- subject { seed_build }
+ it 'can not be persisted without explicit assignment' do
+ pipeline.save!
- context 'when no branch policy is specified' do
- let(:attributes) do
- { name: 'rspec' }
+ expect(subject).not_to be_persisted
end
-
- it { is_expected.to be_included }
end
- context 'when branch policy does not match' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: ['deploy'] } }
- end
-
- it { is_expected.not_to be_included }
- end
+ describe 'applying job inclusion policies' do
+ subject { seed_build }
- context 'when using except' do
+ context 'when no branch policy is specified' do
let(:attributes) do
- { name: 'rspec', except: { refs: ['deploy'] } }
+ { name: 'rspec' }
end
it { is_expected.to be_included }
end
- context 'with both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: %w[deploy] },
- except: { refs: %w[deploy] }
- }
+ context 'when branch policy does not match' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: ['deploy'] } }
+ end
+
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: ['deploy'] } }
+ end
- context 'when branch regexp policy does not match' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: %w[/^deploy$/] } }
+ it { is_expected.to be_included }
end
- it { is_expected.not_to be_included }
- end
+ context 'with both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: %w[deploy] },
+ except: { refs: %w[deploy] }
+ }
+ end
- context 'when using except' do
- let(:attributes) do
- { name: 'rspec', except: { refs: %w[/^deploy$/] } }
+ it { is_expected.not_to be_included }
end
-
- it { is_expected.to be_included }
end
- context 'with both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: %w[/^deploy$/] },
- except: { refs: %w[/^deploy$/] }
- }
+ context 'when branch regexp policy does not match' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: %w[/^deploy$/] } }
+ end
+
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: %w[/^deploy$/] } }
+ end
- context 'when branch policy matches' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: %w[deploy master] } }
+ it { is_expected.to be_included }
end
- it { is_expected.to be_included }
- end
+ context 'with both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: %w[/^deploy$/] },
+ except: { refs: %w[/^deploy$/] }
+ }
+ end
- context 'when using except' do
- let(:attributes) do
- { name: 'rspec', except: { refs: %w[deploy master] } }
+ it { is_expected.not_to be_included }
end
-
- it { is_expected.not_to be_included }
end
- context 'when using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: %w[deploy master] },
- except: { refs: %w[deploy master] }
- }
+ context 'when branch policy matches' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: %w[deploy master] } }
+ end
+
+ it { is_expected.to be_included }
end
- it { is_expected.not_to be_included }
- end
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: %w[deploy master] } }
+ end
- context 'when keyword policy matches' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: %w[branches] } }
+ it { is_expected.not_to be_included }
end
- it { is_expected.to be_included }
- end
+ context 'when using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: %w[deploy master] },
+ except: { refs: %w[deploy master] }
+ }
+ end
- context 'when using except' do
- let(:attributes) do
- { name: 'rspec', except: { refs: %w[branches] } }
+ it { is_expected.not_to be_included }
end
-
- it { is_expected.not_to be_included }
end
- context 'when using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: %w[branches] },
- except: { refs: %w[branches] }
- }
+ context 'when keyword policy matches' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: %w[branches] } }
+ end
+
+ it { is_expected.to be_included }
end
- it { is_expected.not_to be_included }
- end
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: %w[branches] } }
+ end
- context 'when keyword policy does not match' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: %w[tags] } }
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
+ context 'when using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: %w[branches] },
+ except: { refs: %w[branches] }
+ }
+ end
- context 'when using except' do
- let(:attributes) do
- { name: 'rspec', except: { refs: %w[tags] } }
+ it { is_expected.not_to be_included }
end
-
- it { is_expected.to be_included }
end
- context 'when using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: %w[tags] },
- except: { refs: %w[tags] }
- }
+ context 'when keyword policy does not match' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: %w[tags] } }
+ end
+
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: %w[tags] } }
+ end
- context 'with source-keyword policy' do
- using RSpec::Parameterized
+ it { is_expected.to be_included }
+ end
- let(:pipeline) do
- build(:ci_empty_pipeline, ref: 'deploy', tag: false, source: source, project: project)
- end
+ context 'when using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: %w[tags] },
+ except: { refs: %w[tags] }
+ }
+ end
- context 'matches' do
- where(:keyword, :source) do
- [
- %w[pushes push],
- %w[web web],
- %w[triggers trigger],
- %w[schedules schedule],
- %w[api api],
- %w[external external]
- ]
+ it { is_expected.not_to be_included }
end
+ end
- with_them do
- context 'using an only policy' do
- let(:attributes) do
- { name: 'rspec', only: { refs: [keyword] } }
- end
+ context 'with source-keyword policy' do
+ using RSpec::Parameterized
- it { is_expected.to be_included }
+ let(:pipeline) do
+ build(:ci_empty_pipeline, ref: 'deploy', tag: false, source: source, project: project)
+ end
+
+ context 'matches' do
+ where(:keyword, :source) do
+ [
+ %w[pushes push],
+ %w[web web],
+ %w[triggers trigger],
+ %w[schedules schedule],
+ %w[api api],
+ %w[external external]
+ ]
end
- context 'using an except policy' do
- let(:attributes) do
- { name: 'rspec', except: { refs: [keyword] } }
+ with_them do
+ context 'using an only policy' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: [keyword] } }
+ end
+
+ it { is_expected.to be_included }
end
- it { is_expected.not_to be_included }
- end
+ context 'using an except policy' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: [keyword] } }
+ end
- context 'using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: [keyword] },
- except: { refs: [keyword] }
- }
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
+ context 'using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: [keyword] },
+ except: { refs: [keyword] }
+ }
+ end
+
+ it { is_expected.not_to be_included }
+ end
end
end
- end
- context 'non-matches' do
- where(:keyword, :source) do
- %w[web trigger schedule api external].map { |source| ['pushes', source] } +
- %w[push trigger schedule api external].map { |source| ['web', source] } +
- %w[push web schedule api external].map { |source| ['triggers', source] } +
- %w[push web trigger api external].map { |source| ['schedules', source] } +
- %w[push web trigger schedule external].map { |source| ['api', source] } +
- %w[push web trigger schedule api].map { |source| ['external', source] }
- end
+ context 'non-matches' do
+ where(:keyword, :source) do
+ %w[web trigger schedule api external].map { |source| ['pushes', source] } +
+ %w[push trigger schedule api external].map { |source| ['web', source] } +
+ %w[push web schedule api external].map { |source| ['triggers', source] } +
+ %w[push web trigger api external].map { |source| ['schedules', source] } +
+ %w[push web trigger schedule external].map { |source| ['api', source] } +
+ %w[push web trigger schedule api].map { |source| ['external', source] }
+ end
+
+ with_them do
+ context 'using an only policy' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: [keyword] } }
+ end
- with_them do
- context 'using an only policy' do
- let(:attributes) do
- { name: 'rspec', only: { refs: [keyword] } }
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
+ context 'using an except policy' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: [keyword] } }
+ end
- context 'using an except policy' do
- let(:attributes) do
- { name: 'rspec', except: { refs: [keyword] } }
+ it { is_expected.to be_included }
end
- it { is_expected.to be_included }
- end
+ context 'using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: [keyword] },
+ except: { refs: [keyword] }
+ }
+ end
- context 'using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: [keyword] },
- except: { refs: [keyword] }
- }
+ it { is_expected.not_to be_included }
end
-
- it { is_expected.not_to be_included }
end
end
end
- end
- context 'when repository path matches' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: ["branches@#{pipeline.project_full_path}"] } }
+ context 'when repository path matches' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: ["branches@#{pipeline.project_full_path}"] } }
+ end
+
+ it { is_expected.to be_included }
end
- it { is_expected.to be_included }
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: ["branches@#{pipeline.project_full_path}"] } }
+ end
- context 'when using except' do
- let(:attributes) do
- { name: 'rspec', except: { refs: ["branches@#{pipeline.project_full_path}"] } }
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
+ context 'when using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: ["branches@#{pipeline.project_full_path}"] },
+ except: { refs: ["branches@#{pipeline.project_full_path}"] }
+ }
+ end
- context 'when using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: ["branches@#{pipeline.project_full_path}"] },
- except: { refs: ["branches@#{pipeline.project_full_path}"] }
- }
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
-
- context 'when using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: {
- refs: ["branches@#{pipeline.project_full_path}"]
- },
- except: {
- refs: ["branches@#{pipeline.project_full_path}"]
+ context 'when using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: {
+ refs: ["branches@#{pipeline.project_full_path}"]
+ },
+ except: {
+ refs: ["branches@#{pipeline.project_full_path}"]
+ }
}
- }
- end
+ end
- it { is_expected.not_to be_included }
+ it { is_expected.not_to be_included }
+ end
end
- end
- context 'when repository path does not match' do
- context 'when using only' do
- let(:attributes) do
- { name: 'rspec', only: { refs: %w[branches@fork] } }
+ context 'when repository path does not match' do
+ context 'when using only' do
+ let(:attributes) do
+ { name: 'rspec', only: { refs: %w[branches@fork] } }
+ end
+
+ it { is_expected.not_to be_included }
end
- it { is_expected.not_to be_included }
- end
+ context 'when using except' do
+ let(:attributes) do
+ { name: 'rspec', except: { refs: %w[branches@fork] } }
+ end
- context 'when using except' do
- let(:attributes) do
- { name: 'rspec', except: { refs: %w[branches@fork] } }
+ it { is_expected.to be_included }
end
- it { is_expected.to be_included }
- end
+ context 'when using both only and except policies' do
+ let(:attributes) do
+ {
+ name: 'rspec',
+ only: { refs: %w[branches@fork] },
+ except: { refs: %w[branches@fork] }
+ }
+ end
- context 'when using both only and except policies' do
- let(:attributes) do
- {
- name: 'rspec',
- only: { refs: %w[branches@fork] },
- except: { refs: %w[branches@fork] }
- }
+ it { is_expected.not_to be_included }
end
-
- it { is_expected.not_to be_included }
end
- end
- context 'using rules:' do
- using RSpec::Parameterized
+ context 'using rules:' do
+ using RSpec::Parameterized
- let(:attributes) { { name: 'rspec', rules: rule_set, when: 'on_success' } }
+ let(:attributes) { { name: 'rspec', rules: rule_set, when: 'on_success' } }
- context 'with a matching if: rule' do
- context 'with an explicit `when: never`' do
- where(:rule_set) do
- [
- [[{ if: '$VARIABLE == null', when: 'never' }]],
- [[{ if: '$VARIABLE == null', when: 'never' }, { if: '$VARIABLE == null', when: 'always' }]],
- [[{ if: '$VARIABLE != "the wrong value"', when: 'never' }, { if: '$VARIABLE == null', when: 'always' }]]
- ]
- end
+ context 'with a matching if: rule' do
+ context 'with an explicit `when: never`' do
+ where(:rule_set) do
+ [
+ [[{ if: '$VARIABLE == null', when: 'never' }]],
+ [[{ if: '$VARIABLE == null', when: 'never' }, { if: '$VARIABLE == null', when: 'always' }]],
+ [[{ if: '$VARIABLE != "the wrong value"', when: 'never' }, { if: '$VARIABLE == null', when: 'always' }]]
+ ]
+ end
- with_them do
- it { is_expected.not_to be_included }
+ with_them do
+ it { is_expected.not_to be_included }
- it 'still correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'never')
+ it 'still correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'never')
+ end
end
end
- end
- context 'with an explicit `when: always`' do
- where(:rule_set) do
- [
- [[{ if: '$VARIABLE == null', when: 'always' }]],
- [[{ if: '$VARIABLE == null', when: 'always' }, { if: '$VARIABLE == null', when: 'never' }]],
- [[{ if: '$VARIABLE != "the wrong value"', when: 'always' }, { if: '$VARIABLE == null', when: 'never' }]]
- ]
+ context 'with an explicit `when: always`' do
+ where(:rule_set) do
+ [
+ [[{ if: '$VARIABLE == null', when: 'always' }]],
+ [[{ if: '$VARIABLE == null', when: 'always' }, { if: '$VARIABLE == null', when: 'never' }]],
+ [[{ if: '$VARIABLE != "the wrong value"', when: 'always' }, { if: '$VARIABLE == null', when: 'never' }]]
+ ]
+ end
+
+ with_them do
+ it { is_expected.to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'always')
+ end
+ end
end
- with_them do
- it { is_expected.to be_included }
+ context 'with an explicit `when: on_failure`' do
+ where(:rule_set) do
+ [
+ [[{ if: '$CI_JOB_NAME == "rspec" && $VAR == null', when: 'on_failure' }]],
+ [[{ if: '$VARIABLE != null', when: 'delayed', start_in: '1 day' }, { if: '$CI_JOB_NAME == "rspec"', when: 'on_failure' }]],
+ [[{ if: '$VARIABLE == "the wrong value"', when: 'delayed', start_in: '1 day' }, { if: '$CI_BUILD_NAME == "rspec"', when: 'on_failure' }]]
+ ]
+ end
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'always')
+ with_them do
+ it { is_expected.to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'on_failure')
+ end
end
end
- end
- context 'with an explicit `when: on_failure`' do
- where(:rule_set) do
- [
- [[{ if: '$CI_JOB_NAME == "rspec" && $VAR == null', when: 'on_failure' }]],
- [[{ if: '$VARIABLE != null', when: 'delayed', start_in: '1 day' }, { if: '$CI_JOB_NAME == "rspec"', when: 'on_failure' }]],
- [[{ if: '$VARIABLE == "the wrong value"', when: 'delayed', start_in: '1 day' }, { if: '$CI_BUILD_NAME == "rspec"', when: 'on_failure' }]]
- ]
+ context 'with an explicit `when: delayed`' do
+ where(:rule_set) do
+ [
+ [[{ if: '$VARIABLE == null', when: 'delayed', start_in: '1 day' }]],
+ [[{ if: '$VARIABLE == null', when: 'delayed', start_in: '1 day' }, { if: '$VARIABLE == null', when: 'never' }]],
+ [[{ if: '$VARIABLE != "the wrong value"', when: 'delayed', start_in: '1 day' }, { if: '$VARIABLE == null', when: 'never' }]]
+ ]
+ end
+
+ with_them do
+ it { is_expected.to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'delayed', options: { start_in: '1 day' })
+ end
+ end
end
- with_them do
- it { is_expected.to be_included }
+ context 'without an explicit when: value' do
+ where(:rule_set) do
+ [
+ [[{ if: '$VARIABLE == null' }]],
+ [[{ if: '$VARIABLE == null' }, { if: '$VARIABLE == null' }]],
+ [[{ if: '$VARIABLE != "the wrong value"' }, { if: '$VARIABLE == null' }]]
+ ]
+ end
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'on_failure')
+ with_them do
+ it { is_expected.to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'on_success')
+ end
end
end
end
- context 'with an explicit `when: delayed`' do
- where(:rule_set) do
- [
- [[{ if: '$VARIABLE == null', when: 'delayed', start_in: '1 day' }]],
- [[{ if: '$VARIABLE == null', when: 'delayed', start_in: '1 day' }, { if: '$VARIABLE == null', when: 'never' }]],
- [[{ if: '$VARIABLE != "the wrong value"', when: 'delayed', start_in: '1 day' }, { if: '$VARIABLE == null', when: 'never' }]]
- ]
+ context 'with a matching changes: rule' do
+ let(:pipeline) do
+ build(:ci_pipeline, project: project).tap do |pipeline|
+ stub_pipeline_modified_paths(pipeline, %w[app/models/ci/pipeline.rb spec/models/ci/pipeline_spec.rb .gitlab-ci.yml])
+ end
end
- with_them do
- it { is_expected.to be_included }
+ context 'with an explicit `when: never`' do
+ where(:rule_set) do
+ [
+ [[{ changes: { paths: %w[*/**/*.rb] }, when: 'never' }, { changes: { paths: %w[*/**/*.rb] }, when: 'always' }]],
+ [[{ changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'never' }, { changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'always' }]],
+ [[{ changes: { paths: %w[spec/**/*.rb] }, when: 'never' }, { changes: { paths: %w[spec/**/*.rb] }, when: 'always' }]],
+ [[{ changes: { paths: %w[*.yml] }, when: 'never' }, { changes: { paths: %w[*.yml] }, when: 'always' }]],
+ [[{ changes: { paths: %w[.*.yml] }, when: 'never' }, { changes: { paths: %w[.*.yml] }, when: 'always' }]],
+ [[{ changes: { paths: %w[**/*] }, when: 'never' }, { changes: { paths: %w[**/*] }, when: 'always' }]],
+ [[{ changes: { paths: %w[*/**/*.rb *.yml] }, when: 'never' }, { changes: { paths: %w[*/**/*.rb *.yml] }, when: 'always' }]],
+ [[{ changes: { paths: %w[.*.yml **/*] }, when: 'never' }, { changes: { paths: %w[.*.yml **/*] }, when: 'always' }]]
+ ]
+ end
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'delayed', options: { start_in: '1 day' })
+ with_them do
+ it { is_expected.not_to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'never')
+ end
end
end
- end
- context 'without an explicit when: value' do
- where(:rule_set) do
- [
- [[{ if: '$VARIABLE == null' }]],
- [[{ if: '$VARIABLE == null' }, { if: '$VARIABLE == null' }]],
- [[{ if: '$VARIABLE != "the wrong value"' }, { if: '$VARIABLE == null' }]]
- ]
- end
+ context 'with an explicit `when: always`' do
+ where(:rule_set) do
+ [
+ [[{ changes: { paths: %w[*/**/*.rb] }, when: 'always' }, { changes: { paths: %w[*/**/*.rb] }, when: 'never' }]],
+ [[{ changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'always' }, { changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'never' }]],
+ [[{ changes: { paths: %w[spec/**/*.rb] }, when: 'always' }, { changes: { paths: %w[spec/**/*.rb] }, when: 'never' }]],
+ [[{ changes: { paths: %w[*.yml] }, when: 'always' }, { changes: { paths: %w[*.yml] }, when: 'never' }]],
+ [[{ changes: { paths: %w[.*.yml] }, when: 'always' }, { changes: { paths: %w[.*.yml] }, when: 'never' }]],
+ [[{ changes: { paths: %w[**/*] }, when: 'always' }, { changes: { paths: %w[**/*] }, when: 'never' }]],
+ [[{ changes: { paths: %w[*/**/*.rb *.yml] }, when: 'always' }, { changes: { paths: %w[*/**/*.rb *.yml] }, when: 'never' }]],
+ [[{ changes: { paths: %w[.*.yml **/*] }, when: 'always' }, { changes: { paths: %w[.*.yml **/*] }, when: 'never' }]]
+ ]
+ end
- with_them do
- it { is_expected.to be_included }
+ with_them do
+ it { is_expected.to be_included }
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'on_success')
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'always')
+ end
end
end
- end
- end
- context 'with a matching changes: rule' do
- let(:pipeline) do
- build(:ci_pipeline, project: project).tap do |pipeline|
- stub_pipeline_modified_paths(pipeline, %w[app/models/ci/pipeline.rb spec/models/ci/pipeline_spec.rb .gitlab-ci.yml])
+ context 'without an explicit when: value' do
+ where(:rule_set) do
+ [
+ [[{ changes: { paths: %w[*/**/*.rb] } }]],
+ [[{ changes: { paths: %w[app/models/ci/pipeline.rb] } }]],
+ [[{ changes: { paths: %w[spec/**/*.rb] } }]],
+ [[{ changes: { paths: %w[*.yml] } }]],
+ [[{ changes: { paths: %w[.*.yml] } }]],
+ [[{ changes: { paths: %w[**/*] } }]],
+ [[{ changes: { paths: %w[*/**/*.rb *.yml] } }]],
+ [[{ changes: { paths: %w[.*.yml **/*] } }]]
+ ]
+ end
+
+ with_them do
+ it { is_expected.to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'on_success')
+ end
+ end
end
end
- context 'with an explicit `when: never`' do
+ context 'with no matching rule' do
where(:rule_set) do
[
- [[{ changes: { paths: %w[*/**/*.rb] }, when: 'never' }, { changes: { paths: %w[*/**/*.rb] }, when: 'always' }]],
- [[{ changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'never' }, { changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'always' }]],
- [[{ changes: { paths: %w[spec/**/*.rb] }, when: 'never' }, { changes: { paths: %w[spec/**/*.rb] }, when: 'always' }]],
- [[{ changes: { paths: %w[*.yml] }, when: 'never' }, { changes: { paths: %w[*.yml] }, when: 'always' }]],
- [[{ changes: { paths: %w[.*.yml] }, when: 'never' }, { changes: { paths: %w[.*.yml] }, when: 'always' }]],
- [[{ changes: { paths: %w[**/*] }, when: 'never' }, { changes: { paths: %w[**/*] }, when: 'always' }]],
- [[{ changes: { paths: %w[*/**/*.rb *.yml] }, when: 'never' }, { changes: { paths: %w[*/**/*.rb *.yml] }, when: 'always' }]],
- [[{ changes: { paths: %w[.*.yml **/*] }, when: 'never' }, { changes: { paths: %w[.*.yml **/*] }, when: 'always' }]]
+ [[{ if: '$VARIABLE != null', when: 'never' }]],
+ [[{ if: '$VARIABLE != null', when: 'never' }, { if: '$VARIABLE != null', when: 'always' }]],
+ [[{ if: '$VARIABLE == "the wrong value"', when: 'never' }, { if: '$VARIABLE != null', when: 'always' }]],
+ [[{ if: '$VARIABLE != null', when: 'always' }]],
+ [[{ if: '$VARIABLE != null', when: 'always' }, { if: '$VARIABLE != null', when: 'never' }]],
+ [[{ if: '$VARIABLE == "the wrong value"', when: 'always' }, { if: '$VARIABLE != null', when: 'never' }]],
+ [[{ if: '$VARIABLE != null' }]],
+ [[{ if: '$VARIABLE != null' }, { if: '$VARIABLE != null' }]],
+ [[{ if: '$VARIABLE == "the wrong value"' }, { if: '$VARIABLE != null' }]]
]
end
@@ -878,291 +971,249 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build, feature_category: :pipeline_au
end
end
- context 'with an explicit `when: always`' do
- where(:rule_set) do
- [
- [[{ changes: { paths: %w[*/**/*.rb] }, when: 'always' }, { changes: { paths: %w[*/**/*.rb] }, when: 'never' }]],
- [[{ changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'always' }, { changes: { paths: %w[app/models/ci/pipeline.rb] }, when: 'never' }]],
- [[{ changes: { paths: %w[spec/**/*.rb] }, when: 'always' }, { changes: { paths: %w[spec/**/*.rb] }, when: 'never' }]],
- [[{ changes: { paths: %w[*.yml] }, when: 'always' }, { changes: { paths: %w[*.yml] }, when: 'never' }]],
- [[{ changes: { paths: %w[.*.yml] }, when: 'always' }, { changes: { paths: %w[.*.yml] }, when: 'never' }]],
- [[{ changes: { paths: %w[**/*] }, when: 'always' }, { changes: { paths: %w[**/*] }, when: 'never' }]],
- [[{ changes: { paths: %w[*/**/*.rb *.yml] }, when: 'always' }, { changes: { paths: %w[*/**/*.rb *.yml] }, when: 'never' }]],
- [[{ changes: { paths: %w[.*.yml **/*] }, when: 'always' }, { changes: { paths: %w[.*.yml **/*] }, when: 'never' }]]
- ]
+ context 'with a rule using CI_ENVIRONMENT_NAME variable' do
+ let(:rule_set) do
+ [{ if: '$CI_ENVIRONMENT_NAME == "test"' }]
end
- with_them do
+ context 'when environment:name satisfies the rule' do
+ let(:attributes) { { name: 'rspec', rules: rule_set, environment: 'test', when: 'on_success' } }
+
it { is_expected.to be_included }
it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'always')
+ expect(seed_build.attributes).to include(when: 'on_success')
end
end
- end
- context 'without an explicit when: value' do
- where(:rule_set) do
- [
- [[{ changes: { paths: %w[*/**/*.rb] } }]],
- [[{ changes: { paths: %w[app/models/ci/pipeline.rb] } }]],
- [[{ changes: { paths: %w[spec/**/*.rb] } }]],
- [[{ changes: { paths: %w[*.yml] } }]],
- [[{ changes: { paths: %w[.*.yml] } }]],
- [[{ changes: { paths: %w[**/*] } }]],
- [[{ changes: { paths: %w[*/**/*.rb *.yml] } }]],
- [[{ changes: { paths: %w[.*.yml **/*] } }]]
- ]
+ context 'when environment:name does not satisfy rule' do
+ let(:attributes) { { name: 'rspec', rules: rule_set, environment: 'dev', when: 'on_success' } }
+
+ it { is_expected.not_to be_included }
+
+ it 'correctly populates when:' do
+ expect(seed_build.attributes).to include(when: 'never')
+ end
end
- with_them do
- it { is_expected.to be_included }
+ context 'when environment:name is not set' do
+ it { is_expected.not_to be_included }
it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'on_success')
+ expect(seed_build.attributes).to include(when: 'never')
end
end
end
- end
- context 'with no matching rule' do
- where(:rule_set) do
- [
- [[{ if: '$VARIABLE != null', when: 'never' }]],
- [[{ if: '$VARIABLE != null', when: 'never' }, { if: '$VARIABLE != null', when: 'always' }]],
- [[{ if: '$VARIABLE == "the wrong value"', when: 'never' }, { if: '$VARIABLE != null', when: 'always' }]],
- [[{ if: '$VARIABLE != null', when: 'always' }]],
- [[{ if: '$VARIABLE != null', when: 'always' }, { if: '$VARIABLE != null', when: 'never' }]],
- [[{ if: '$VARIABLE == "the wrong value"', when: 'always' }, { if: '$VARIABLE != null', when: 'never' }]],
- [[{ if: '$VARIABLE != null' }]],
- [[{ if: '$VARIABLE != null' }, { if: '$VARIABLE != null' }]],
- [[{ if: '$VARIABLE == "the wrong value"' }, { if: '$VARIABLE != null' }]]
- ]
- end
+ context 'with no rules' do
+ let(:rule_set) { [] }
- with_them do
it { is_expected.not_to be_included }
it 'correctly populates when:' do
expect(seed_build.attributes).to include(when: 'never')
end
end
- end
-
- context 'with a rule using CI_ENVIRONMENT_NAME variable' do
- let(:rule_set) do
- [{ if: '$CI_ENVIRONMENT_NAME == "test"' }]
- end
- context 'when environment:name satisfies the rule' do
- let(:attributes) { { name: 'rspec', rules: rule_set, environment: 'test', when: 'on_success' } }
-
- it { is_expected.to be_included }
-
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'on_success')
+ context 'with invalid rules raising error' do
+ let(:rule_set) do
+ [
+ { changes: { paths: ['README.md'], compare_to: 'invalid-ref' }, when: 'never' }
+ ]
end
- end
-
- context 'when environment:name does not satisfy rule' do
- let(:attributes) { { name: 'rspec', rules: rule_set, environment: 'dev', when: 'on_success' } }
it { is_expected.not_to be_included }
it 'correctly populates when:' do
expect(seed_build.attributes).to include(when: 'never')
end
- end
-
- context 'when environment:name is not set' do
- it { is_expected.not_to be_included }
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'never')
+ it 'returns an error' do
+ expect(seed_build.errors).to contain_exactly(
+ 'Failed to parse rule for rspec: rules:changes:compare_to is not a valid ref'
+ )
end
end
end
+ end
- context 'with no rules' do
- let(:rule_set) { [] }
+ describe 'applying needs: dependency' do
+ subject { seed_build }
- it { is_expected.not_to be_included }
+ let(:needs_count) { 1 }
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'never')
- end
+ let(:needs_attributes) do
+ Array.new(needs_count, name: 'build')
end
- context 'with invalid rules raising error' do
- let(:rule_set) do
- [
- { changes: { paths: ['README.md'], compare_to: 'invalid-ref' }, when: 'never' }
- ]
- end
+ let(:attributes) do
+ {
+ name: 'rspec',
+ needs_attributes: needs_attributes
+ }
+ end
- it { is_expected.not_to be_included }
+ context 'when build job is not present in prior stages' do
+ it "is included" do
+ is_expected.to be_included
+ end
- it 'correctly populates when:' do
- expect(seed_build.attributes).to include(when: 'never')
+ it "returns an error" do
+ expect(subject.errors).to contain_exactly(
+ "'rspec' job needs 'build' job, but 'build' is not in any previous stage")
end
- it 'returns an error' do
- expect(seed_build.errors).to contain_exactly(
- 'Failed to parse rule for rspec: rules:changes:compare_to is not a valid ref'
- )
+ context 'when the needed job is optional' do
+ let(:needs_attributes) { [{ name: 'build', optional: true }] }
+
+ it "does not return an error" do
+ expect(subject.errors).to be_empty
+ end
end
end
- end
- end
- describe 'applying needs: dependency' do
- subject { seed_build }
+ context 'when build job is part of prior stages' do
+ let(:stage_attributes) do
+ {
+ name: 'build',
+ index: 0,
+ builds: [{ name: 'build' }]
+ }
+ end
- let(:needs_count) { 1 }
+ let(:stage_seed) do
+ Gitlab::Ci::Pipeline::Seed::Stage.new(seed_context, stage_attributes, [])
+ end
- let(:needs_attributes) do
- Array.new(needs_count, name: 'build')
- end
+ let(:previous_stages) { [stage_seed] }
- let(:attributes) do
- {
- name: 'rspec',
- needs_attributes: needs_attributes
- }
- end
+ it "is included" do
+ is_expected.to be_included
+ end
- context 'when build job is not present in prior stages' do
- it "is included" do
- is_expected.to be_included
+ it "does not have errors" do
+ expect(subject.errors).to be_empty
+ end
end
- it "returns an error" do
- expect(subject.errors).to contain_exactly(
- "'rspec' job needs 'build' job, but 'build' is not in any previous stage")
- end
+ context 'when build job is part of the same stage' do
+ let(:current_stage) { double(seeds_names: [attributes[:name], 'build']) }
- context 'when the needed job is optional' do
- let(:needs_attributes) { [{ name: 'build', optional: true }] }
+ it 'is included' do
+ is_expected.to be_included
+ end
- it "does not return an error" do
+ it 'does not have errors' do
expect(subject.errors).to be_empty
end
end
- end
- context 'when build job is part of prior stages' do
- let(:stage_attributes) do
- {
- name: 'build',
- index: 0,
- builds: [{ name: 'build' }]
- }
- end
-
- let(:stage_seed) do
- Gitlab::Ci::Pipeline::Seed::Stage.new(seed_context, stage_attributes, [])
- end
-
- let(:previous_stages) { [stage_seed] }
+ context 'when using 101 needs' do
+ let(:needs_count) { 101 }
- it "is included" do
- is_expected.to be_included
- end
+ it "returns an error" do
+ expect(subject.errors).to contain_exactly(
+ "rspec: one job can only need 50 others, but you have listed 101. See needs keyword documentation for more details")
+ end
- it "does not have errors" do
- expect(subject.errors).to be_empty
- end
- end
+ context 'when ci_needs_size_limit is set to 100' do
+ before do
+ project.actual_limits.update!(ci_needs_size_limit: 100)
+ end
- context 'when build job is part of the same stage' do
- let(:current_stage) { double(seeds_names: [attributes[:name], 'build']) }
+ it "returns an error" do
+ expect(subject.errors).to contain_exactly(
+ "rspec: one job can only need 100 others, but you have listed 101. See needs keyword documentation for more details")
+ end
+ end
- it 'is included' do
- is_expected.to be_included
- end
+ context 'when ci_needs_size_limit is set to 0' do
+ before do
+ project.actual_limits.update!(ci_needs_size_limit: 0)
+ end
- it 'does not have errors' do
- expect(subject.errors).to be_empty
+ it "returns an error" do
+ expect(subject.errors).to contain_exactly(
+ "rspec: one job can only need 0 others, but you have listed 101. See needs keyword documentation for more details")
+ end
+ end
end
end
- context 'when using 101 needs' do
- let(:needs_count) { 101 }
+ describe 'applying pipeline variables' do
+ subject { seed_build }
- it "returns an error" do
- expect(subject.errors).to contain_exactly(
- "rspec: one job can only need 50 others, but you have listed 101. See needs keyword documentation for more details")
+ let(:pipeline_variables) { [] }
+ let(:pipeline) do
+ build(:ci_empty_pipeline, project: project, sha: head_sha, variables: pipeline_variables)
end
- context 'when ci_needs_size_limit is set to 100' do
- before do
- project.actual_limits.update!(ci_needs_size_limit: 100)
+ context 'containing variable references' do
+ let(:pipeline_variables) do
+ [
+ build(:ci_pipeline_variable, key: 'A', value: '$B'),
+ build(:ci_pipeline_variable, key: 'B', value: '$C')
+ ]
end
- it "returns an error" do
- expect(subject.errors).to contain_exactly(
- "rspec: one job can only need 100 others, but you have listed 101. See needs keyword documentation for more details")
+ it "does not have errors" do
+ expect(subject.errors).to be_empty
end
end
- context 'when ci_needs_size_limit is set to 0' do
- before do
- project.actual_limits.update!(ci_needs_size_limit: 0)
+ context 'containing cyclic reference' do
+ let(:pipeline_variables) do
+ [
+ build(:ci_pipeline_variable, key: 'A', value: '$B'),
+ build(:ci_pipeline_variable, key: 'B', value: '$C'),
+ build(:ci_pipeline_variable, key: 'C', value: '$A')
+ ]
end
it "returns an error" do
expect(subject.errors).to contain_exactly(
- "rspec: one job can only need 0 others, but you have listed 101. See needs keyword documentation for more details")
+ 'rspec: circular variable reference detected: ["A", "B", "C"]')
+ end
+
+ context 'with job:rules:[if:]' do
+ let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$C != null', when: 'always' }] } }
+
+ it "included? does not raise" do
+ expect { subject.included? }.not_to raise_error
+ end
+
+ it "included? returns true" do
+ expect(subject.included?).to eq(true)
+ end
end
end
end
end
- describe 'applying pipeline variables' do
- subject { seed_build }
-
- let(:pipeline_variables) { [] }
- let(:pipeline) do
- build(:ci_empty_pipeline, project: project, sha: head_sha, variables: pipeline_variables)
+ describe 'feature flag ci_reuse_build_in_seed_context' do
+ let(:attributes) do
+ { name: 'rspec', rules: [{ if: '$VARIABLE == null' }], when: 'on_success' }
end
- context 'containing variable references' do
- let(:pipeline_variables) do
- [
- build(:ci_pipeline_variable, key: 'A', value: '$B'),
- build(:ci_pipeline_variable, key: 'B', value: '$C')
- ]
- end
+ context 'when enabled' do
+ it_behaves_like 'build seed'
- it "does not have errors" do
- expect(subject.errors).to be_empty
+ it 'initializes the build once' do
+ expect(Ci::Build).to receive(:new).once.and_call_original
+ seed_build.to_resource
end
end
- context 'containing cyclic reference' do
- let(:pipeline_variables) do
- [
- build(:ci_pipeline_variable, key: 'A', value: '$B'),
- build(:ci_pipeline_variable, key: 'B', value: '$C'),
- build(:ci_pipeline_variable, key: 'C', value: '$A')
- ]
- end
-
- it "returns an error" do
- expect(subject.errors).to contain_exactly(
- 'rspec: circular variable reference detected: ["A", "B", "C"]')
+ context 'when disabled' do
+ before do
+ stub_feature_flags(ci_reuse_build_in_seed_context: false)
end
- context 'with job:rules:[if:]' do
- let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$C != null', when: 'always' }] } }
-
- it "included? does not raise" do
- expect { subject.included? }.not_to raise_error
- end
+ it_behaves_like 'build seed'
- it "included? returns true" do
- expect(subject.included?).to eq(true)
- end
+ it 'initializes the build twice' do
+ expect(Ci::Build).to receive(:new).twice.and_call_original
+ seed_build.to_resource
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
index a632b5dedcf..288ac3f3854 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::Pipeline::Seed::Stage do
+RSpec.describe Gitlab::Ci::Pipeline::Seed::Stage, feature_category: :pipeline_authoring do
let(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:previous_stages) { [] }
diff --git a/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb b/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
index 9c27005065d..bfe5815fa00 100644
--- a/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
+++ b/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
@@ -6,7 +6,7 @@ require_migration!
RSpec.describe FinalizeGroupMemberNamespaceIdMigration, :migration do
let(:batched_migrations) { table(:batched_background_migrations) }
- let_it_be(:migration) { described_class::MIGRATION }
+ let!(:migration) { described_class::MIGRATION }
describe '#up' do
shared_examples 'finalizes the migration' do
diff --git a/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb b/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb
index f4e2b1bd5af..2cd483cfb7a 100644
--- a/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb
+++ b/spec/migrations/20221018095434_schedule_disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb
@@ -4,8 +4,8 @@ require 'spec_helper'
require_migration!
RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForProjectsLessThanFiveMb do
- let_it_be(:migration) { described_class.new }
- let_it_be(:post_migration) { described_class::MIGRATION }
+ let!(:migration) { described_class.new }
+ let!(:post_migration) { described_class::MIGRATION }
context 'when on gitlab.com' do
before do
diff --git a/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb b/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb
index 3c467f1a437..d0c25fb3dd6 100644
--- a/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb
+++ b/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb
@@ -6,7 +6,7 @@ require_migration!
RSpec.describe FinalizeIssuesNamespaceIdBackfilling, :migration, feature_category: :team_planning do
let(:batched_migrations) { table(:batched_background_migrations) }
- let_it_be(:migration) { described_class::MIGRATION }
+ let!(:migration) { described_class::MIGRATION }
describe '#up' do
shared_examples 'finalizes the migration' do
diff --git a/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb b/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb
index 028e230af3e..9c2afb7cf21 100644
--- a/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb
+++ b/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb
@@ -46,25 +46,25 @@ RSpec.describe InsertCiDailyPipelineScheduleTriggersPlanLimits do
end
context 'when on self hosted' do
- let(:free_plan) { plans.create!(name: 'free') }
+ let(:default_plan) { plans.create!(name: 'default') }
before do
allow(Gitlab).to receive(:com?).and_return(false)
- plan_limits.create!(plan_id: free_plan.id)
+ plan_limits.create!(plan_id: default_plan.id)
end
it 'does nothing' do
reversible_migration do |migration|
migration.before -> {
expect(plan_limits.pluck(:plan_id, :ci_daily_pipeline_schedule_triggers)).to contain_exactly(
- [free_plan.id, 0]
+ [default_plan.id, 0]
)
}
migration.after -> {
expect(plan_limits.pluck(:plan_id, :ci_daily_pipeline_schedule_triggers)).to contain_exactly(
- [free_plan.id, 0]
+ [default_plan.id, 0]
)
}
end
diff --git a/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb b/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb
index e958593dc19..c4c7819bda7 100644
--- a/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb
+++ b/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb
@@ -3,20 +3,21 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleFixingSecurityScanStatuses, feature_category: :vulnerability_management do
- let_it_be(:namespaces) { table(:namespaces) }
- let_it_be(:projects) { table(:projects) }
- let_it_be(:pipelines) { table(:ci_pipelines) }
- let_it_be(:builds) { table(:ci_builds) }
- let_it_be(:security_scans) { table(:security_scans) }
-
- let_it_be(:namespace) { namespaces.create!(name: "foo", path: "bar") }
- let_it_be(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
- let_it_be(:pipeline) do
+RSpec.describe ScheduleFixingSecurityScanStatuses, :suppress_gitlab_schemas_validate_connection,
+ feature_category: :vulnerability_management do
+ let!(:namespaces) { table(:namespaces) }
+ let!(:projects) { table(:projects) }
+ let!(:pipelines) { table(:ci_pipelines) }
+ let!(:builds) { table(:ci_builds) }
+ let!(:security_scans) { table(:security_scans) }
+
+ let!(:namespace) { namespaces.create!(name: "foo", path: "bar") }
+ let!(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
+ let!(:pipeline) do
pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success', partition_id: 1)
end
- let_it_be(:ci_build) { builds.create!(commit_id: pipeline.id, retried: false, type: 'Ci::Build', partition_id: 1) }
+ let!(:ci_build) { builds.create!(commit_id: pipeline.id, retried: false, type: 'Ci::Build', partition_id: 1) }
let!(:security_scan_1) { security_scans.create!(build_id: ci_build.id, scan_type: 1, created_at: 91.days.ago) }
let!(:security_scan_2) { security_scans.create!(build_id: ci_build.id, scan_type: 2) }
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index 471253bc2f7..40307cc9c2f 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Ci::PipelineSchedule do
+RSpec.describe Ci::PipelineSchedule, feature_category: :continuous_integration do
let_it_be_with_reload(:project) { create_default(:project) }
subject { build(:ci_pipeline_schedule) }
@@ -42,7 +42,7 @@ RSpec.describe Ci::PipelineSchedule do
end
it 'does not allow empty variable key' do
- pipeline_schedule = build(:ci_pipeline_schedule, variables_attributes: [{ secret_value: 'test_value' }] )
+ pipeline_schedule = build(:ci_pipeline_schedule, variables_attributes: [{ secret_value: 'test_value' }])
expect(pipeline_schedule).not_to be_valid
end
@@ -116,48 +116,18 @@ RSpec.describe Ci::PipelineSchedule do
end
describe '#set_next_run_at' do
- using RSpec::Parameterized::TableSyntax
-
- where(:worker_cron, :schedule_cron, :plan_limit, :now, :result) do
- '0 1 2 3 *' | '0 1 * * *' | nil | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
- '0 1 2 3 *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
- '*/5 * * * *' | '*/1 * * * *' | nil | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 5)
- '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
- '*/5 * * * *' | '*/1 * * * *' | (1.day.in_minutes / 10).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
- '*/5 * * * *' | '*/1 * * * *' | 200 | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
- '*/5 * * * *' | '0 * * * *' | nil | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 10).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
- '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 2.hours.in_minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
- '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
- '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 10).to_i | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
- '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 8).to_i | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
- '*/5 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 1, 1, 0) | Time.zone.local(2021, 6, 1, 1, 0)
- '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 0)
- '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0)
- '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 45)
- end
-
- with_them do
- let(:pipeline_schedule) { create(:ci_pipeline_schedule, cron: schedule_cron) }
+ let(:now) { Time.zone.local(2021, 3, 2, 1, 0) }
+ let(:pipeline_schedule) { create(:ci_pipeline_schedule, cron: "0 1 * * *") }
- before do
- allow(Settings).to receive(:cron_jobs) do
- { 'pipeline_schedule_worker' => { 'cron' => worker_cron } }
- end
+ it 'calls fallback method next_run_at if there is no plan limit' do
+ allow(Settings).to receive(:cron_jobs).and_return({ 'pipeline_schedule_worker' => { 'cron' => "0 1 2 3 *" } })
- create(:plan_limits, :default_plan, ci_daily_pipeline_schedule_triggers: plan_limit) if plan_limit
-
- # Setting this here to override initial save with the current time
- pipeline_schedule.next_run_at = now
- end
+ travel_to(now) do
+ expect(pipeline_schedule).to receive(:calculate_next_run_at).and_call_original
- it 'updates next_run_at' do
- travel_to(now) do
- pipeline_schedule.set_next_run_at
+ pipeline_schedule.set_next_run_at
- expect(pipeline_schedule.next_run_at).to eq(result)
- end
+ expect(pipeline_schedule.next_run_at).to eq(Time.zone.local(2022, 3, 2, 1, 0))
end
end
diff --git a/spec/requests/api/ci/jobs_spec.rb b/spec/requests/api/ci/jobs_spec.rb
index f53335c2da2..4e348ae64b6 100644
--- a/spec/requests/api/ci/jobs_spec.rb
+++ b/spec/requests/api/ci/jobs_spec.rb
@@ -487,6 +487,46 @@ RSpec.describe API::Ci::Jobs, feature_category: :continuous_integration do
end
end
+ describe 'GET /projects/:id/jobs rate limited' do
+ let(:query) { {} }
+
+ context 'with the ci_enforce_rate_limits_jobs_api feature flag on' do
+ before do
+ stub_feature_flags(ci_enforce_rate_limits_jobs_api: true)
+
+ allow_next_instance_of(Gitlab::ApplicationRateLimiter::BaseStrategy) do |strategy|
+ threshold = Gitlab::ApplicationRateLimiter.rate_limits[:jobs_index][:threshold]
+ allow(strategy).to receive(:increment).and_return(threshold + 1)
+ end
+
+ get api("/projects/#{project.id}/jobs", api_user), params: query
+ end
+
+ it 'enforces rate limits for the endpoint' do
+ expect(response).to have_gitlab_http_status :too_many_requests
+ expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
+ end
+ end
+
+ context 'with the ci_enforce_rate_limits_jobs_api feature flag off' do
+ before do
+ stub_feature_flags(ci_enforce_rate_limits_jobs_api: false)
+
+ allow_next_instance_of(Gitlab::ApplicationRateLimiter::BaseStrategy) do |strategy|
+ threshold = Gitlab::ApplicationRateLimiter.rate_limits[:jobs_index][:threshold]
+ allow(strategy).to receive(:increment).and_return(threshold + 1)
+ end
+
+ get api("/projects/#{project.id}/jobs", api_user), params: query
+ end
+
+ it 'makes a successful request' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_limited_pagination_headers
+ end
+ end
+ end
+
describe 'GET /projects/:id/jobs/:job_id' do
before do |example|
unless example.metadata[:skip_before_request]
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index a09204dd94a..b2a7c523cb0 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -489,6 +489,9 @@ RSpec.describe 'Query.runner(id)', feature_category: :runner do
projects {
nodes {
id
+ path
+ fullPath
+ webUrl
}
}
ownerProject {
diff --git a/spec/requests/api/integrations/jira_connect/subscriptions_spec.rb b/spec/requests/api/integrations/jira_connect/subscriptions_spec.rb
index 762cbd5df10..8d7b462771d 100644
--- a/spec/requests/api/integrations/jira_connect/subscriptions_spec.rb
+++ b/spec/requests/api/integrations/jira_connect/subscriptions_spec.rb
@@ -20,20 +20,6 @@ RSpec.describe API::Integrations::JiraConnect::Subscriptions, feature_category:
post api('/integrations/jira_connect/subscriptions', user), params: { jwt: jwt, namespace_path: group.path }
end
- context 'with feature flag disabled' do
- before do
- stub_feature_flags(jira_connect_oauth: false)
- end
-
- let(:jwt) { '123' }
-
- it 'returns 404' do
- post_subscriptions
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
context 'with invalid JWT' do
let(:jwt) { '123' }
diff --git a/spec/requests/ide_controller_spec.rb b/spec/requests/ide_controller_spec.rb
index 6786d313ce3..d6d5a2710bf 100644
--- a/spec/requests/ide_controller_spec.rb
+++ b/spec/requests/ide_controller_spec.rb
@@ -21,6 +21,18 @@ RSpec.describe IdeController, feature_category: :web_ide do
let(:user) { creator }
let(:branch) { '' }
+ def find_csp_frame_src
+ csp = response.headers['Content-Security-Policy']
+
+ # Transform "frame-src foo bar; connect-src foo bar; script-src ..."
+ # into array of connect-src values
+ csp.split(';')
+ .map(&:strip)
+ .find { |entry| entry.starts_with?('frame-src') }
+ .split(' ')
+ .drop(1)
+ end
+
before do
sign_in(user)
end
@@ -265,5 +277,32 @@ RSpec.describe IdeController, feature_category: :web_ide do
end
end
end
+
+ describe 'frame-src content security policy' do
+ let(:route) { '/-/ide' }
+
+ before do
+ subject
+ end
+
+ it 'adds https://*.vscode-cdn.net in frame-src CSP policy' do
+ expect(find_csp_frame_src).to include("https://*.vscode-cdn.net/")
+ end
+ end
+
+ describe 'when vscode_web_ide feature flag is disabled' do
+ describe 'frame-src content security policy' do
+ let(:route) { '/-/ide' }
+
+ before do
+ stub_feature_flags(vscode_web_ide: false)
+ subject
+ end
+
+ it 'does not add https://*.vscode-cdn.net in frame-src CSP policy' do
+ expect(find_csp_frame_src).not_to include("https://*.vscode-cdn.net/")
+ end
+ end
+ end
end
end
diff --git a/spec/requests/web_ide/remote_ide_controller_spec.rb b/spec/requests/web_ide/remote_ide_controller_spec.rb
index 9b99da3469c..ee8a89200fa 100644
--- a/spec/requests/web_ide/remote_ide_controller_spec.rb
+++ b/spec/requests/web_ide/remote_ide_controller_spec.rb
@@ -63,13 +63,17 @@ RSpec.describe WebIde::RemoteIdeController, feature_category: :remote_developmen
end
it "updates the content security policy with the correct connect sources" do
- expect(find_csp_connect_src).to include(
+ expect(find_csp_source('connect-src')).to include(
"ws://#{remote_host}",
"wss://#{remote_host}",
"http://#{remote_host}",
"https://#{remote_host}"
)
end
+
+ it "updates the content security policy with the correct frame sources" do
+ expect(find_csp_source('frame-src')).to include("https://*.vscode-cdn.net/")
+ end
end
context 'when remote_host does not have port' do
@@ -80,7 +84,7 @@ RSpec.describe WebIde::RemoteIdeController, feature_category: :remote_developmen
end
it "updates the content security policy with the correct remote_host" do
- expect(find_csp_connect_src).to include(
+ expect(find_csp_source('connect-src')).to include(
"ws://#{remote_host}",
"wss://#{remote_host}",
"http://#{remote_host}",
@@ -97,6 +101,12 @@ RSpec.describe WebIde::RemoteIdeController, feature_category: :remote_developmen
let(:ff_vscode_web_ide) { false }
it_behaves_like '404 response'
+
+ it 'does not the content security policy with the correct frame sources' do
+ post_to_remote_ide
+
+ expect(find_csp_source('frame-src')).not_to include("https://*.vscode-cdn.net/")
+ end
end
context "when the remote host is invalid" do
@@ -118,14 +128,14 @@ RSpec.describe WebIde::RemoteIdeController, feature_category: :remote_developmen
}
end
- def find_csp_connect_src
+ def find_csp_source(key)
csp = response.headers['Content-Security-Policy']
# Transform "default-src foo bar; connect-src foo bar; script-src ..."
- # into array of connect-src values
+ # into array of values for a single directive based on the given key
csp.split(';')
.map(&:strip)
- .find { |entry| entry.starts_with?('connect-src') }
+ .find { |entry| entry.starts_with?(key) }
.split(' ')
.drop(1)
end
diff --git a/spec/rubocop/cop/rspec/avoid_test_prof_spec.rb b/spec/rubocop/cop/rspec/avoid_test_prof_spec.rb
new file mode 100644
index 00000000000..b180134b226
--- /dev/null
+++ b/spec/rubocop/cop/rspec/avoid_test_prof_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require 'rspec-parameterized'
+
+require_relative '../../../../rubocop/cop/rspec/avoid_test_prof'
+
+RSpec.describe RuboCop::Cop::RSpec::AvoidTestProf, feature_category: :not_owned do
+ using RSpec::Parameterized::TableSyntax
+
+ context 'when there are offenses' do
+ where(:method_call, :method_name, :alternatives) do
+ 'let_it_be(:user)' | 'let_it_be' | '`let` or `let!`'
+ 'let_it_be_with_reload(:user)' | 'let_it_be_with_reload' | '`let` or `let!`'
+ 'let_it_be_with_refind(:user)' | 'let_it_be_with_refind' | '`let` or `let!`'
+ 'before_all' | 'before_all' | '`before` or `before(:all)`'
+ end
+
+ with_them do
+ it 'registers the offense' do
+ error_message = "Prefer #{alternatives} over `#{method_name}` in migration specs. " \
+ 'See ' \
+ 'https://docs.gitlab.com/ee/development/testing_guide/best_practices.html' \
+ '#testprof-in-migration-specs'
+
+ expect_offense(<<~RUBY)
+ describe 'foo' do
+ #{method_call} { table(:users) }
+ #{'^' * method_call.size} #{error_message}
+ end
+ RUBY
+ end
+ end
+ end
+
+ context 'when there are no offenses' do
+ where(method_call: %w[let(:user) let!(:user) before before(:all)])
+
+ with_them do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~RUBY)
+ describe 'foo' do
+ #{method_call} { table(:users) }
+ end
+ RUBY
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/pipeline_schedules/calculate_next_run_service_spec.rb b/spec/services/ci/pipeline_schedules/calculate_next_run_service_spec.rb
new file mode 100644
index 00000000000..182c5bebbc1
--- /dev/null
+++ b/spec/services/ci/pipeline_schedules/calculate_next_run_service_spec.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+# rubocop:disable Layout/LineLength
+require 'spec_helper'
+
+RSpec.describe Ci::PipelineSchedules::CalculateNextRunService, feature_category: :continuous_integration do
+ let_it_be(:project) { create(:project, :public, :repository) }
+
+ describe '#execute' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:run_service) do
+ described_class.new(project).execute(pipeline_schedule,
+ fallback_method: pipeline_schedule.method(:calculate_next_run_at))
+ end
+
+ let(:pipeline_schedule) { create(:ci_pipeline_schedule, cron: schedule_cron) }
+ let(:daily_limit_of_144_runs) { 1.day / 10.minutes }
+ let(:daily_limit_of_24_runs) { 1.day / 1.hour }
+
+ before do
+ allow(Settings).to receive(:cron_jobs) { { 'pipeline_schedule_worker' => { 'cron' => worker_cron } } }
+ create(:plan_limits, :default_plan, ci_daily_pipeline_schedule_triggers: plan_limit) if plan_limit
+ end
+
+ context "when there is invalid or no plan limits" do
+ where(:worker_cron, :schedule_cron, :plan_limit, :now, :expected_result) do
+ '0 1 2 3 *' | '0 1 * * *' | nil | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
+ '*/5 * * * *' | '*/1 * * * *' | nil | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 5)
+ '*/5 * * * *' | '0 * * * *' | nil | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
+ # 1.day / 2.hours => 12 times a day and it is invalid because there is a minimum for plan limits.
+ # See: https://docs.gitlab.com/ee/administration/instance_limits.html#limit-the-number-of-pipelines-created-by-a-pipeline-schedule-per-day
+ '*/5 * * * *' | '0 * * * *' | 1.day / 2.hours | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5)
+ end
+
+ with_them do
+ it 'calls fallback method to get next_run_at' do
+ travel_to(now) do
+ expect(pipeline_schedule).to receive(:calculate_next_run_at).and_call_original
+
+ result = run_service
+
+ expect(result).to eq(expected_result)
+ end
+ end
+ end
+ end
+
+ context "when the workers next run matches schedule's earliest run" do
+ where(:worker_cron, :schedule_cron, :plan_limit, :now, :expected_result) do
+ '*/5 * * * *' | '0 * * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
+ '*/5 * * * *' | '*/5 * * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
+ '*/5 * * * *' | '0 1 * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0)
+ '*/5 * * * *' | '0 2 * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 27, 2, 0)
+ '*/5 * * * *' | '0 3 * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 27, 3, 0)
+ '*/5 * * * *' | '0 1 1 * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 1, 1, 0) | Time.zone.local(2021, 6, 1, 1, 0)
+ '*/9 * * * *' | '0 1 1 * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 0)
+ '*/5 * * * *' | '45 21 1 2 *' | daily_limit_of_144_runs | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 45)
+ end
+
+ with_them do
+ it 'calculates the next_run_at to be earliest point of match' do
+ travel_to(now) do
+ result = run_service
+
+ expect(result).to eq(expected_result)
+ end
+ end
+ end
+ end
+
+ context "when next_run_at is restricted by plan limit" do
+ where(:worker_cron, :schedule_cron, :plan_limit, :now, :expected_result) do
+ '*/5 * * * *' | '59 14 * * *' | daily_limit_of_24_runs | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0)
+ '*/5 * * * *' | '*/1 * * * *' | daily_limit_of_24_runs | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0)
+ '*/5 * * * *' | '*/1 * * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
+ '*/5 * * * *' | '*/1 * * * *' | (1.day / 7.minutes).to_i | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 11, 10)
+ end
+
+ with_them do
+ it 'calculates the next_run_at based on next available limit' do
+ travel_to(now) do
+ result = run_service
+
+ expect(result).to eq(expected_result)
+ end
+ end
+ end
+ end
+
+ context "when next_run_at is restricted by worker's availability" do
+ where(:worker_cron, :schedule_cron, :plan_limit, :now, :expected_result) do
+ '0 1 2 3 *' | '0 1 * * *' | daily_limit_of_144_runs | Time.zone.local(2021, 3, 2, 1, 0) | Time.zone.local(2022, 3, 2, 1, 0)
+ end
+
+ with_them do
+ it 'calculates the next_run_at using worker_cron' do
+ travel_to(now) do
+ result = run_service
+
+ expect(result).to eq(expected_result)
+ end
+ end
+ end
+ end
+ end
+end
+# rubocop:enable Layout/LineLength
diff --git a/spec/support/shared_examples/csp.rb b/spec/support/shared_examples/csp.rb
index 91242ae9f37..725d0a832c2 100644
--- a/spec/support/shared_examples/csp.rb
+++ b/spec/support/shared_examples/csp.rb
@@ -29,7 +29,8 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
context 'when feature is enabled' do
it "appends to #{rule_name}" do
- is_expected.to eql("#{rule_name} #{default_csp_values} #{allowlisted_url}")
+ is_expected.to include("#{rule_name} #{default_csp_values}")
+ is_expected.to include(allowlisted_url)
end
end
@@ -37,7 +38,7 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
include_context 'disable feature'
it "keeps original #{rule_name}" do
- is_expected.to eql("#{rule_name} #{default_csp_values}")
+ is_expected.to include("#{rule_name} #{default_csp_values}")
end
end
end
@@ -47,7 +48,8 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
context 'when feature is enabled' do
it "uses default-src values in #{rule_name}" do
- is_expected.to eql("default-src #{default_csp_values}; #{rule_name} #{default_csp_values} #{allowlisted_url}")
+ is_expected.to include("default-src #{default_csp_values}")
+ is_expected.to include(allowlisted_url)
end
end
@@ -55,7 +57,7 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
include_context 'disable feature'
it "does not add #{rule_name}" do
- is_expected.to eql("default-src #{default_csp_values}")
+ is_expected.to include("default-src #{default_csp_values}")
end
end
end
@@ -65,7 +67,8 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
context 'when feature is enabled' do
it "uses default-src values in #{rule_name}" do
- is_expected.to eql("font-src #{default_csp_values}; #{rule_name} #{allowlisted_url}")
+ is_expected.to include("font-src #{default_csp_values}")
+ is_expected.not_to include("#{rule_name} #{default_csp_values}")
end
end
@@ -73,7 +76,7 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
include_context 'disable feature'
it "does not add #{rule_name}" do
- is_expected.to eql("font-src #{default_csp_values}")
+ is_expected.to include("font-src #{default_csp_values}")
end
end
end
diff --git a/spec/tasks/gitlab/feature_categories_rake_spec.rb b/spec/tasks/gitlab/feature_categories_rake_spec.rb
new file mode 100644
index 00000000000..22f36309a7c
--- /dev/null
+++ b/spec/tasks/gitlab/feature_categories_rake_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'rake_helper'
+
+RSpec.describe 'gitlab:feature_categories:index', :silence_stdout, feature_category: :scalability do
+ before do
+ Rake.application.rake_require 'tasks/gitlab/feature_categories'
+ end
+
+ it 'outputs objects by stage group' do
+ # Sample items that _hopefully_ won't change very often.
+ expected = {
+ 'controller_actions' => a_hash_including(
+ 'integrations' => a_collection_including(
+ klass: 'Oauth::JiraDvcs::AuthorizationsController',
+ action: 'new',
+ source_location: [
+ 'app/controllers/oauth/jira_dvcs/authorizations_controller.rb',
+ an_instance_of(Integer)
+ ]
+ )
+ ),
+ 'api_endpoints' => a_hash_including(
+ 'authentication_and_authorization' => a_collection_including(
+ klass: 'API::AccessRequests',
+ action: '/groups/:id/access_requests',
+ source_location: [
+ 'lib/api/access_requests.rb',
+ an_instance_of(Integer)
+ ]
+ )
+ ),
+ 'sidekiq_workers' => a_hash_including(
+ 'source_code_management' => a_collection_including(
+ klass: 'MergeWorker',
+ source_location: [
+ 'app/workers/merge_worker.rb',
+ an_instance_of(Integer)
+ ]
+ )
+ ),
+ 'database_tables' => a_hash_including(
+ 'container_scanning' => a_collection_including('vulnerability_advisories')
+ )
+ }
+
+ expect(YAML).to receive(:dump).with(a_hash_including(expected))
+
+ run_rake_task('gitlab:feature_categories:index')
+ end
+end
diff --git a/yarn.lock b/yarn.lock
index 19a19b884ce..dc500fb2d5c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -80,33 +80,33 @@
tslib "^2.3.0"
zen-observable-ts "^1.2.0"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.18.6":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
dependencies:
"@babel/highlight" "^7.18.6"
-"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.10":
- version "7.17.10"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab"
- integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==
+"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.10", "@babel/compat-data@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.0.tgz#2a592fd89bacb1fcde68de31bee4f2f2dacb0e86"
+ integrity sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==
-"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.17.0", "@babel/core@^7.18.5", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
- version "7.18.5"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.5.tgz#c597fa680e58d571c28dda9827669c78cdd7f000"
- integrity sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==
+"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.17.0", "@babel/core@^7.18.5":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.0.tgz#d2f5f4f2033c00de8096be3c9f45772563e150c3"
+ integrity sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==
dependencies:
"@ampproject/remapping" "^2.1.0"
- "@babel/code-frame" "^7.16.7"
- "@babel/generator" "^7.18.2"
- "@babel/helper-compilation-targets" "^7.18.2"
- "@babel/helper-module-transforms" "^7.18.0"
- "@babel/helpers" "^7.18.2"
- "@babel/parser" "^7.18.5"
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.18.5"
- "@babel/types" "^7.18.4"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.19.0"
+ "@babel/helper-compilation-targets" "^7.19.0"
+ "@babel/helper-module-transforms" "^7.19.0"
+ "@babel/helpers" "^7.19.0"
+ "@babel/parser" "^7.19.0"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
@@ -129,13 +129,13 @@
dependencies:
eslint-rule-composer "^0.3.0"
-"@babel/generator@^7.18.2", "@babel/generator@^7.7.2":
- version "7.18.2"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d"
- integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==
+"@babel/generator@^7.19.0", "@babel/generator@^7.7.2":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a"
+ integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==
dependencies:
- "@babel/types" "^7.18.2"
- "@jridgewell/gen-mapping" "^0.3.0"
+ "@babel/types" "^7.19.0"
+ "@jridgewell/gen-mapping" "^0.3.2"
jsesc "^2.5.1"
"@babel/helper-annotate-as-pure@^7.16.7":
@@ -153,13 +153,13 @@
"@babel/helper-explode-assignable-expression" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.10", "@babel/helper-compilation-targets@^7.18.2":
- version "7.18.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz#67a85a10cbd5fc7f1457fec2e7f45441dc6c754b"
- integrity sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==
+"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.10", "@babel/helper-compilation-targets@^7.18.2", "@babel/helper-compilation-targets@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz#537ec8339d53e806ed422f1e06c8f17d55b96bb0"
+ integrity sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==
dependencies:
- "@babel/compat-data" "^7.17.10"
- "@babel/helper-validator-option" "^7.16.7"
+ "@babel/compat-data" "^7.19.0"
+ "@babel/helper-validator-option" "^7.18.6"
browserslist "^4.20.2"
semver "^6.3.0"
@@ -198,10 +198,10 @@
resolve "^1.14.2"
semver "^6.1.2"
-"@babel/helper-environment-visitor@^7.16.7", "@babel/helper-environment-visitor@^7.18.2":
- version "7.18.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz#8a6d2dedb53f6bf248e31b4baf38739ee4a637bd"
- integrity sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==
+"@babel/helper-environment-visitor@^7.16.7", "@babel/helper-environment-visitor@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
+ integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
"@babel/helper-explode-assignable-expression@^7.16.7":
version "7.16.7"
@@ -210,20 +210,20 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9":
- version "7.17.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12"
- integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==
+"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9", "@babel/helper-function-name@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+ integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
dependencies:
- "@babel/template" "^7.16.7"
- "@babel/types" "^7.17.0"
+ "@babel/template" "^7.18.10"
+ "@babel/types" "^7.19.0"
-"@babel/helper-hoist-variables@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246"
- integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==
+"@babel/helper-hoist-variables@^7.16.7", "@babel/helper-hoist-variables@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
+ integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
dependencies:
- "@babel/types" "^7.16.7"
+ "@babel/types" "^7.18.6"
"@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7":
version "7.17.7"
@@ -232,26 +232,26 @@
dependencies:
"@babel/types" "^7.17.0"
-"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
- integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
+"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
+ integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
dependencies:
- "@babel/types" "^7.16.7"
+ "@babel/types" "^7.18.6"
-"@babel/helper-module-transforms@^7.18.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz#baf05dec7a5875fb9235bd34ca18bad4e21221cd"
- integrity sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==
+"@babel/helper-module-transforms@^7.18.0", "@babel/helper-module-transforms@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
+ integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
dependencies:
- "@babel/helper-environment-visitor" "^7.16.7"
- "@babel/helper-module-imports" "^7.16.7"
- "@babel/helper-simple-access" "^7.17.7"
- "@babel/helper-split-export-declaration" "^7.16.7"
- "@babel/helper-validator-identifier" "^7.16.7"
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.18.0"
- "@babel/types" "^7.18.0"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-module-imports" "^7.18.6"
+ "@babel/helper-simple-access" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/helper-validator-identifier" "^7.18.6"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
"@babel/helper-optimise-call-expression@^7.16.7":
version "7.16.7"
@@ -285,12 +285,12 @@
"@babel/traverse" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-simple-access@^7.17.7", "@babel/helper-simple-access@^7.18.2":
- version "7.18.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9"
- integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==
+"@babel/helper-simple-access@^7.18.2", "@babel/helper-simple-access@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea"
+ integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==
dependencies:
- "@babel/types" "^7.18.2"
+ "@babel/types" "^7.18.6"
"@babel/helper-skip-transparent-expression-wrappers@^7.16.0":
version "7.16.0"
@@ -299,22 +299,27 @@
dependencies:
"@babel/types" "^7.16.0"
-"@babel/helper-split-export-declaration@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b"
- integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
+"@babel/helper-split-export-declaration@^7.16.7", "@babel/helper-split-export-declaration@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
+ integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
dependencies:
- "@babel/types" "^7.16.7"
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-string-parser@^7.18.10":
+ version "7.18.10"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56"
+ integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==
"@babel/helper-validator-identifier@^7.15.7", "@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.18.6":
- version "7.19.1"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
- integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
+ integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
-"@babel/helper-validator-option@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
- integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
+"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
+ integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
"@babel/helper-wrap-function@^7.16.8":
version "7.16.8"
@@ -326,14 +331,14 @@
"@babel/traverse" "^7.16.8"
"@babel/types" "^7.16.8"
-"@babel/helpers@^7.18.2":
- version "7.18.2"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.2.tgz#970d74f0deadc3f5a938bfa250738eb4ac889384"
- integrity sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==
+"@babel/helpers@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18"
+ integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==
dependencies:
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.18.2"
- "@babel/types" "^7.18.2"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
"@babel/highlight@^7.18.6":
version "7.18.6"
@@ -344,10 +349,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.16.8", "@babel/parser@^7.18.5":
- version "7.18.11"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9"
- integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==
+"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.8", "@babel/parser@^7.18.10", "@babel/parser@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c"
+ integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.17.12":
version "7.17.12"
@@ -978,37 +983,38 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/template@^7.16.7", "@babel/template@^7.3.3":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
- integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
+"@babel/template@^7.16.7", "@babel/template@^7.18.10", "@babel/template@^7.3.3":
+ version "7.18.10"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
+ integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
dependencies:
- "@babel/code-frame" "^7.16.7"
- "@babel/parser" "^7.16.7"
- "@babel/types" "^7.16.7"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/parser" "^7.18.10"
+ "@babel/types" "^7.18.10"
-"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2", "@babel/traverse@^7.18.5", "@babel/traverse@^7.7.2":
- version "7.18.5"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.5.tgz#94a8195ad9642801837988ab77f36e992d9a20cd"
- integrity sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==
+"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.19.0", "@babel/traverse@^7.7.2":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.0.tgz#eb9c561c7360005c592cc645abafe0c3c4548eed"
+ integrity sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==
dependencies:
- "@babel/code-frame" "^7.16.7"
- "@babel/generator" "^7.18.2"
- "@babel/helper-environment-visitor" "^7.18.2"
- "@babel/helper-function-name" "^7.17.9"
- "@babel/helper-hoist-variables" "^7.16.7"
- "@babel/helper-split-export-declaration" "^7.16.7"
- "@babel/parser" "^7.18.5"
- "@babel/types" "^7.18.4"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.19.0"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.19.0"
+ "@babel/types" "^7.19.0"
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
- version "7.18.4"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354"
- integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==
+"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.18.10", "@babel/types@^7.18.2", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600"
+ integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==
dependencies:
- "@babel/helper-validator-identifier" "^7.16.7"
+ "@babel/helper-string-parser" "^7.18.10"
+ "@babel/helper-validator-identifier" "^7.18.6"
to-fast-properties "^2.0.0"
"@bcoe/v8-coverage@^0.2.3":
@@ -1367,163 +1373,186 @@
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
-"@jest/console@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba"
- integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==
+"@jest/console@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df"
+ integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==
dependencies:
- "@jest/types" "^27.5.1"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
chalk "^4.0.0"
- jest-message-util "^27.5.1"
- jest-util "^27.5.1"
+ jest-message-util "^28.1.3"
+ jest-util "^28.1.3"
slash "^3.0.0"
-"@jest/core@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626"
- integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==
+"@jest/core@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7"
+ integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==
dependencies:
- "@jest/console" "^27.5.1"
- "@jest/reporters" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/transform" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/console" "^28.1.3"
+ "@jest/reporters" "^28.1.3"
+ "@jest/test-result" "^28.1.3"
+ "@jest/transform" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
ansi-escapes "^4.2.1"
chalk "^4.0.0"
- emittery "^0.8.1"
+ ci-info "^3.2.0"
exit "^0.1.2"
graceful-fs "^4.2.9"
- jest-changed-files "^27.5.1"
- jest-config "^27.5.1"
- jest-haste-map "^27.5.1"
- jest-message-util "^27.5.1"
- jest-regex-util "^27.5.1"
- jest-resolve "^27.5.1"
- jest-resolve-dependencies "^27.5.1"
- jest-runner "^27.5.1"
- jest-runtime "^27.5.1"
- jest-snapshot "^27.5.1"
- jest-util "^27.5.1"
- jest-validate "^27.5.1"
- jest-watcher "^27.5.1"
+ jest-changed-files "^28.1.3"
+ jest-config "^28.1.3"
+ jest-haste-map "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-regex-util "^28.0.2"
+ jest-resolve "^28.1.3"
+ jest-resolve-dependencies "^28.1.3"
+ jest-runner "^28.1.3"
+ jest-runtime "^28.1.3"
+ jest-snapshot "^28.1.3"
+ jest-util "^28.1.3"
+ jest-validate "^28.1.3"
+ jest-watcher "^28.1.3"
micromatch "^4.0.4"
+ pretty-format "^28.1.3"
rimraf "^3.0.0"
slash "^3.0.0"
strip-ansi "^6.0.0"
-"@jest/environment@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74"
- integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==
+"@jest/environment@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e"
+ integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==
dependencies:
- "@jest/fake-timers" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/fake-timers" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
- jest-mock "^27.5.1"
+ jest-mock "^28.1.3"
-"@jest/fake-timers@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74"
- integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==
+"@jest/expect-utils@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525"
+ integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==
dependencies:
- "@jest/types" "^27.5.1"
- "@sinonjs/fake-timers" "^8.0.1"
+ jest-get-type "^28.0.2"
+
+"@jest/expect@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72"
+ integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==
+ dependencies:
+ expect "^28.1.3"
+ jest-snapshot "^28.1.3"
+
+"@jest/fake-timers@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e"
+ integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==
+ dependencies:
+ "@jest/types" "^28.1.3"
+ "@sinonjs/fake-timers" "^9.1.2"
"@types/node" "*"
- jest-message-util "^27.5.1"
- jest-mock "^27.5.1"
- jest-util "^27.5.1"
+ jest-message-util "^28.1.3"
+ jest-mock "^28.1.3"
+ jest-util "^28.1.3"
-"@jest/globals@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b"
- integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==
+"@jest/globals@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333"
+ integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==
dependencies:
- "@jest/environment" "^27.5.1"
- "@jest/types" "^27.5.1"
- expect "^27.5.1"
+ "@jest/environment" "^28.1.3"
+ "@jest/expect" "^28.1.3"
+ "@jest/types" "^28.1.3"
-"@jest/reporters@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04"
- integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==
+"@jest/reporters@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a"
+ integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==
dependencies:
"@bcoe/v8-coverage" "^0.2.3"
- "@jest/console" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/transform" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/console" "^28.1.3"
+ "@jest/test-result" "^28.1.3"
+ "@jest/transform" "^28.1.3"
+ "@jest/types" "^28.1.3"
+ "@jridgewell/trace-mapping" "^0.3.13"
"@types/node" "*"
chalk "^4.0.0"
collect-v8-coverage "^1.0.0"
exit "^0.1.2"
- glob "^7.1.2"
+ glob "^7.1.3"
graceful-fs "^4.2.9"
istanbul-lib-coverage "^3.0.0"
istanbul-lib-instrument "^5.1.0"
istanbul-lib-report "^3.0.0"
istanbul-lib-source-maps "^4.0.0"
istanbul-reports "^3.1.3"
- jest-haste-map "^27.5.1"
- jest-resolve "^27.5.1"
- jest-util "^27.5.1"
- jest-worker "^27.5.1"
+ jest-message-util "^28.1.3"
+ jest-util "^28.1.3"
+ jest-worker "^28.1.3"
slash "^3.0.0"
- source-map "^0.6.0"
string-length "^4.0.1"
+ strip-ansi "^6.0.0"
terminal-link "^2.0.0"
- v8-to-istanbul "^8.1.0"
+ v8-to-istanbul "^9.0.1"
+
+"@jest/schemas@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905"
+ integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==
+ dependencies:
+ "@sinclair/typebox" "^0.24.1"
-"@jest/source-map@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf"
- integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==
+"@jest/source-map@^28.1.2":
+ version "28.1.2"
+ resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24"
+ integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==
dependencies:
+ "@jridgewell/trace-mapping" "^0.3.13"
callsites "^3.0.0"
graceful-fs "^4.2.9"
- source-map "^0.6.0"
-"@jest/test-result@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb"
- integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==
+"@jest/test-result@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5"
+ integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==
dependencies:
- "@jest/console" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/console" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/istanbul-lib-coverage" "^2.0.0"
collect-v8-coverage "^1.0.0"
-"@jest/test-sequencer@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b"
- integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==
+"@jest/test-sequencer@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3"
+ integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==
dependencies:
- "@jest/test-result" "^27.5.1"
+ "@jest/test-result" "^28.1.3"
graceful-fs "^4.2.9"
- jest-haste-map "^27.5.1"
- jest-runtime "^27.5.1"
+ jest-haste-map "^28.1.3"
+ slash "^3.0.0"
-"@jest/transform@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409"
- integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==
+"@jest/transform@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0"
+ integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==
dependencies:
- "@babel/core" "^7.1.0"
- "@jest/types" "^27.5.1"
+ "@babel/core" "^7.11.6"
+ "@jest/types" "^28.1.3"
+ "@jridgewell/trace-mapping" "^0.3.13"
babel-plugin-istanbul "^6.1.1"
chalk "^4.0.0"
convert-source-map "^1.4.0"
fast-json-stable-stringify "^2.0.0"
graceful-fs "^4.2.9"
- jest-haste-map "^27.5.1"
- jest-regex-util "^27.5.1"
- jest-util "^27.5.1"
+ jest-haste-map "^28.1.3"
+ jest-regex-util "^28.0.2"
+ jest-util "^28.1.3"
micromatch "^4.0.4"
pirates "^4.0.4"
slash "^3.0.0"
- source-map "^0.6.1"
- write-file-atomic "^3.0.0"
+ write-file-atomic "^4.0.1"
"@jest/types@^26.6.2":
version "26.6.2"
@@ -1536,23 +1565,24 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
-"@jest/types@^27.5.1":
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80"
- integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==
+"@jest/types@^28.1.3":
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b"
+ integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==
dependencies:
+ "@jest/schemas" "^28.1.3"
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^3.0.0"
"@types/node" "*"
- "@types/yargs" "^16.0.0"
+ "@types/yargs" "^17.0.8"
chalk "^4.0.0"
-"@jridgewell/gen-mapping@^0.3.0":
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9"
- integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==
+"@jridgewell/gen-mapping@^0.3.2":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
+ integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
dependencies:
- "@jridgewell/set-array" "^1.0.0"
+ "@jridgewell/set-array" "^1.0.1"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.9"
@@ -1561,17 +1591,17 @@
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c"
integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==
-"@jridgewell/set-array@^1.0.0":
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea"
- integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==
+"@jridgewell/set-array@^1.0.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
+ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.11"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec"
integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==
-"@jridgewell/trace-mapping@0.3.9", "@jridgewell/trace-mapping@^0.3.0", "@jridgewell/trace-mapping@^0.3.9":
+"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
@@ -1579,6 +1609,14 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
+"@jridgewell/trace-mapping@^0.3.0", "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.9":
+ version "0.3.15"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774"
+ integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.0.3"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+
"@jsdevtools/ono@^7.1.3":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
@@ -1720,6 +1758,11 @@
"@sentry/types" "7.21.1"
tslib "^1.9.3"
+"@sinclair/typebox@^0.24.1":
+ version "0.24.40"
+ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.40.tgz#00ee9b48537b147f6ffc80ebc28ab16d6016ed5c"
+ integrity sha512-Xint60L8rF0+nRy+6fCjW9jQMmu7fTpbwTBrXZiK6eq/RHDJS7LvWX/0oXC8O7fCePmrY/XdfaTv2HiUDeCq4g==
+
"@sinonjs/commons@^1.7.0":
version "1.8.1"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
@@ -1727,10 +1770,10 @@
dependencies:
type-detect "4.0.8"
-"@sinonjs/fake-timers@^8.0.1":
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7"
- integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==
+"@sinonjs/fake-timers@^9.1.2":
+ version "9.1.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c"
+ integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==
dependencies:
"@sinonjs/commons" "^1.7.0"
@@ -1976,10 +2019,10 @@
"@tiptap/extension-floating-menu" "^2.0.0-beta.56"
prosemirror-view "1.26.2"
-"@tootallnate/once@1":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
- integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
+"@tootallnate/once@2":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
+ integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
"@tsconfig/node10@^1.0.7":
version "1.0.9"
@@ -2006,7 +2049,7 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0"
integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A==
-"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
+"@types/babel__core@^7.1.14":
version "7.1.19"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460"
integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==
@@ -2032,7 +2075,7 @@
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
-"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6":
+"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.15.tgz#db9e4238931eb69ef8aab0ad6523d4d4caa39d03"
integrity sha512-Pzh9O3sTK8V6I1olsXpCfj2k/ygO2q1X0vhhnDrEQyYLHZesWz+zMZMVcwXLCYf0U36EtmyYaFGPfXlTtDHe3A==
@@ -2109,10 +2152,10 @@
"@types/minimatch" "*"
"@types/node" "*"
-"@types/graceful-fs@^4.1.2":
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.3.tgz#039af35fe26bec35003e8d86d2ee9c586354348f"
- integrity sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==
+"@types/graceful-fs@^4.1.3":
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
+ integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
dependencies:
"@types/node" "*"
@@ -2149,13 +2192,22 @@
dependencies:
"@types/istanbul-lib-report" "*"
-"@types/jest@^27.5.1":
- version "27.5.2"
- resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c"
- integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==
+"@types/jest@^28.1.3":
+ version "28.1.8"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-28.1.8.tgz#6936409f3c9724ea431efd412ea0238a0f03b09b"
+ integrity sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==
dependencies:
- jest-matcher-utils "^27.0.0"
- pretty-format "^27.0.0"
+ expect "^28.0.0"
+ pretty-format "^28.0.0"
+
+"@types/jsdom@^16.2.4":
+ version "16.2.15"
+ resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.15.tgz#6c09990ec43b054e49636cba4d11d54367fc90d6"
+ integrity sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==
+ dependencies:
+ "@types/node" "*"
+ "@types/parse5" "^6.0.3"
+ "@types/tough-cookie" "*"
"@types/json-schema@^7.0.0", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.11"
@@ -2224,7 +2276,7 @@
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.0.tgz#9ae2106efc443d7c1e26570aa8247828c9c80f11"
integrity sha512-J5D3z703XTDIGQFYXsnU9uRCW9e9mMEFO0Kpe6kykyiboqziru/RlZ0hM2P+PKTG4NHG1SjLrqae/NrV2iJApQ==
-"@types/parse5@^6.0.0":
+"@types/parse5@^6.0.0", "@types/parse5@^6.0.3":
version "6.0.3"
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
@@ -2276,6 +2328,21 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==
+"@types/strip-bom@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2"
+ integrity sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==
+
+"@types/strip-json-comments@0.0.30":
+ version "0.0.30"
+ resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
+ integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
+
+"@types/tough-cookie@*":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397"
+ integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==
+
"@types/unist@*", "@types/unist@^2.0.0":
version "2.0.6"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
@@ -2307,10 +2374,10 @@
dependencies:
"@types/yargs-parser" "*"
-"@types/yargs@^16.0.0":
- version "16.0.4"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977"
- integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==
+"@types/yargs@^17.0.8":
+ version "17.0.12"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.12.tgz#0745ff3e4872b4ace98616d4b7e37ccbd75f9526"
+ integrity sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==
dependencies:
"@types/yargs-parser" "*"
@@ -2385,16 +2452,17 @@
lodash "^4.17.15"
pretty "^2.0.0"
-"@vue/vue2-jest@^27.0.0":
- version "27.0.0"
- resolved "https://registry.yarnpkg.com/@vue/vue2-jest/-/vue2-jest-27.0.0.tgz#456076e27f7fa0179a37b04baea3e0b3cf786c6d"
- integrity sha512-r8YGOuqEWpAf2wGfgxfOL6Jce3WYOMcYji2qd8kuDe466ZsybHFeMryMJi6JrELOOI+MCA/8eFsSOx1KoJa7Dg==
+"@vue/vue2-jest@^28.1.0":
+ version "28.1.0"
+ resolved "https://registry.yarnpkg.com/@vue/vue2-jest/-/vue2-jest-28.1.0.tgz#2ac1a1ba4fdfc286947bd06f5f363129c77292f3"
+ integrity sha512-4aZB6tRQw7x5Xi0dt1itLfOv4WeNLutccV7FHw47xfHjFr/JnwgqTmzC9yOiYzC9H7T2/3DSW95Bzl3RETtFlA==
dependencies:
"@babel/plugin-transform-modules-commonjs" "^7.2.0"
"@vue/component-compiler-utils" "^3.1.0"
chalk "^2.1.0"
css-tree "^2.0.1"
source-map "0.5.6"
+ tsconfig "^7.0.0"
"@webassemblyjs/ast@1.9.0":
version "1.9.0"
@@ -2599,7 +2667,7 @@ JSV@^4.0.x:
resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57"
integrity sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw==
-abab@^2.0.3, abab@^2.0.5:
+abab@^2.0.5, abab@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
@@ -2657,7 +2725,7 @@ acorn@^7.1.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
-acorn@^8.0.4, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.8.0:
+acorn@^8.0.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.8.0:
version "8.8.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
@@ -2938,16 +3006,15 @@ axios@^0.24.0:
dependencies:
follow-redirects "^1.14.4"
-babel-jest@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444"
- integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==
+babel-jest@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5"
+ integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==
dependencies:
- "@jest/transform" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/transform" "^28.1.3"
"@types/babel__core" "^7.1.14"
babel-plugin-istanbul "^6.1.1"
- babel-preset-jest "^27.5.1"
+ babel-preset-jest "^28.1.3"
chalk "^4.0.0"
graceful-fs "^4.2.9"
slash "^3.0.0"
@@ -2980,14 +3047,14 @@ babel-plugin-istanbul@^6.1.1:
istanbul-lib-instrument "^5.0.4"
test-exclude "^6.0.0"
-babel-plugin-jest-hoist@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e"
- integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==
+babel-plugin-jest-hoist@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe"
+ integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==
dependencies:
"@babel/template" "^7.3.3"
"@babel/types" "^7.3.3"
- "@types/babel__core" "^7.0.0"
+ "@types/babel__core" "^7.1.14"
"@types/babel__traverse" "^7.0.6"
babel-plugin-lodash@^3.3.4:
@@ -3043,12 +3110,12 @@ babel-preset-current-node-syntax@^1.0.0:
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-syntax-top-level-await" "^7.8.3"
-babel-preset-jest@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81"
- integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==
+babel-preset-jest@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d"
+ integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==
dependencies:
- babel-plugin-jest-hoist "^27.5.1"
+ babel-plugin-jest-hoist "^28.1.3"
babel-preset-current-node-syntax "^1.0.0"
backo2@^1.0.2:
@@ -3695,17 +3762,12 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
-color-convert@~0.5.0:
- version "0.5.3"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd"
- integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=
-
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
-color-name@~1.1.4:
+color-name@^1.1.4, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
@@ -4156,10 +4218,10 @@ cssfontparser@^1.2.1:
resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3"
integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M=
-cssom@^0.4.4:
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
- integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
+cssom@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36"
+ integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==
cssom@~0.3.6:
version "0.3.8"
@@ -4701,14 +4763,14 @@ dagre@^0.8.5:
graphlib "^2.1.8"
lodash "^4.17.15"
-data-urls@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
- integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
+data-urls@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143"
+ integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==
dependencies:
- abab "^2.0.3"
- whatwg-mimetype "^2.3.0"
- whatwg-url "^8.0.0"
+ abab "^2.0.6"
+ whatwg-mimetype "^3.0.0"
+ whatwg-url "^11.0.0"
dataloader@2.0.0:
version "2.0.0"
@@ -4769,10 +4831,10 @@ decamelize@^1.1.0, decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
-decimal.js@^10.2.1:
- version "10.3.1"
- resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
- integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
+decimal.js@^10.3.1:
+ version "10.4.0"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.0.tgz#97a7448873b01e92e5ff9117d89a7bca8e63e0fe"
+ integrity sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==
deckar01-task_list@^2.3.1:
version "2.3.1"
@@ -4913,10 +4975,10 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
-diff-sequences@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
- integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==
+diff-sequences@^28.1.1:
+ version "28.1.1"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6"
+ integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==
diff@^3.4.0:
version "3.5.0"
@@ -5009,12 +5071,12 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
-domexception@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
- integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
+domexception@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
+ integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==
dependencies:
- webidl-conversions "^5.0.0"
+ webidl-conversions "^7.0.0"
domhandler@^4.0.0, domhandler@^4.2.0:
version "4.2.0"
@@ -5118,10 +5180,10 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
-emittery@^0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
- integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==
+emittery@^0.10.2:
+ version "0.10.2"
+ resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933"
+ integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==
emoji-regex@^10.0.0:
version "10.0.0"
@@ -5780,15 +5842,16 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-expect@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74"
- integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==
+expect@^28.0.0, expect@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec"
+ integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==
dependencies:
- "@jest/types" "^27.5.1"
- jest-get-type "^27.5.1"
- jest-matcher-utils "^27.5.1"
- jest-message-util "^27.5.1"
+ "@jest/expect-utils" "^28.1.3"
+ jest-get-type "^28.0.2"
+ jest-matcher-utils "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-util "^28.1.3"
express@^4.17.3:
version "4.17.3"
@@ -6085,10 +6148,10 @@ form-data-encoder@^1.7.1:
resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040"
integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==
-form-data@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
- integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
+form-data@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
+ integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
@@ -6289,7 +6352,7 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
-"glob@5 - 7", glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+"glob@5 - 7", glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
@@ -6691,12 +6754,12 @@ hpack.js@^2.1.6:
readable-stream "^2.0.1"
wbuf "^1.1.0"
-html-encoding-sniffer@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
- integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
+html-encoding-sniffer@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
+ integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==
dependencies:
- whatwg-encoding "^1.0.5"
+ whatwg-encoding "^2.0.0"
html-entities@^2.3.2:
version "2.3.2"
@@ -6759,12 +6822,12 @@ http-parser-js@>=0.5.1:
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9"
integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==
-http-proxy-agent@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
- integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==
+http-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
+ integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==
dependencies:
- "@tootallnate/once" "1"
+ "@tootallnate/once" "2"
agent-base "6"
debug "4"
@@ -6813,7 +6876,7 @@ iconv-lite@0.4, iconv-lite@0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
-iconv-lite@0.6:
+iconv-lite@0.6, iconv-lite@0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
@@ -7238,11 +7301,6 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-is-typedarray@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
- integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-
is-weakref@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
@@ -7360,246 +7418,243 @@ jed@^1.1.1:
resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"
integrity sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=
-jest-canvas-mock@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.1.2.tgz#0d16c9f91534f773fd132fc289f2e6b6db8faa28"
- integrity sha512-1VI4PK4/X70yrSjYScYVkYJYbXYlZLKJkUrAlyHjQsfolv64aoFyIrmMDtqCjpYrpVvWYEcAGUaYv5DVJj00oQ==
+jest-canvas-mock@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz#947b71442d7719f8e055decaecdb334809465341"
+ integrity sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ==
dependencies:
cssfontparser "^1.2.1"
- parse-color "^1.0.0"
+ moo-color "^1.0.2"
-jest-changed-files@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5"
- integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==
+jest-changed-files@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831"
+ integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==
dependencies:
- "@jest/types" "^27.5.1"
execa "^5.0.0"
- throat "^6.0.1"
+ p-limit "^3.1.0"
-jest-circus@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc"
- integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==
+jest-circus@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4"
+ integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==
dependencies:
- "@jest/environment" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/environment" "^28.1.3"
+ "@jest/expect" "^28.1.3"
+ "@jest/test-result" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
chalk "^4.0.0"
co "^4.6.0"
dedent "^0.7.0"
- expect "^27.5.1"
is-generator-fn "^2.0.0"
- jest-each "^27.5.1"
- jest-matcher-utils "^27.5.1"
- jest-message-util "^27.5.1"
- jest-runtime "^27.5.1"
- jest-snapshot "^27.5.1"
- jest-util "^27.5.1"
- pretty-format "^27.5.1"
+ jest-each "^28.1.3"
+ jest-matcher-utils "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-runtime "^28.1.3"
+ jest-snapshot "^28.1.3"
+ jest-util "^28.1.3"
+ p-limit "^3.1.0"
+ pretty-format "^28.1.3"
slash "^3.0.0"
stack-utils "^2.0.3"
- throat "^6.0.1"
-jest-cli@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145"
- integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==
+jest-cli@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2"
+ integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==
dependencies:
- "@jest/core" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/core" "^28.1.3"
+ "@jest/test-result" "^28.1.3"
+ "@jest/types" "^28.1.3"
chalk "^4.0.0"
exit "^0.1.2"
graceful-fs "^4.2.9"
import-local "^3.0.2"
- jest-config "^27.5.1"
- jest-util "^27.5.1"
- jest-validate "^27.5.1"
+ jest-config "^28.1.3"
+ jest-util "^28.1.3"
+ jest-validate "^28.1.3"
prompts "^2.0.1"
- yargs "^16.2.0"
+ yargs "^17.3.1"
-jest-config@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41"
- integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==
+jest-config@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60"
+ integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==
dependencies:
- "@babel/core" "^7.8.0"
- "@jest/test-sequencer" "^27.5.1"
- "@jest/types" "^27.5.1"
- babel-jest "^27.5.1"
+ "@babel/core" "^7.11.6"
+ "@jest/test-sequencer" "^28.1.3"
+ "@jest/types" "^28.1.3"
+ babel-jest "^28.1.3"
chalk "^4.0.0"
ci-info "^3.2.0"
deepmerge "^4.2.2"
- glob "^7.1.1"
+ glob "^7.1.3"
graceful-fs "^4.2.9"
- jest-circus "^27.5.1"
- jest-environment-jsdom "^27.5.1"
- jest-environment-node "^27.5.1"
- jest-get-type "^27.5.1"
- jest-jasmine2 "^27.5.1"
- jest-regex-util "^27.5.1"
- jest-resolve "^27.5.1"
- jest-runner "^27.5.1"
- jest-util "^27.5.1"
- jest-validate "^27.5.1"
+ jest-circus "^28.1.3"
+ jest-environment-node "^28.1.3"
+ jest-get-type "^28.0.2"
+ jest-regex-util "^28.0.2"
+ jest-resolve "^28.1.3"
+ jest-runner "^28.1.3"
+ jest-util "^28.1.3"
+ jest-validate "^28.1.3"
micromatch "^4.0.4"
parse-json "^5.2.0"
- pretty-format "^27.5.1"
+ pretty-format "^28.1.3"
slash "^3.0.0"
strip-json-comments "^3.1.1"
-jest-diff@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def"
- integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==
+jest-diff@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f"
+ integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==
dependencies:
chalk "^4.0.0"
- diff-sequences "^27.5.1"
- jest-get-type "^27.5.1"
- pretty-format "^27.5.1"
+ diff-sequences "^28.1.1"
+ jest-get-type "^28.0.2"
+ pretty-format "^28.1.3"
-jest-docblock@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0"
- integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==
+jest-docblock@^28.1.1:
+ version "28.1.1"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8"
+ integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==
dependencies:
detect-newline "^3.0.0"
-jest-each@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e"
- integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==
+jest-each@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81"
+ integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==
dependencies:
- "@jest/types" "^27.5.1"
+ "@jest/types" "^28.1.3"
chalk "^4.0.0"
- jest-get-type "^27.5.1"
- jest-util "^27.5.1"
- pretty-format "^27.5.1"
-
-jest-environment-jsdom@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546"
- integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==
- dependencies:
- "@jest/environment" "^27.5.1"
- "@jest/fake-timers" "^27.5.1"
- "@jest/types" "^27.5.1"
+ jest-get-type "^28.0.2"
+ jest-util "^28.1.3"
+ pretty-format "^28.1.3"
+
+jest-environment-jsdom@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-28.1.3.tgz#2d4e5d61b7f1d94c3bddfbb21f0308ee506c09fb"
+ integrity sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==
+ dependencies:
+ "@jest/environment" "^28.1.3"
+ "@jest/fake-timers" "^28.1.3"
+ "@jest/types" "^28.1.3"
+ "@types/jsdom" "^16.2.4"
"@types/node" "*"
- jest-mock "^27.5.1"
- jest-util "^27.5.1"
- jsdom "^16.6.0"
-
-jest-environment-node@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e"
- integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==
- dependencies:
- "@jest/environment" "^27.5.1"
- "@jest/fake-timers" "^27.5.1"
- "@jest/types" "^27.5.1"
+ jest-mock "^28.1.3"
+ jest-util "^28.1.3"
+ jsdom "^19.0.0"
+
+jest-environment-node@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5"
+ integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==
+ dependencies:
+ "@jest/environment" "^28.1.3"
+ "@jest/fake-timers" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
- jest-mock "^27.5.1"
- jest-util "^27.5.1"
+ jest-mock "^28.1.3"
+ jest-util "^28.1.3"
-jest-get-type@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1"
- integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==
+jest-get-type@^28.0.2:
+ version "28.0.2"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203"
+ integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==
-jest-haste-map@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f"
- integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==
+jest-haste-map@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b"
+ integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==
dependencies:
- "@jest/types" "^27.5.1"
- "@types/graceful-fs" "^4.1.2"
+ "@jest/types" "^28.1.3"
+ "@types/graceful-fs" "^4.1.3"
"@types/node" "*"
anymatch "^3.0.3"
fb-watchman "^2.0.0"
graceful-fs "^4.2.9"
- jest-regex-util "^27.5.1"
- jest-serializer "^27.5.1"
- jest-util "^27.5.1"
- jest-worker "^27.5.1"
+ jest-regex-util "^28.0.2"
+ jest-util "^28.1.3"
+ jest-worker "^28.1.3"
micromatch "^4.0.4"
- walker "^1.0.7"
+ walker "^1.0.8"
optionalDependencies:
fsevents "^2.3.2"
-jest-jasmine2@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4"
- integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==
+jest-jasmine2@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-28.1.3.tgz#979726a3aa0755d6815bf675d38ff85b7c41f54c"
+ integrity sha512-nlNWJY1u62w+WAVgnXOQTdxFdZhqlxpKvMTn1cOK1QHX2oRrkPV3JcIcJfXwcGcifttOJZhExcgDUqSHrYQ6Dw==
dependencies:
- "@jest/environment" "^27.5.1"
- "@jest/source-map" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/environment" "^28.1.3"
+ "@jest/expect" "^28.1.3"
+ "@jest/source-map" "^28.1.2"
+ "@jest/test-result" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
chalk "^4.0.0"
co "^4.6.0"
- expect "^27.5.1"
is-generator-fn "^2.0.0"
- jest-each "^27.5.1"
- jest-matcher-utils "^27.5.1"
- jest-message-util "^27.5.1"
- jest-runtime "^27.5.1"
- jest-snapshot "^27.5.1"
- jest-util "^27.5.1"
- pretty-format "^27.5.1"
- throat "^6.0.1"
-
-jest-junit@^12.0.0:
- version "12.0.0"
- resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-12.0.0.tgz#3ebd4a6a84b50c4ab18323a8f7d9cceb9d845df6"
- integrity sha512-+8K35LlboWiPuCnXSyiid7rFdxNlpCWWM20WEYe6IZH6psfUWKZmSpSRQ5tk0C0cBeDsvsnIzcef5mYhyJsbug==
+ jest-each "^28.1.3"
+ jest-matcher-utils "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-runtime "^28.1.3"
+ jest-snapshot "^28.1.3"
+ jest-util "^28.1.3"
+ p-limit "^3.1.0"
+ pretty-format "^28.1.3"
+
+jest-junit@^12.3.0:
+ version "12.3.0"
+ resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-12.3.0.tgz#ee41a74e439eecdc8965f163f83035cce5998d6d"
+ integrity sha512-+NmE5ogsEjFppEl90GChrk7xgz8xzvF0f+ZT5AnhW6suJC93gvQtmQjfyjDnE0Z2nXJqEkxF0WXlvjG/J+wn/g==
dependencies:
mkdirp "^1.0.4"
strip-ansi "^5.2.0"
- uuid "^3.3.3"
+ uuid "^8.3.2"
xml "^1.0.1"
-jest-leak-detector@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8"
- integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==
+jest-leak-detector@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d"
+ integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==
dependencies:
- jest-get-type "^27.5.1"
- pretty-format "^27.5.1"
+ jest-get-type "^28.0.2"
+ pretty-format "^28.1.3"
-jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab"
- integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==
+jest-matcher-utils@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e"
+ integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==
dependencies:
chalk "^4.0.0"
- jest-diff "^27.5.1"
- jest-get-type "^27.5.1"
- pretty-format "^27.5.1"
+ jest-diff "^28.1.3"
+ jest-get-type "^28.0.2"
+ pretty-format "^28.1.3"
-jest-message-util@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf"
- integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==
+jest-message-util@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d"
+ integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==
dependencies:
"@babel/code-frame" "^7.12.13"
- "@jest/types" "^27.5.1"
+ "@jest/types" "^28.1.3"
"@types/stack-utils" "^2.0.0"
chalk "^4.0.0"
graceful-fs "^4.2.9"
micromatch "^4.0.4"
- pretty-format "^27.5.1"
+ pretty-format "^28.1.3"
slash "^3.0.0"
stack-utils "^2.0.3"
-jest-mock@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6"
- integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==
+jest-mock@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da"
+ integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==
dependencies:
- "@jest/types" "^27.5.1"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
jest-pnp-resolver@^1.2.2:
@@ -7607,181 +7662,174 @@ jest-pnp-resolver@^1.2.2:
resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
-jest-regex-util@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95"
- integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==
+jest-regex-util@^28.0.2:
+ version "28.0.2"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead"
+ integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==
-jest-resolve-dependencies@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8"
- integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==
+jest-resolve-dependencies@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66"
+ integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==
dependencies:
- "@jest/types" "^27.5.1"
- jest-regex-util "^27.5.1"
- jest-snapshot "^27.5.1"
+ jest-regex-util "^28.0.2"
+ jest-snapshot "^28.1.3"
-jest-resolve@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384"
- integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==
+jest-resolve@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8"
+ integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==
dependencies:
- "@jest/types" "^27.5.1"
chalk "^4.0.0"
graceful-fs "^4.2.9"
- jest-haste-map "^27.5.1"
+ jest-haste-map "^28.1.3"
jest-pnp-resolver "^1.2.2"
- jest-util "^27.5.1"
- jest-validate "^27.5.1"
+ jest-util "^28.1.3"
+ jest-validate "^28.1.3"
resolve "^1.20.0"
resolve.exports "^1.1.0"
slash "^3.0.0"
-jest-runner@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5"
- integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==
+jest-runner@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1"
+ integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==
dependencies:
- "@jest/console" "^27.5.1"
- "@jest/environment" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/transform" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/console" "^28.1.3"
+ "@jest/environment" "^28.1.3"
+ "@jest/test-result" "^28.1.3"
+ "@jest/transform" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
chalk "^4.0.0"
- emittery "^0.8.1"
+ emittery "^0.10.2"
graceful-fs "^4.2.9"
- jest-docblock "^27.5.1"
- jest-environment-jsdom "^27.5.1"
- jest-environment-node "^27.5.1"
- jest-haste-map "^27.5.1"
- jest-leak-detector "^27.5.1"
- jest-message-util "^27.5.1"
- jest-resolve "^27.5.1"
- jest-runtime "^27.5.1"
- jest-util "^27.5.1"
- jest-worker "^27.5.1"
- source-map-support "^0.5.6"
- throat "^6.0.1"
-
-jest-runtime@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af"
- integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==
- dependencies:
- "@jest/environment" "^27.5.1"
- "@jest/fake-timers" "^27.5.1"
- "@jest/globals" "^27.5.1"
- "@jest/source-map" "^27.5.1"
- "@jest/test-result" "^27.5.1"
- "@jest/transform" "^27.5.1"
- "@jest/types" "^27.5.1"
+ jest-docblock "^28.1.1"
+ jest-environment-node "^28.1.3"
+ jest-haste-map "^28.1.3"
+ jest-leak-detector "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-resolve "^28.1.3"
+ jest-runtime "^28.1.3"
+ jest-util "^28.1.3"
+ jest-watcher "^28.1.3"
+ jest-worker "^28.1.3"
+ p-limit "^3.1.0"
+ source-map-support "0.5.13"
+
+jest-runtime@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f"
+ integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==
+ dependencies:
+ "@jest/environment" "^28.1.3"
+ "@jest/fake-timers" "^28.1.3"
+ "@jest/globals" "^28.1.3"
+ "@jest/source-map" "^28.1.2"
+ "@jest/test-result" "^28.1.3"
+ "@jest/transform" "^28.1.3"
+ "@jest/types" "^28.1.3"
chalk "^4.0.0"
cjs-module-lexer "^1.0.0"
collect-v8-coverage "^1.0.0"
execa "^5.0.0"
glob "^7.1.3"
graceful-fs "^4.2.9"
- jest-haste-map "^27.5.1"
- jest-message-util "^27.5.1"
- jest-mock "^27.5.1"
- jest-regex-util "^27.5.1"
- jest-resolve "^27.5.1"
- jest-snapshot "^27.5.1"
- jest-util "^27.5.1"
+ jest-haste-map "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-mock "^28.1.3"
+ jest-regex-util "^28.0.2"
+ jest-resolve "^28.1.3"
+ jest-snapshot "^28.1.3"
+ jest-util "^28.1.3"
slash "^3.0.0"
strip-bom "^4.0.0"
-jest-serializer@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64"
- integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==
+jest-snapshot@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668"
+ integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==
dependencies:
- "@types/node" "*"
- graceful-fs "^4.2.9"
-
-jest-snapshot@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1"
- integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==
- dependencies:
- "@babel/core" "^7.7.2"
+ "@babel/core" "^7.11.6"
"@babel/generator" "^7.7.2"
"@babel/plugin-syntax-typescript" "^7.7.2"
"@babel/traverse" "^7.7.2"
- "@babel/types" "^7.0.0"
- "@jest/transform" "^27.5.1"
- "@jest/types" "^27.5.1"
- "@types/babel__traverse" "^7.0.4"
+ "@babel/types" "^7.3.3"
+ "@jest/expect-utils" "^28.1.3"
+ "@jest/transform" "^28.1.3"
+ "@jest/types" "^28.1.3"
+ "@types/babel__traverse" "^7.0.6"
"@types/prettier" "^2.1.5"
babel-preset-current-node-syntax "^1.0.0"
chalk "^4.0.0"
- expect "^27.5.1"
+ expect "^28.1.3"
graceful-fs "^4.2.9"
- jest-diff "^27.5.1"
- jest-get-type "^27.5.1"
- jest-haste-map "^27.5.1"
- jest-matcher-utils "^27.5.1"
- jest-message-util "^27.5.1"
- jest-util "^27.5.1"
+ jest-diff "^28.1.3"
+ jest-get-type "^28.0.2"
+ jest-haste-map "^28.1.3"
+ jest-matcher-utils "^28.1.3"
+ jest-message-util "^28.1.3"
+ jest-util "^28.1.3"
natural-compare "^1.4.0"
- pretty-format "^27.5.1"
- semver "^7.3.2"
+ pretty-format "^28.1.3"
+ semver "^7.3.5"
-jest-util@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9"
- integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==
+jest-util@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0"
+ integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==
dependencies:
- "@jest/types" "^27.5.1"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
chalk "^4.0.0"
ci-info "^3.2.0"
graceful-fs "^4.2.9"
picomatch "^2.2.3"
-jest-validate@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067"
- integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==
+jest-validate@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df"
+ integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==
dependencies:
- "@jest/types" "^27.5.1"
+ "@jest/types" "^28.1.3"
camelcase "^6.2.0"
chalk "^4.0.0"
- jest-get-type "^27.5.1"
+ jest-get-type "^28.0.2"
leven "^3.1.0"
- pretty-format "^27.5.1"
+ pretty-format "^28.1.3"
-jest-watcher@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2"
- integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==
+jest-watcher@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4"
+ integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==
dependencies:
- "@jest/test-result" "^27.5.1"
- "@jest/types" "^27.5.1"
+ "@jest/test-result" "^28.1.3"
+ "@jest/types" "^28.1.3"
"@types/node" "*"
ansi-escapes "^4.2.1"
chalk "^4.0.0"
- jest-util "^27.5.1"
+ emittery "^0.10.2"
+ jest-util "^28.1.3"
string-length "^4.0.1"
-jest-worker@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
- integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
+jest-worker@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98"
+ integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==
dependencies:
"@types/node" "*"
merge-stream "^2.0.0"
supports-color "^8.0.0"
-jest@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc"
- integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==
+jest@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b"
+ integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==
dependencies:
- "@jest/core" "^27.5.1"
+ "@jest/core" "^28.1.3"
+ "@jest/types" "^28.1.3"
import-local "^3.0.2"
- jest-cli "^27.5.1"
+ jest-cli "^28.1.3"
joycon@^3.0.1:
version "3.1.1"
@@ -7839,23 +7887,23 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"
-jsdom@^16.6.0:
- version "16.7.0"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
- integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
+jsdom@^19.0.0:
+ version "19.0.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a"
+ integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==
dependencies:
abab "^2.0.5"
- acorn "^8.2.4"
+ acorn "^8.5.0"
acorn-globals "^6.0.0"
- cssom "^0.4.4"
+ cssom "^0.5.0"
cssstyle "^2.3.0"
- data-urls "^2.0.0"
- decimal.js "^10.2.1"
- domexception "^2.0.1"
+ data-urls "^3.0.1"
+ decimal.js "^10.3.1"
+ domexception "^4.0.0"
escodegen "^2.0.0"
- form-data "^3.0.0"
- html-encoding-sniffer "^2.0.1"
- http-proxy-agent "^4.0.1"
+ form-data "^4.0.0"
+ html-encoding-sniffer "^3.0.0"
+ http-proxy-agent "^5.0.0"
https-proxy-agent "^5.0.0"
is-potential-custom-element-name "^1.0.1"
nwsapi "^2.2.0"
@@ -7864,13 +7912,13 @@ jsdom@^16.6.0:
symbol-tree "^3.2.4"
tough-cookie "^4.0.0"
w3c-hr-time "^1.0.2"
- w3c-xmlserializer "^2.0.0"
- webidl-conversions "^6.1.0"
- whatwg-encoding "^1.0.5"
- whatwg-mimetype "^2.3.0"
- whatwg-url "^8.5.0"
- ws "^7.4.6"
- xml-name-validator "^3.0.0"
+ w3c-xmlserializer "^3.0.0"
+ webidl-conversions "^7.0.0"
+ whatwg-encoding "^2.0.0"
+ whatwg-mimetype "^3.0.0"
+ whatwg-url "^10.0.0"
+ ws "^8.2.3"
+ xml-name-validator "^4.0.0"
jsesc@^2.5.1:
version "2.5.2"
@@ -8240,7 +8288,7 @@ lodash.values@^4.3.0:
resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347"
integrity sha1-o6bCsOvsxcLLocF+bmIP6BtT00c=
-lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0:
+lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -8313,12 +8361,12 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
-makeerror@1.0.x:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
- integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=
+makeerror@1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a"
+ integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==
dependencies:
- tmpl "1.0.x"
+ tmpl "1.0.5"
map-cache@^0.2.2:
version "0.2.2"
@@ -9206,6 +9254,13 @@ monaco-yaml@4.0.0:
vscode-uri "^3.0.0"
yaml "^2.0.0"
+moo-color@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.3.tgz#d56435f8359c8284d83ac58016df7427febece74"
+ integrity sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==
+ dependencies:
+ color-name "^1.1.4"
+
mousetrap@1.6.5:
version "1.6.5"
resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9"
@@ -9618,7 +9673,7 @@ osenv@^0.1.4:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
-p-limit@3.1.0, p-limit@^3.0.2:
+p-limit@3.1.0, p-limit@^3.0.2, p-limit@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
@@ -9729,13 +9784,6 @@ parse-asn1@^5.0.0:
evp_bytestokey "^1.0.0"
pbkdf2 "^3.0.3"
-parse-color@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/parse-color/-/parse-color-1.0.0.tgz#7b748b95a83f03f16a94f535e52d7f3d94658619"
- integrity sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=
- dependencies:
- color-convert "~0.5.0"
-
parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
@@ -10045,14 +10093,15 @@ pretty-format@^26.4.2:
ansi-styles "^4.0.0"
react-is "^17.0.1"
-pretty-format@^27.0.0, pretty-format@^27.5.1:
- version "27.5.1"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
- integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
+pretty-format@^28.0.0, pretty-format@^28.1.3:
+ version "28.1.3"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5"
+ integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==
dependencies:
+ "@jest/schemas" "^28.1.3"
ansi-regex "^5.0.1"
ansi-styles "^5.0.0"
- react-is "^17.0.1"
+ react-is "^18.0.0"
pretty@^2.0.0:
version "2.0.0"
@@ -10391,6 +10440,11 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+react-is@^18.0.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
+ integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
+
read-pkg-up@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
@@ -10873,7 +10927,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7:
+semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7:
version "7.3.7"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
@@ -11051,7 +11105,7 @@ sigmund@^1.0.1:
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=
-signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
+signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
@@ -11161,10 +11215,10 @@ source-map-resolve@^0.5.0:
source-map-url "^0.4.0"
urix "^0.1.0"
-source-map-support@^0.5.6, source-map-support@~0.5.12:
- version "0.5.20"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9"
- integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==
+source-map-support@0.5.13, source-map-support@~0.5.12:
+ version "0.5.13"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
+ integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
@@ -11184,11 +11238,6 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-source-map@^0.7.3:
- version "0.7.3"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
- integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
-
space-separated-tokens@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz#43193cec4fb858a2ce934b7f98b7f2c18107098b"
@@ -11414,6 +11463,11 @@ strip-indent@^3.0.0:
dependencies:
min-indent "^1.0.0"
+strip-json-comments@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+ integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
+
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
@@ -11688,11 +11742,6 @@ three@^0.143.0:
resolved "https://registry.yarnpkg.com/three/-/three-0.143.0.tgz#1455bca132cc2b20beb7f41d313e10c29e5ed9df"
integrity sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==
-throat@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
- integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==
-
throttle-debounce@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.1.0.tgz#257e648f0a56bd9e54fe0f132c4ab8611df4e1d5"
@@ -11747,7 +11796,7 @@ tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
-tmpl@1.0.x:
+tmpl@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
@@ -11820,10 +11869,10 @@ tough-cookie@^4.0.0:
punycode "^2.1.1"
universalify "^0.1.2"
-tr46@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
- integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==
+tr46@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
+ integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
dependencies:
punycode "^2.1.1"
@@ -11878,6 +11927,16 @@ tsconfig-paths@^3.14.1:
minimist "^1.2.6"
strip-bom "^3.0.0"
+tsconfig@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7"
+ integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==
+ dependencies:
+ "@types/strip-bom" "^3.0.0"
+ "@types/strip-json-comments" "0.0.30"
+ strip-bom "^3.0.0"
+ strip-json-comments "^2.0.0"
+
tslib@2.3.0, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
@@ -11957,13 +12016,6 @@ type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
-typedarray-to-buffer@^3.1.5:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
- integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
- dependencies:
- is-typedarray "^1.0.0"
-
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@@ -12230,11 +12282,6 @@ uuid@8.1.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==
-uuid@^3.3.3:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
- integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
@@ -12260,14 +12307,14 @@ v8-compile-cache@^2.3.0:
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
-v8-to-istanbul@^8.1.0:
- version "8.1.1"
- resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed"
- integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==
+v8-to-istanbul@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4"
+ integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==
dependencies:
+ "@jridgewell/trace-mapping" "^0.3.12"
"@types/istanbul-lib-coverage" "^2.0.1"
convert-source-map "^1.6.0"
- source-map "^0.7.3"
validate-npm-package-license@^3.0.1:
version "3.0.4"
@@ -12458,19 +12505,19 @@ w3c-keyname@^2.2.0:
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b"
integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==
-w3c-xmlserializer@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
- integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
+w3c-xmlserializer@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923"
+ integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==
dependencies:
- xml-name-validator "^3.0.0"
+ xml-name-validator "^4.0.0"
-walker@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
- integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=
+walker@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
+ integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==
dependencies:
- makeerror "1.0.x"
+ makeerror "1.0.12"
watchpack-chokidar2@^2.0.1:
version "2.0.1"
@@ -12522,15 +12569,10 @@ webidl-conversions@^3.0.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
-webidl-conversions@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
- integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
-
-webidl-conversions@^6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
- integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
+webidl-conversions@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
+ integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
webpack-bundle-analyzer@^4.6.1:
version "4.6.1"
@@ -12683,17 +12725,33 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
-whatwg-encoding@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
- integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
+whatwg-encoding@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53"
+ integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==
dependencies:
- iconv-lite "0.4.24"
+ iconv-lite "0.6.3"
-whatwg-mimetype@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
- integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
+whatwg-mimetype@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7"
+ integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==
+
+whatwg-url@^10.0.0:
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da"
+ integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==
+ dependencies:
+ tr46 "^3.0.0"
+ webidl-conversions "^7.0.0"
+
+whatwg-url@^11.0.0:
+ version "11.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018"
+ integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==
+ dependencies:
+ tr46 "^3.0.0"
+ webidl-conversions "^7.0.0"
whatwg-url@^5.0.0:
version "5.0.0"
@@ -12703,15 +12761,6 @@ whatwg-url@^5.0.0:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
-whatwg-url@^8.0.0, whatwg-url@^8.5.0:
- version "8.7.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
- integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
- dependencies:
- lodash "^4.7.0"
- tr46 "^2.1.0"
- webidl-conversions "^6.1.0"
-
which-boxed-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
@@ -12790,16 +12839,6 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-write-file-atomic@^3.0.0:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
- integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
- dependencies:
- imurmurhash "^0.1.4"
- is-typedarray "^1.0.0"
- signal-exit "^3.0.2"
- typedarray-to-buffer "^3.1.5"
-
write-file-atomic@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f"
@@ -12808,15 +12847,15 @@ write-file-atomic@^4.0.1:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"
-"ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1, ws@^7.4.6:
+"ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1:
version "7.5.7"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
-ws@^8.3.0, ws@^8.4.2:
- version "8.5.0"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
- integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
+ws@^8.2.3, ws@^8.3.0, ws@^8.4.2:
+ version "8.8.1"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0"
+ integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==
xhr-mock@^2.5.1:
version "2.5.1"
@@ -12826,11 +12865,6 @@ xhr-mock@^2.5.1:
global "^4.3.0"
url "^0.11.0"
-xml-name-validator@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
- integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
-
xml-name-validator@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
@@ -12899,11 +12933,16 @@ yargs-parser@^18.1.2:
camelcase "^5.0.0"
decamelize "^1.2.0"
-yargs-parser@^20.2.2, yargs-parser@^20.2.3:
+yargs-parser@^20.2.3:
version "20.2.9"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
+yargs-parser@^21.0.0:
+ version "21.1.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+ integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+
yargs@^15.4.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
@@ -12921,18 +12960,18 @@ yargs@^15.4.1:
y18n "^4.0.0"
yargs-parser "^18.1.2"
-yargs@^16.2.0:
- version "16.2.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
- integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+yargs@^17.3.1:
+ version "17.5.1"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e"
+ integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
- string-width "^4.2.0"
+ string-width "^4.2.3"
y18n "^5.0.5"
- yargs-parser "^20.2.2"
+ yargs-parser "^21.0.0"
yarn-check-webpack-plugin@^1.2.0:
version "1.2.0"