Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
ca3ff7f842
commit
b3e461ab0f
|
@ -1,11 +1,10 @@
|
|||
---
|
||||
# Cop supports --auto-correct.
|
||||
Style/ExplicitBlockArgument:
|
||||
# Offense count: 143
|
||||
# Temporarily disabled due to too many offenses
|
||||
Enabled: false
|
||||
Details: grace period
|
||||
Exclude:
|
||||
- 'app/controllers/admin/background_migrations_controller.rb'
|
||||
- 'app/controllers/admin/batched_jobs_controller.rb'
|
||||
- 'app/controllers/application_controller.rb'
|
||||
- 'app/models/application_record.rb'
|
||||
- 'app/models/broadcast_message.rb'
|
||||
|
@ -14,13 +13,14 @@ Style/ExplicitBlockArgument:
|
|||
- 'app/models/ci/build_trace_chunks/redis_trace_chunks.rb'
|
||||
- 'app/models/concerns/counter_attribute.rb'
|
||||
- 'app/models/merge_request.rb'
|
||||
- 'app/models/merge_request_diff.rb'
|
||||
- 'app/models/snippet_repository.rb'
|
||||
- 'app/services/import_export_clean_up_service.rb'
|
||||
- 'app/services/packages/debian/generate_distribution_key_service.rb'
|
||||
- 'app/workers/concerns/each_shard_worker.rb'
|
||||
- 'db/migrate/20210629031900_associate_existing_dast_builds_with_variables.rb'
|
||||
- 'ee/app/services/gitlab_subscriptions/fetch_subscription_plans_service.rb'
|
||||
- 'ee/app/services/group_saml/identity/destroy_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/base_merge_requests_service.rb'
|
||||
- 'ee/lib/ee/backup/repositories.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules.rb'
|
||||
- 'ee/lib/gitlab/audit/events/preloader.rb'
|
||||
|
@ -44,6 +44,7 @@ Style/ExplicitBlockArgument:
|
|||
- 'lib/gitlab/ci/variables/collection.rb'
|
||||
- 'lib/gitlab/cleanup/remote_uploads.rb'
|
||||
- 'lib/gitlab/database/dynamic_model_helpers.rb'
|
||||
- 'lib/gitlab/database/lock_writes_manager.rb'
|
||||
- 'lib/gitlab/database/reindexing/reindex_concurrently.rb'
|
||||
- 'lib/gitlab/git/changes.rb'
|
||||
- 'lib/gitlab/gitaly_client/list_blobs_adapter.rb'
|
||||
|
@ -58,16 +59,20 @@ Style/ExplicitBlockArgument:
|
|||
- 'lib/gitlab/import_export/project/base_task.rb'
|
||||
- 'lib/gitlab/import_export/project/export_task.rb'
|
||||
- 'lib/gitlab/import_export/project/import_task.rb'
|
||||
- 'lib/gitlab/import_export/remote_stream_upload.rb'
|
||||
- 'lib/gitlab/issuable/clone/copy_resource_events_service.rb'
|
||||
- 'lib/gitlab/metrics/dashboard/cache.rb'
|
||||
- 'lib/gitlab/metrics/dashboard/stages/base_stage.rb'
|
||||
- 'lib/gitlab/profiler.rb'
|
||||
- 'lib/gitlab/redis/wrapper.rb'
|
||||
- 'lib/gitlab/reference_counter.rb'
|
||||
- 'lib/gitlab/seeder.rb'
|
||||
- 'lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb'
|
||||
- 'lib/gitlab/sidekiq_middleware/monitor.rb'
|
||||
- 'lib/gitlab/sidekiq_middleware/query_analyzer.rb'
|
||||
- 'lib/gitlab/sidekiq_middleware/request_store_middleware.rb'
|
||||
- 'lib/gitlab/sidekiq_middleware/server_metrics.rb'
|
||||
- 'lib/gitlab/sidekiq_status.rb'
|
||||
- 'lib/gitlab/utils/measuring.rb'
|
||||
- 'lib/tasks/config_lint.rake'
|
||||
- 'qa/qa/ee/page/insights/show.rb'
|
||||
|
@ -87,7 +92,6 @@ Style/ExplicitBlockArgument:
|
|||
- 'qa/qa/resource/events/base.rb'
|
||||
- 'qa/qa/runtime/api/repository_storage_moves.rb'
|
||||
- 'qa/qa/runtime/search.rb'
|
||||
- 'qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb'
|
||||
- 'rubocop/code_reuse_helpers.rb'
|
||||
- 'spec/features/merge_request/user_sees_wip_help_message_spec.rb'
|
||||
- 'spec/features/projects/features_visibility_spec.rb'
|
||||
|
@ -99,9 +103,10 @@ Style/ExplicitBlockArgument:
|
|||
- 'spec/models/repository_spec.rb'
|
||||
- 'spec/services/pages/zip_directory_service_spec.rb'
|
||||
- 'spec/services/todo_service_spec.rb'
|
||||
- 'spec/support/database/gitlab_schemas_validate_connection.rb'
|
||||
- 'spec/support/helpers/feature_flag_helpers.rb'
|
||||
- 'spec/support/helpers/features/runners_helpers.rb'
|
||||
- 'spec/support/helpers/features/top_nav_spec_helpers.rb'
|
||||
- 'spec/support/helpers/graphql_helpers.rb'
|
||||
- 'spec/support/helpers/modal_helpers.rb'
|
||||
- 'spec/support/helpers/next_found_instance_of.rb'
|
||||
- 'spec/support/helpers/usage_data_helpers.rb'
|
||||
|
|
12
Gemfile
12
Gemfile
|
@ -76,7 +76,7 @@ gem 'omniauth-authentiq', '~> 0.3.3'
|
|||
gem 'gitlab-omniauth-openid-connect', '~> 0.10.0', require: 'omniauth_openid_connect'
|
||||
gem 'omniauth-salesforce', '~> 1.0.5', path: 'vendor/gems/omniauth-salesforce' # See gem README.md
|
||||
gem 'omniauth-atlassian-oauth2', '~> 0.2.0'
|
||||
gem 'rack-oauth2', '~> 1.21.2'
|
||||
gem 'rack-oauth2', '~> 1.21.3'
|
||||
gem 'jwt', '~> 2.1.0'
|
||||
|
||||
# Kerberos authentication. EE-only
|
||||
|
@ -118,7 +118,7 @@ gem 'net-ldap', '~> 0.16.3'
|
|||
# API
|
||||
gem 'grape', '~> 1.5.2'
|
||||
gem 'grape-entity', '~> 0.10.0'
|
||||
gem 'rack-cors', '~> 1.1.0', require: 'rack/cors'
|
||||
gem 'rack-cors', '~> 1.1.1', require: 'rack/cors'
|
||||
|
||||
# GraphQL API
|
||||
gem 'graphql', '~> 1.13.12'
|
||||
|
@ -166,7 +166,7 @@ gem 'seed-fu', '~> 2.3.7'
|
|||
gem 'elasticsearch-model', '~> 7.2'
|
||||
gem 'elasticsearch-rails', '~> 7.2', require: 'elasticsearch/rails/instrumentation'
|
||||
gem 'elasticsearch-api', '7.13.3'
|
||||
gem 'aws-sdk-core', '~> 3.131.0'
|
||||
gem 'aws-sdk-core', '~> 3.156.0'
|
||||
gem 'aws-sdk-cloudformation', '~> 1'
|
||||
gem 'aws-sdk-s3', '~> 1.114.0'
|
||||
gem 'faraday_middleware-aws-sigv4', '~>0.3.0'
|
||||
|
@ -204,7 +204,7 @@ gem 'diff_match_patch', '~> 0.1.0'
|
|||
# Application server
|
||||
gem 'rack', '~> 2.2.4'
|
||||
# https://github.com/zombocom/rack-timeout/blob/master/README.md#rails-apps-manually
|
||||
gem 'rack-timeout', '~> 0.6.0', require: 'rack/timeout/base'
|
||||
gem 'rack-timeout', '~> 0.6.3', require: 'rack/timeout/base'
|
||||
|
||||
group :puma do
|
||||
gem 'puma', '~> 5.6.5', require: false
|
||||
|
@ -309,7 +309,7 @@ gem 'fast_blank'
|
|||
gem 'gitlab-chronic', '~> 0.10.5'
|
||||
gem 'gitlab_chronic_duration', '~> 0.10.6.2'
|
||||
|
||||
gem 'rack-proxy', '~> 0.7.2'
|
||||
gem 'rack-proxy', '~> 0.7.4'
|
||||
|
||||
gem 'sassc-rails', '~> 2.1.0'
|
||||
gem 'autoprefixer-rails', '10.2.5.1'
|
||||
|
@ -324,7 +324,7 @@ gem 'base32', '~> 0.3.0'
|
|||
gem 'gitlab-license', '~> 2.2.1'
|
||||
|
||||
# Protect against bruteforcing
|
||||
gem 'rack-attack', '~> 6.6.0'
|
||||
gem 'rack-attack', '~> 6.6.1'
|
||||
|
||||
# Sentry integration
|
||||
gem 'sentry-raven', '~> 3.1'
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
{"name":"awesome_print","version":"1.9.2","platform":"ruby","checksum":"e99b32b704acff16d768b3468680793ced40bfdc4537eb07e06a4be11133786e"},
|
||||
{"name":"awrence","version":"1.1.1","platform":"ruby","checksum":"9be584c97408ed92d5e1ca11740853646fe270de675f2f8dd44e8233226dfc97"},
|
||||
{"name":"aws-eventstream","version":"1.2.0","platform":"ruby","checksum":"ffa53482c92880b001ff2fb06919b9bb82fd847cbb0fa244985d2ebb6dd0d1df"},
|
||||
{"name":"aws-partitions","version":"1.600.0","platform":"ruby","checksum":"23592386dd0bb34c38fae2714eb1ab5c18fbef714f22b042815a92fdd51fa733"},
|
||||
{"name":"aws-partitions","version":"1.638.0","platform":"ruby","checksum":"8dfe833a15e81cd586b2a9bc624c4800d6e4b003aa76f2e588972fd78be3941f"},
|
||||
{"name":"aws-sdk-cloudformation","version":"1.41.0","platform":"ruby","checksum":"31e47539719734413671edf9b1a31f8673fbf9688549f50c41affabbcb1c6b26"},
|
||||
{"name":"aws-sdk-core","version":"3.131.1","platform":"ruby","checksum":"481c602d682b61abccb4e9f5b64750907bb49758f6f31b3bec599819951a3f7a"},
|
||||
{"name":"aws-sdk-core","version":"3.156.0","platform":"ruby","checksum":"0975d3894936dbaf9120dac7781245f177e8ba8f109100bd86a0711d4f9ee01d"},
|
||||
{"name":"aws-sdk-kms","version":"1.57.0","platform":"ruby","checksum":"ffd7dbb9b4251f29d4f508af761d0addd7035a346a88e3481cdb4dc548e51bd5"},
|
||||
{"name":"aws-sdk-s3","version":"1.114.0","platform":"ruby","checksum":"ce0f71df1a7b0fb1f88d40a70636ef1a9b08e69fb560694c5dab3f4ac7efcde4"},
|
||||
{"name":"aws-sigv4","version":"1.5.0","platform":"ruby","checksum":"3f81c08bacabec6cbc77ebbbac755ca6132a74a4a3279afbde64db83796ce776"},
|
||||
{"name":"aws-sigv4","version":"1.5.1","platform":"ruby","checksum":"d68c87fff4ee843b4b92b23c7f31f957f254ec6eb064181f7119124aab8b8bb4"},
|
||||
{"name":"azure-storage-blob","version":"2.0.3","platform":"ruby","checksum":"61b76118843c91776bd24bee22c74adafeb7c4bb3a858a325047dae3b59d0363"},
|
||||
{"name":"azure-storage-common","version":"2.0.4","platform":"ruby","checksum":"608f4daab0e06b583b73dcffd3246ea39e78056de31630286b0cf97af7d6956b"},
|
||||
{"name":"babosa","version":"1.0.4","platform":"ruby","checksum":"18dea450f595462ed7cb80595abd76b2e535db8c91b350f6c4b3d73986c5bc99"},
|
||||
|
@ -52,7 +52,7 @@
|
|||
{"name":"benchmark-perf","version":"0.6.0","platform":"ruby","checksum":"fe2b01959f3de0f9dd34820d54ef881eb4f3589fccb7d17b63068ac92d7f9621"},
|
||||
{"name":"benchmark-trend","version":"0.4.0","platform":"ruby","checksum":"de5a02a9f443babefbbd97784759820decee8554a0c273d859c02a0990845d81"},
|
||||
{"name":"better_errors","version":"2.9.1","platform":"ruby","checksum":"39efc116ab04d6c4200052c5782936e4bd99906978d098992bce6bf81d054284"},
|
||||
{"name":"bindata","version":"2.4.10","platform":"ruby","checksum":"798b5e3ec00e9d562243076b819c16b1e226eb176d5b7b5cd21417bc3589981a"},
|
||||
{"name":"bindata","version":"2.4.11","platform":"ruby","checksum":"c38e0c99ffcd80c10a0a7ae6c8586d2fe26bf245cbefac90bec8764523220f6a"},
|
||||
{"name":"binding_ninja","version":"0.2.3","platform":"java","checksum":"bbcf70b211d6e397493bf57c249bbec6aaf28fa7dafeb78e447b1b2f0610484f"},
|
||||
{"name":"binding_ninja","version":"0.2.3","platform":"ruby","checksum":"4a85550a0066ee4721506b4e150857486808e50c9ddfeed04bdc896bb61eca9d"},
|
||||
{"name":"bootsnap","version":"1.13.0","platform":"ruby","checksum":"c673282ec0f48506f093ca9acefe0f666d1ab9fda716e49fb95c9fe677653e78"},
|
||||
|
@ -284,7 +284,7 @@
|
|||
{"name":"js_regex","version":"3.7.0","platform":"ruby","checksum":"b13fac68c4416d1a5f21c3bab8a71b4530f424b7c4ff9f46d8e62b895dc05975"},
|
||||
{"name":"json","version":"2.5.1","platform":"java","checksum":"be284a0c4a9d0373e81b0d5dfe71ed5b18d0479f05970e60a77be89a2978ce6c"},
|
||||
{"name":"json","version":"2.5.1","platform":"ruby","checksum":"918d8c41dacb7cfdbe0c7bbd6014a5372f0cf1c454ca150e9f4010fe80cc3153"},
|
||||
{"name":"json-jwt","version":"1.13.0","platform":"ruby","checksum":"b9bded80ba687e59d199db365731494ee68214f27d0d7be5b635b9956b98eb5b"},
|
||||
{"name":"json-jwt","version":"1.15.3","platform":"ruby","checksum":"66db4f14e538a774c15502a5b5b26b1f3e7585481bbb96df490aa74b5c2d6110"},
|
||||
{"name":"json_schemer","version":"0.2.18","platform":"ruby","checksum":"3362c21efbefdd12ce994e541a1e7fdb86fd267a6541dd8715e8a580fe3b6be6"},
|
||||
{"name":"jsonpath","version":"1.1.2","platform":"ruby","checksum":"6804124c244d04418218acb85b15c7caa79c592d7d6970195300428458946d3a"},
|
||||
{"name":"jwt","version":"2.1.0","platform":"ruby","checksum":"7e7e7ffc1a5ebce628ac7da428341c50615a3a10ac47bb74c22c1cba325613f0"},
|
||||
|
@ -430,11 +430,11 @@
|
|||
{"name":"rack-accept","version":"0.4.5","platform":"ruby","checksum":"66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2"},
|
||||
{"name":"rack-attack","version":"6.6.1","platform":"ruby","checksum":"187e5d248c6a162ed8cafa8241a7b5947d9b9cf122a4870eb1cdd0db861f3a11"},
|
||||
{"name":"rack-cors","version":"1.1.1","platform":"ruby","checksum":"4702644ac6d63ebbddff372a3cd4cd573513287e3524b5a5415f678970057a4b"},
|
||||
{"name":"rack-oauth2","version":"1.21.2","platform":"ruby","checksum":"06fc157cad243ac11d8681c18139c4556a3f86b518f0fcb419e29512181a3ff2"},
|
||||
{"name":"rack-oauth2","version":"1.21.3","platform":"ruby","checksum":"4e72a79dd6a866692e84422a552b27c38a5a1918ded06661e04910f2bbe676ba"},
|
||||
{"name":"rack-protection","version":"2.2.2","platform":"ruby","checksum":"fd41414dbabbec274af0bdb1f72a48504449de4d979782c9af38cbb5dfff3299"},
|
||||
{"name":"rack-proxy","version":"0.7.2","platform":"ruby","checksum":"89c74fd6d3e5a4db0ed7e0d8b9915dbc85360fd6f98f6c1f9a66479fe236f4b6"},
|
||||
{"name":"rack-proxy","version":"0.7.4","platform":"ruby","checksum":"a8bb373583d8a3165d8caf5af5fd7c32c9e8a91b983fbc531efa0e3d6617d2d4"},
|
||||
{"name":"rack-test","version":"1.1.0","platform":"ruby","checksum":"154161f40f162b1c009a655b7b0c5de3a3102cc6d7d2e94b64e1f46ace800866"},
|
||||
{"name":"rack-timeout","version":"0.6.0","platform":"ruby","checksum":"6038d1cc31936394bd2c57bb16c17b31d2fd1d33ce928537cf0ef6f1f1905099"},
|
||||
{"name":"rack-timeout","version":"0.6.3","platform":"ruby","checksum":"1754892eacc124d405e7f1145731ec9b7421ebd1bee5d51ddc18b72c204d0ab3"},
|
||||
{"name":"rails","version":"6.1.6.1","platform":"ruby","checksum":"17024921a3913fb341f584542b06adf6bb12977a8b92d5fce093c3996c963686"},
|
||||
{"name":"rails-controller-testing","version":"1.0.5","platform":"ruby","checksum":"741448db59366073e86fc965ba403f881c636b79a2c39a48d0486f2607182e94"},
|
||||
{"name":"rails-dom-testing","version":"2.0.3","platform":"ruby","checksum":"b140c4f39f6e609c8113137b9a60dfc2ecb89864e496f87f23a68b3b8f12d8d1"},
|
||||
|
|
29
Gemfile.lock
29
Gemfile.lock
|
@ -190,11 +190,11 @@ GEM
|
|||
awesome_print (1.9.2)
|
||||
awrence (1.1.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.600.0)
|
||||
aws-partitions (1.638.0)
|
||||
aws-sdk-cloudformation (1.41.0)
|
||||
aws-sdk-core (~> 3, >= 3.99.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-core (3.131.1)
|
||||
aws-sdk-core (3.156.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.525.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
|
@ -206,7 +206,7 @@ GEM
|
|||
aws-sdk-core (~> 3, >= 3.127.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
aws-sigv4 (1.5.0)
|
||||
aws-sigv4 (1.5.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
azure-storage-blob (2.0.3)
|
||||
azure-storage-common (~> 2.0)
|
||||
|
@ -232,7 +232,7 @@ GEM
|
|||
coderay (>= 1.0.0)
|
||||
erubi (>= 1.0.0)
|
||||
rack (>= 0.9.0)
|
||||
bindata (2.4.10)
|
||||
bindata (2.4.11)
|
||||
binding_ninja (0.2.3)
|
||||
bootsnap (1.13.0)
|
||||
msgpack (~> 1.2)
|
||||
|
@ -761,10 +761,11 @@ GEM
|
|||
regexp_parser (~> 2.1)
|
||||
regexp_property_values (~> 1.0)
|
||||
json (2.5.1)
|
||||
json-jwt (1.13.0)
|
||||
json-jwt (1.15.3)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
httpclient
|
||||
json_schemer (0.2.18)
|
||||
ecma-re-validator (~> 0.3)
|
||||
hana (~> 1.3)
|
||||
|
@ -1070,7 +1071,7 @@ GEM
|
|||
rack (>= 1.0, < 3)
|
||||
rack-cors (1.1.1)
|
||||
rack (>= 2.0.0)
|
||||
rack-oauth2 (1.21.2)
|
||||
rack-oauth2 (1.21.3)
|
||||
activesupport
|
||||
attr_required
|
||||
httpclient
|
||||
|
@ -1078,11 +1079,11 @@ GEM
|
|||
rack (>= 2.1.0)
|
||||
rack-protection (2.2.2)
|
||||
rack
|
||||
rack-proxy (0.7.2)
|
||||
rack-proxy (0.7.4)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-timeout (0.6.0)
|
||||
rack-timeout (0.6.3)
|
||||
rails (6.1.6.1)
|
||||
actioncable (= 6.1.6.1)
|
||||
actionmailbox (= 6.1.6.1)
|
||||
|
@ -1544,7 +1545,7 @@ DEPENDENCIES
|
|||
autoprefixer-rails (= 10.2.5.1)
|
||||
awesome_print
|
||||
aws-sdk-cloudformation (~> 1)
|
||||
aws-sdk-core (~> 3.131.0)
|
||||
aws-sdk-core (~> 3.156.0)
|
||||
aws-sdk-s3 (~> 1.114.0)
|
||||
babosa (~> 1.0.4)
|
||||
base32 (~> 0.3.0)
|
||||
|
@ -1730,11 +1731,11 @@ DEPENDENCIES
|
|||
puma (~> 5.6.5)
|
||||
puma_worker_killer (~> 0.3.1)
|
||||
rack (~> 2.2.4)
|
||||
rack-attack (~> 6.6.0)
|
||||
rack-cors (~> 1.1.0)
|
||||
rack-oauth2 (~> 1.21.2)
|
||||
rack-proxy (~> 0.7.2)
|
||||
rack-timeout (~> 0.6.0)
|
||||
rack-attack (~> 6.6.1)
|
||||
rack-cors (~> 1.1.1)
|
||||
rack-oauth2 (~> 1.21.3)
|
||||
rack-proxy (~> 0.7.4)
|
||||
rack-timeout (~> 0.6.3)
|
||||
rails (~> 6.1.6.1)
|
||||
rails-controller-testing
|
||||
rails-i18n (~> 7.0)
|
||||
|
|
|
@ -12,22 +12,6 @@ module MarkupHelper
|
|||
# https://gitlab.com/gitlab-org/gitlab/-/issues/365358
|
||||
RENDER_TIMEOUT = 5.seconds
|
||||
|
||||
def plain?(filename)
|
||||
Gitlab::MarkupHelper.plain?(filename)
|
||||
end
|
||||
|
||||
def markup?(filename)
|
||||
Gitlab::MarkupHelper.markup?(filename)
|
||||
end
|
||||
|
||||
def gitlab_markdown?(filename)
|
||||
Gitlab::MarkupHelper.gitlab_markdown?(filename)
|
||||
end
|
||||
|
||||
def asciidoc?(filename)
|
||||
Gitlab::MarkupHelper.asciidoc?(filename)
|
||||
end
|
||||
|
||||
# Use this in places where you would normally use link_to(gfm(...), ...).
|
||||
def link_to_markdown(body, url, html_options = {})
|
||||
return '' if body.blank?
|
||||
|
@ -146,11 +130,11 @@ module MarkupHelper
|
|||
return '' unless text.present?
|
||||
|
||||
markup = proc do
|
||||
if gitlab_markdown?(file_name)
|
||||
if Gitlab::MarkupHelper.gitlab_markdown?(file_name)
|
||||
markdown_unsafe(text, context)
|
||||
elsif asciidoc?(file_name)
|
||||
elsif Gitlab::MarkupHelper.asciidoc?(file_name)
|
||||
asciidoc_unsafe(text, context)
|
||||
elsif plain?(file_name)
|
||||
elsif Gitlab::MarkupHelper.plain?(file_name)
|
||||
plain_unsafe(text)
|
||||
else
|
||||
other_markup_unsafe(file_name, text, context)
|
||||
|
|
|
@ -350,7 +350,7 @@ class Snippet < ApplicationRecord
|
|||
end
|
||||
|
||||
def can_cache_field?(field)
|
||||
field != :content || MarkupHelper.gitlab_markdown?(file_name)
|
||||
field != :content || Gitlab::MarkupHelper.gitlab_markdown?(file_name)
|
||||
end
|
||||
|
||||
def hexdigest
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Tree
|
||||
include Gitlab::MarkupHelper
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
attr_accessor :repository, :sha, :path, :entries, :cursor
|
||||
|
@ -24,11 +23,11 @@ class Tree
|
|||
end
|
||||
|
||||
previewable_readmes = available_readmes.select do |blob|
|
||||
previewable?(blob.name)
|
||||
Gitlab::MarkupHelper.previewable?(blob.name)
|
||||
end
|
||||
|
||||
plain_readmes = available_readmes.select do |blob|
|
||||
plain?(blob.name)
|
||||
Gitlab::MarkupHelper.plain?(blob.name)
|
||||
end
|
||||
|
||||
# Prioritize previewable over plain readmes
|
||||
|
|
|
@ -20,7 +20,7 @@ module Ci
|
|||
|
||||
def execute
|
||||
in_lock(EXCLUSIVE_LOCK_KEY, ttl: LOCK_TIMEOUT, retries: 1) do
|
||||
destroy_unlocked_pipeline_artifacts if ::Feature.enabled?(:ci_destroy_unlocked_pipeline_artifacts)
|
||||
destroy_unlocked_pipeline_artifacts
|
||||
|
||||
legacy_destroy_pipeline_artifacts
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- if markup?(@blob.name)
|
||||
- if Gitlab::MarkupHelper.markup?(@blob.name)
|
||||
.file-content.md
|
||||
= markup(@blob.name, @content)
|
||||
- else
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_destroy_unlocked_pipeline_artifacts
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98633
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/375011
|
||||
milestone: '15.5'
|
||||
type: development
|
||||
group: group::pipeline insights
|
||||
default_enabled: false
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ScheduleResetDuplicateCiRunnersTokenValues < Gitlab::Database::Migration[2.0]
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_ci
|
||||
disable_ddl_transaction!
|
||||
|
||||
MIGRATION = 'ResetDuplicateCiRunnersTokenValues'
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 2_000
|
||||
MAX_BATCH_SIZE = 100_000
|
||||
SUB_BATCH_SIZE = 500
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:ci_runners,
|
||||
:id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
max_batch_size: MAX_BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(MIGRATION, :ci_runners, :id, [])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ScheduleResetDuplicateCiRunnersTokenEncryptedValues < Gitlab::Database::Migration[2.0]
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_ci
|
||||
disable_ddl_transaction!
|
||||
|
||||
MIGRATION = 'ResetDuplicateCiRunnersTokenEncryptedValues'
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 2_000
|
||||
MAX_BATCH_SIZE = 100_000
|
||||
SUB_BATCH_SIZE = 500
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:ci_runners,
|
||||
:id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
max_batch_size: MAX_BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(MIGRATION, :ci_runners, :id, [])
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
79aa2360fdf84d7bee402cf51e29813b9c25acfe809123ac5a3218644a63c71f
|
|
@ -0,0 +1 @@
|
|||
f48217567db22e6a4d3a32c607911da9f9a39a37d75be158a893ce840f718f02
|
|
@ -0,0 +1,197 @@
|
|||
---
|
||||
stage: Package
|
||||
group: Package
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Dependency Proxy
|
||||
|
||||
The Dependency Proxy is a pull-through-cache for registry images from DockerHub. This document describes how this
|
||||
feature is constructed in GitLab.
|
||||
|
||||
## Container registry
|
||||
|
||||
The Dependency Proxy for the container registry acts a stand-in for a remote container registry. In our case,
|
||||
the remote registry is the public DockerHub registry.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
id1([$ docker]) --> id2([GitLab Dependency Proxy])
|
||||
id2 --> id3([DockerHub])
|
||||
```
|
||||
|
||||
From the user's perspective, the GitLab instance is just a container registry that they are interacting with to
|
||||
pull images by using `docker login gitlab.com`
|
||||
|
||||
When you use `docker login gitlab.com`, the Docker client uses the [v2 API](https://docs.docker.com/registry/spec/api/)
|
||||
to make requests.
|
||||
|
||||
To support authentication, we must include one route:
|
||||
|
||||
- [API Version Check](https://docs.docker.com/registry/spec/api/#api-version-check)
|
||||
|
||||
To support `docker pull` requests, we must include two additional routes:
|
||||
|
||||
- [Pulling an image manifest](https://docs.docker.com/registry/spec/api/#pulling-an-image-manifest)
|
||||
- [Pulling an image layer (blob)](https://docs.docker.com/registry/spec/api/#pulling-a-layer)
|
||||
|
||||
These routes are defined in [`gitlab-org/gitlab/config/routes/group.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/3f76455ac9cf90a927767e55c837d6b07af818df/config/routes/group.rb#L164-175).
|
||||
|
||||
In its simplest form, the Dependency Proxy manages three requests:
|
||||
|
||||
- Logging in / returning a JWT
|
||||
- Fetching a manifest
|
||||
- Fetching a blob
|
||||
|
||||
Here is what the general request sequence looks like for the Dependency Proxy:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Client->>+GitLab: Login? / request token
|
||||
GitLab->>+Client: JWT
|
||||
Client->>+GitLab: request a manifest for an image
|
||||
GitLab->>+ExternalRegistry: request JWT
|
||||
ExternalRegistry->>+GitLab : JWT
|
||||
GitLab->>+ExternalRegistry : request manifest
|
||||
ExternalRegistry->>+GitLab : return manifest
|
||||
GitLab->>+GitLab : store manifest
|
||||
GitLab->>+Client : return manifest
|
||||
loop request image layers
|
||||
Client->>+GitLab: request a blob from the manifest
|
||||
GitLab->>+ExternalRegistry: request JWT
|
||||
ExternalRegistry->>+GitLab : JWT
|
||||
GitLab->>+ExternalRegistry : request blob
|
||||
ExternalRegistry->>+GitLab : return blob
|
||||
GitLab->>+GitLab : store blob
|
||||
GitLab->>+Client : return blob
|
||||
end
|
||||
```
|
||||
|
||||
### Authentication and authorization
|
||||
|
||||
When a Docker client authenticates with a registry, the registry tells the client where to get a JSON Web Token
|
||||
(JWT) and to use it for all subsequent requests. This allows the authentication service to live in a separate
|
||||
application from the registry. For example, the GitLab container registry directs Docker clients to get a token
|
||||
from `https://gitlab.com/jwt/auth`. This endpoint is part of the `gitlab-org/gitlab` project, also known as the
|
||||
rails project or web service.
|
||||
|
||||
When a user tries to log into the dependency proxy with a Docker client, we must tell it where to get a JWT. We
|
||||
can use the same endpoint we use with the container registry: `https://gitlab.com/jwt/auth`. But in our case,
|
||||
we tell the Docker client to specify `service=dependency_proxy` in the parameters so can use a separate underlying
|
||||
service to generate the token.
|
||||
|
||||
This sequence diagram shows the request flow for logging into the Dependency Proxy.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant C as Docker CLI
|
||||
participant R as GitLab (Dependency Proxy)
|
||||
|
||||
Note right of C: User tries `docker login gitlab.com` and enters username/password
|
||||
C->>R: GET /v2/
|
||||
Note left of R: Check for Authorization header, return 401 if none, return 200 if token exists and is valid
|
||||
R->>C: 401 Unauthorized with header "WWW-Authenticate": "Bearer realm=\"http://gitlab.com/jwt/auth\",service=\"registry.docker.io\""
|
||||
Note right of C: Request Oauth token using HTTP Basic Auth
|
||||
C->>R: GET /jwt/auth
|
||||
Note left of R: Token is returned
|
||||
R->>C: 200 OK (with Bearer token included)
|
||||
Note right of C: original request is tested again
|
||||
C->>R: GET /v2/ (this time with `Authorization: Bearer [token]` header)
|
||||
Note right of C: Login Succeeded
|
||||
R->>C: 200 OK
|
||||
```
|
||||
|
||||
The dependency proxy uses its own authentication service, separate from the authentication managed by the UI
|
||||
(`ApplicationController`) and API (`ApiGuard`). Once the service has created a JWT, the `DependencyProxy::ApplicationController`
|
||||
manages authentication and authorization for the rest of the requests. It manages the user by using `GitLab::Auth::Result` and
|
||||
is similar to the authentication implemented by the Git client requests in `GitHttpClientController`.
|
||||
|
||||
### Caching
|
||||
|
||||
Blobs are cached artifacts with no logic around them. We cache them by digest. When we receive a request for a new blob,
|
||||
we check to see if we have a blob with the requested digest, and return it. Otherwise we fetch it from the external
|
||||
registry and cache it.
|
||||
|
||||
Manifests are more complicated, partially due to [rate limiting on DockerHub](https://www.docker.com/increase-rate-limits/).
|
||||
A manifest is essentially a recipe for creating an image. It has a list of blobs to create a certain image. So
|
||||
`alpine:latest` has a manifest associated with it that specifies the blobs needed to create the `alpine:latest`
|
||||
image. The interesting part is that `alpine:latest` can change over time, so we can't just cache the manifest and
|
||||
assume it is OK to use forever. Instead, we must check the digest of the manifest, which is an Etag. This gets
|
||||
interesting because the requests for manifests often don't include the digest. So how do we know if the manifest
|
||||
we have cached is still the most up-to-date `alpine:latest`? DockerHub allows free HEAD requests that don't count
|
||||
toward their rate limit. The HEAD request returns the manifest digest so we can tell whether or not the one we
|
||||
have is stale.
|
||||
|
||||
With this knowledge, we have built the following logic to manage manifest requests:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Receive manifest request] --> | We have the manifest cached.| B{Docker manifest HEAD request}
|
||||
A --> | We do not have manifest cached.| C{Docker manifest GET request}
|
||||
B --> | Digest matches the one in the DB | D[Fetch manifest from cache]
|
||||
B --> | Network failure, cannot reach DockerHub | D[Fetch manifest from cache]
|
||||
B --> | Digest does not match the one in DB | C
|
||||
C --> E[Save manifest to cache, save digest to database]
|
||||
D --> F
|
||||
E --> F[Return manifest]
|
||||
```
|
||||
|
||||
### Workhorse for file handling
|
||||
|
||||
Management of file uploads and caching happens in [Workhorse](../workhorse/index.md). This explains the additional
|
||||
[`POST` routes](https://gitlab.com/gitlab-org/gitlab/-/blob/3f76455ac9cf90a927767e55c837d6b07af818df/config/routes/group.rb#L170-173)
|
||||
that we have for the Dependency Proxy.
|
||||
|
||||
The [send_dependency](https://gitlab.com/gitlab-org/gitlab/-/blob/7359d23f4e078479969c872924150219c6f1665f/app/helpers/workhorse_helper.rb#L46-53)
|
||||
method makes a request to Workhorse including the previously fetched JWT from the external registry. Workhorse then
|
||||
can use that token to request the manifest or blob the user originally requested. The Workhorse code lives in
|
||||
[`workhorse/internal/dependencyproxy/dependencyproxy.go`](https://gitlab.com/gitlab-org/gitlab/-/blob/b8f44a8f3c26efe9932c2ada2df75ef7acb8417b/workhorse/internal/dependencyproxy/dependencyproxy.go#L4).
|
||||
|
||||
Once we put it all together, the sequence for requesting an image file looks like this:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Client->>Workhorse: GET /v2/*group_id/dependency_proxy/containers/*image/manifests/*tag
|
||||
Workhorse->>Rails: GET /v2/*group_id/dependency_proxy/containers/*image/manifests/*tag
|
||||
Rails->>Rails: Check DB. Is manifest persisted in cache?
|
||||
|
||||
alt In Cache
|
||||
Rails->>Workhorse: Respond with send-url injector
|
||||
Workhorse->>Client: Send the file to the client
|
||||
else Not In Cache
|
||||
Rails->>Rails: Generate auth token and download URL for the manifest in upstream registry
|
||||
Rails->>Workhorse: Respond with send-dependency injector
|
||||
Workhorse->>External Registry: Request the manifest
|
||||
External Registry->>Workhorse: Download the manifest
|
||||
Workhorse->>Rails: GET /v2/*group_id/dependency_proxy/containers/*image/manifest/*tag/authorize
|
||||
Rails->>Workhorse: Respond with upload instructions
|
||||
Workhorse->>Client: Send the manifest file to the client with original headers
|
||||
Workhorse->>Object Storage: Save the manifest file with some of it's header values
|
||||
Workhorse->>Rails: Finalize the upload
|
||||
end
|
||||
```
|
||||
|
||||
### Cleanup policies
|
||||
|
||||
The cleanup policies for the Dependency Proxy work as time-to-live policies. They allow users to set the number
|
||||
of days a file is allowed to remain cached if it has been unread. Since there is no way to associate the blobs
|
||||
with the images they belong to (to do this, we would need to build the metadata database that the container registry
|
||||
folks built), we can set up rules like "if this blob has not been pulled in 90 days, delete it". This means that
|
||||
any files that are continuously getting pulled will not be removed from the cache, but if, for example,
|
||||
`alpine:latest` changes and one of the underlying blobs is no longer used, it will eventually get cleaned up
|
||||
because it has stopped getting pulled. We use the `read_at` attribute to track the last time a given
|
||||
`dependency_proxy_blob` or `dependency_proxy_manifest` was pulled.
|
||||
|
||||
These work using a cron worker, [DependencyProxy::CleanupDependencyProxyWorker](https://gitlab.com/gitlab-org/gitlab/-/blob/7359d23f4e078479969c872924150219c6f1665f/app/workers/dependency_proxy/cleanup_dependency_proxy_worker.rb#L4),
|
||||
that will kick off two [limited capacity](../sidekiq/limited_capacity_worker.md) workers: one to delete blobs,
|
||||
and one to delete manifests. The capacity is set in an [application setting](settings.md#container-registry).
|
||||
|
||||
### Historic reference links
|
||||
|
||||
- [Dependency proxy for private groups](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46042) - initial authentication implementation
|
||||
- [Manifest caching](https://gitlab.com/gitlab-org/gitlab/-/issues/241639) - initial manifest caching implementation
|
||||
- [Workhorse for blobs](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71890) - initial workhorse implementation
|
||||
- [Workhorse for manifest](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73033) - moving manifest cache logic to Workhorse
|
||||
- [Deploy token support](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64363) - authorization largely updated
|
||||
- [SSO support](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67373) - changes how policies are checked
|
|
@ -8,6 +8,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
Development and Architectural documentation for the package registry
|
||||
|
||||
- [Debian repository structure](debian_repository.md)
|
||||
- [Dependency proxy structure](dependency_proxy.md)
|
||||
- [Developing a new format](new_format_development.md)
|
||||
- [Settings](settings.md)
|
||||
- [Structure / Schema](structure.md)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
# A job to nullify duplicate token_encrypted values in ci_runners table in batches
|
||||
class ResetDuplicateCiRunnersTokenEncryptedValues < BatchedMigrationJob
|
||||
def perform
|
||||
each_sub_batch(operation_name: :nullify_duplicate_ci_runner_token_encrypted_values) do |sub_batch|
|
||||
# Reset duplicate runner encrypted tokens that would prevent creating an unique index.
|
||||
nullify_duplicate_ci_runner_token_encrypted_values(sub_batch)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def nullify_duplicate_ci_runner_token_encrypted_values(sub_batch)
|
||||
batchable_model = define_batchable_model(batch_table, connection: connection)
|
||||
|
||||
duplicate_tokens = batchable_model
|
||||
.where(token_encrypted: sub_batch.select(:token_encrypted).distinct)
|
||||
.group(:token_encrypted)
|
||||
.having('COUNT(*) > 1')
|
||||
.pluck(:token_encrypted)
|
||||
|
||||
return if duplicate_tokens.empty?
|
||||
|
||||
batchable_model.where(token_encrypted: duplicate_tokens).update_all(token_encrypted: nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
# A job to nullify duplicate token values in ci_runners table in batches
|
||||
class ResetDuplicateCiRunnersTokenValues < BatchedMigrationJob
|
||||
def perform
|
||||
each_sub_batch(operation_name: :nullify_duplicate_ci_runner_token_values) do |sub_batch|
|
||||
# Reset duplicate runner tokens that would prevent creating an unique index.
|
||||
nullify_duplicate_ci_runner_token_values(sub_batch)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def nullify_duplicate_ci_runner_token_values(sub_batch)
|
||||
batchable_model = define_batchable_model(batch_table, connection: connection)
|
||||
|
||||
duplicate_tokens = batchable_model
|
||||
.where(token: sub_batch.select(:token).distinct)
|
||||
.group(:token)
|
||||
.having('COUNT(*) > 1')
|
||||
.pluck(:token)
|
||||
|
||||
batchable_model.where(token: duplicate_tokens).update_all(token: nil) if duplicate_tokens.any?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -23,7 +23,7 @@ module Gitlab
|
|||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
def url
|
||||
raw_data.url || ''
|
||||
raw_data[:url] || ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,17 @@
|
|||
module Gitlab
|
||||
module LegacyGithubImport
|
||||
class BranchFormatter < BaseFormatter
|
||||
delegate :repo, :sha, :ref, to: :raw_data
|
||||
def repo
|
||||
raw_data[:repo]
|
||||
end
|
||||
|
||||
def sha
|
||||
raw_data[:sha]
|
||||
end
|
||||
|
||||
def ref
|
||||
raw_data[:ref]
|
||||
end
|
||||
|
||||
def exists?
|
||||
branch_exists? && commit_exists?
|
||||
|
@ -14,7 +24,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def user
|
||||
raw_data.user&.login || 'unknown'
|
||||
raw_data.dig(:user, :login) || 'unknown'
|
||||
end
|
||||
|
||||
def short_sha
|
||||
|
|
|
@ -9,19 +9,19 @@ module Gitlab
|
|||
{
|
||||
project: project,
|
||||
note: note,
|
||||
commit_id: raw_data.commit_id,
|
||||
commit_id: raw_data[:commit_id],
|
||||
line_code: line_code,
|
||||
author_id: author_id,
|
||||
type: type,
|
||||
created_at: raw_data.created_at,
|
||||
updated_at: raw_data.updated_at
|
||||
created_at: raw_data[:created_at],
|
||||
updated_at: raw_data[:updated_at]
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def author
|
||||
@author ||= UserFormatter.new(client, raw_data.user)
|
||||
@author ||= UserFormatter.new(client, raw_data[:user])
|
||||
end
|
||||
|
||||
def author_id
|
||||
|
@ -29,7 +29,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def body
|
||||
raw_data.body || ""
|
||||
raw_data[:body] || ""
|
||||
end
|
||||
|
||||
def line_code
|
||||
|
@ -48,11 +48,11 @@ module Gitlab
|
|||
end
|
||||
|
||||
def diff_hunk
|
||||
raw_data.diff_hunk
|
||||
raw_data[:diff_hunk]
|
||||
end
|
||||
|
||||
def file_path
|
||||
raw_data.path
|
||||
raw_data[:path]
|
||||
end
|
||||
|
||||
def note
|
||||
|
|
|
@ -96,7 +96,7 @@ module Gitlab
|
|||
def import_labels
|
||||
fetch_resources(:labels, repo, per_page: 100) do |labels|
|
||||
labels.each do |raw|
|
||||
gh_label = LabelFormatter.new(project, raw)
|
||||
gh_label = LabelFormatter.new(project, raw.to_h)
|
||||
gh_label.create!
|
||||
rescue StandardError => e
|
||||
errors << { type: :label, url: Gitlab::UrlSanitizer.sanitize(gh_label.url), errors: e.message }
|
||||
|
@ -109,7 +109,7 @@ module Gitlab
|
|||
def import_milestones
|
||||
fetch_resources(:milestones, repo, state: :all, per_page: 100) do |milestones|
|
||||
milestones.each do |raw|
|
||||
gh_milestone = MilestoneFormatter.new(project, raw)
|
||||
gh_milestone = MilestoneFormatter.new(project, raw.to_h)
|
||||
gh_milestone.create!
|
||||
rescue StandardError => e
|
||||
errors << { type: :milestone, url: Gitlab::UrlSanitizer.sanitize(gh_milestone.url), errors: e.message }
|
||||
|
@ -121,6 +121,7 @@ module Gitlab
|
|||
def import_issues
|
||||
fetch_resources(:issues, repo, state: :all, sort: :created, direction: :asc, per_page: 100) do |issues|
|
||||
issues.each do |raw|
|
||||
raw = raw.to_h
|
||||
gh_issue = IssueFormatter.new(project, raw, client)
|
||||
|
||||
begin
|
||||
|
@ -143,6 +144,7 @@ module Gitlab
|
|||
def import_pull_requests
|
||||
fetch_resources(:pull_requests, repo, state: :all, sort: :created, direction: :asc, per_page: 100) do |pull_requests|
|
||||
pull_requests.each do |raw|
|
||||
raw = raw.to_h
|
||||
gh_pull_request = PullRequestFormatter.new(project, raw, client)
|
||||
|
||||
next unless gh_pull_request.valid?
|
||||
|
@ -190,10 +192,12 @@ module Gitlab
|
|||
end
|
||||
|
||||
def apply_labels(issuable, raw)
|
||||
return unless raw.labels.count > 0
|
||||
raw = raw.to_h
|
||||
|
||||
label_ids = raw.labels
|
||||
.map { |attrs| @labels[attrs.name] }
|
||||
return unless raw[:labels].count > 0
|
||||
|
||||
label_ids = raw[:labels]
|
||||
.map { |attrs| @labels[attrs[:name]] }
|
||||
.compact
|
||||
|
||||
issuable.update_attribute(:label_ids, label_ids)
|
||||
|
@ -226,10 +230,12 @@ module Gitlab
|
|||
def create_comments(comments)
|
||||
ActiveRecord::Base.no_touching do
|
||||
comments.each do |raw|
|
||||
raw = raw.to_h
|
||||
|
||||
comment = CommentFormatter.new(project, raw, client)
|
||||
|
||||
# GH does not return info about comment's parent, so we guess it by checking its URL!
|
||||
*_, parent, iid = URI(raw.html_url).path.split('/')
|
||||
*_, parent, iid = URI(raw[:html_url]).path.split('/')
|
||||
|
||||
issuable = if parent == 'issues'
|
||||
Issue.find_by(project_id: project.id, iid: iid)
|
||||
|
@ -241,7 +247,7 @@ module Gitlab
|
|||
|
||||
issuable.notes.create!(comment.attributes)
|
||||
rescue StandardError => e
|
||||
errors << { type: :comment, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
|
||||
errors << { type: :comment, url: Gitlab::UrlSanitizer.sanitize(raw[:url]), errors: e.message }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -251,7 +257,7 @@ module Gitlab
|
|||
last_note_attrs = nil
|
||||
|
||||
cut_off_index = comments.find_index do |raw|
|
||||
comment = CommentFormatter.new(project, raw)
|
||||
comment = CommentFormatter.new(project, raw.to_h)
|
||||
comment_attrs = comment.attributes
|
||||
last_note_attrs ||= last_note.slice(*comment_attrs.keys)
|
||||
|
||||
|
@ -282,7 +288,7 @@ module Gitlab
|
|||
def import_releases
|
||||
fetch_resources(:releases, repo, per_page: 100) do |releases|
|
||||
releases.each do |raw|
|
||||
gh_release = ReleaseFormatter.new(project, raw)
|
||||
gh_release = ReleaseFormatter.new(project, raw.to_h)
|
||||
gh_release.create! if gh_release.valid?
|
||||
rescue StandardError => e
|
||||
errors << { type: :release, url: Gitlab::UrlSanitizer.sanitize(gh_release.url), errors: e.message }
|
||||
|
|
|
@ -9,7 +9,9 @@ module Gitlab
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
delegate :number, to: :raw_data
|
||||
def number
|
||||
raw_data[:number]
|
||||
end
|
||||
|
||||
def find_condition
|
||||
{ iid: number }
|
||||
|
@ -18,15 +20,15 @@ module Gitlab
|
|||
private
|
||||
|
||||
def state
|
||||
raw_data.state == 'closed' ? 'closed' : 'opened'
|
||||
raw_data[:state] == 'closed' ? 'closed' : 'opened'
|
||||
end
|
||||
|
||||
def assigned?
|
||||
raw_data.assignee.present?
|
||||
raw_data[:assignee].present?
|
||||
end
|
||||
|
||||
def author
|
||||
@author ||= UserFormatter.new(client, raw_data.user)
|
||||
@author ||= UserFormatter.new(client, raw_data[:user])
|
||||
end
|
||||
|
||||
def author_id
|
||||
|
@ -35,7 +37,7 @@ module Gitlab
|
|||
|
||||
def assignee
|
||||
if assigned?
|
||||
@assignee ||= UserFormatter.new(client, raw_data.assignee)
|
||||
@assignee ||= UserFormatter.new(client, raw_data[:assignee])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -46,7 +48,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def body
|
||||
raw_data.body || ""
|
||||
raw_data[:body] || ""
|
||||
end
|
||||
|
||||
def description
|
||||
|
@ -59,8 +61,8 @@ module Gitlab
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def milestone
|
||||
if raw_data.milestone.present?
|
||||
milestone = MilestoneFormatter.new(project, raw_data.milestone)
|
||||
if raw_data[:milestone].present?
|
||||
milestone = MilestoneFormatter.new(project, raw_data[:milestone])
|
||||
project.milestones.find_by(milestone.find_condition)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,18 +8,18 @@ module Gitlab
|
|||
iid: number,
|
||||
project: project,
|
||||
milestone: milestone,
|
||||
title: raw_data.title,
|
||||
title: raw_data[:title],
|
||||
description: description,
|
||||
state: state,
|
||||
author_id: author_id,
|
||||
assignee_ids: Array(assignee_id),
|
||||
created_at: raw_data.created_at,
|
||||
updated_at: raw_data.updated_at
|
||||
created_at: raw_data[:created_at],
|
||||
updated_at: raw_data[:updated_at]
|
||||
}
|
||||
end
|
||||
|
||||
def has_comments?
|
||||
raw_data.comments > 0
|
||||
raw_data[:comments] > 0
|
||||
end
|
||||
|
||||
def project_association
|
||||
|
@ -27,7 +27,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def pull_request?
|
||||
raw_data.pull_request.present?
|
||||
raw_data[:pull_request].present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,11 +28,11 @@ module Gitlab
|
|||
private
|
||||
|
||||
def color
|
||||
"##{raw_data.color}"
|
||||
"##{raw_data[:color]}"
|
||||
end
|
||||
|
||||
def title
|
||||
raw_data.name
|
||||
raw_data[:name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,12 +7,12 @@ module Gitlab
|
|||
{
|
||||
iid: number,
|
||||
project: project,
|
||||
title: raw_data.title,
|
||||
description: raw_data.description,
|
||||
due_date: raw_data.due_on,
|
||||
title: raw_data[:title],
|
||||
description: raw_data[:description],
|
||||
due_date: raw_data[:due_on],
|
||||
state: state,
|
||||
created_at: raw_data.created_at,
|
||||
updated_at: raw_data.updated_at
|
||||
created_at: raw_data[:created_at],
|
||||
updated_at: raw_data[:updated_at]
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -26,16 +26,16 @@ module Gitlab
|
|||
|
||||
def number
|
||||
if project.gitea_import?
|
||||
raw_data.id
|
||||
raw_data[:id]
|
||||
else
|
||||
raw_data.number
|
||||
raw_data[:number]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def state
|
||||
raw_data.state == 'closed' ? 'closed' : 'active'
|
||||
raw_data[:state] == 'closed' ? 'closed' : 'active'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Gitlab
|
|||
def attributes
|
||||
{
|
||||
iid: number,
|
||||
title: raw_data.title,
|
||||
title: raw_data[:title],
|
||||
description: description,
|
||||
source_project: source_branch_project,
|
||||
source_branch: source_branch_name,
|
||||
|
@ -21,8 +21,8 @@ module Gitlab
|
|||
milestone: milestone,
|
||||
author_id: author_id,
|
||||
assignee_id: assignee_id,
|
||||
created_at: raw_data.created_at,
|
||||
updated_at: raw_data.updated_at,
|
||||
created_at: raw_data[:created_at],
|
||||
updated_at: raw_data[:updated_at],
|
||||
imported: true
|
||||
}
|
||||
end
|
||||
|
@ -36,7 +36,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def source_branch
|
||||
@source_branch ||= BranchFormatter.new(project, raw_data.head)
|
||||
@source_branch ||= BranchFormatter.new(project, raw_data[:head])
|
||||
end
|
||||
|
||||
def source_branch_name
|
||||
|
@ -57,7 +57,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def target_branch
|
||||
@target_branch ||= BranchFormatter.new(project, raw_data.base)
|
||||
@target_branch ||= BranchFormatter.new(project, raw_data[:base])
|
||||
end
|
||||
|
||||
def target_branch_name
|
||||
|
@ -71,7 +71,7 @@ module Gitlab
|
|||
def cross_project?
|
||||
return true if source_branch_repo.nil?
|
||||
|
||||
source_branch_repo.id != target_branch_repo.id
|
||||
source_branch_repo[:id] != target_branch_repo[:id]
|
||||
end
|
||||
|
||||
def opened?
|
||||
|
@ -81,7 +81,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
def state
|
||||
if raw_data.state == 'closed' && raw_data.merged_at.present?
|
||||
if raw_data[:state] == 'closed' && raw_data[:merged_at].present?
|
||||
'merged'
|
||||
else
|
||||
super
|
||||
|
|
|
@ -6,13 +6,13 @@ module Gitlab
|
|||
def attributes
|
||||
{
|
||||
project: project,
|
||||
tag: raw_data.tag_name,
|
||||
name: raw_data.name,
|
||||
description: raw_data.body,
|
||||
created_at: raw_data.created_at,
|
||||
tag: raw_data[:tag_name],
|
||||
name: raw_data[:name],
|
||||
description: raw_data[:body],
|
||||
created_at: raw_data[:created_at],
|
||||
# Draft releases will have a null published_at
|
||||
released_at: raw_data.published_at || Time.current,
|
||||
updated_at: raw_data.created_at
|
||||
released_at: raw_data[:published_at] || Time.current,
|
||||
updated_at: raw_data[:created_at]
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -21,11 +21,11 @@ module Gitlab
|
|||
end
|
||||
|
||||
def find_condition
|
||||
{ tag: raw_data.tag_name }
|
||||
{ tag: raw_data[:tag_name] }
|
||||
end
|
||||
|
||||
def valid?
|
||||
!raw_data.draft && raw_data.tag_name.present?
|
||||
!raw_data[:draft] && raw_data[:tag_name].present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,13 +5,19 @@ module Gitlab
|
|||
class UserFormatter
|
||||
attr_reader :client, :raw
|
||||
|
||||
delegate :id, :login, to: :raw, allow_nil: true
|
||||
|
||||
def initialize(client, raw)
|
||||
@client = client
|
||||
@raw = raw
|
||||
end
|
||||
|
||||
def id
|
||||
raw[:id]
|
||||
end
|
||||
|
||||
def login
|
||||
raw[:login]
|
||||
end
|
||||
|
||||
def gitlab_id
|
||||
return @gitlab_id if defined?(@gitlab_id)
|
||||
|
||||
|
@ -21,7 +27,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
def email
|
||||
@email ||= client.user(raw.login).try(:email)
|
||||
@email ||= client.user(raw[:login]).to_h[:email]
|
||||
end
|
||||
|
||||
def find_by_email
|
||||
|
|
|
@ -425,21 +425,21 @@ FooBar
|
|||
end
|
||||
|
||||
it 'delegates to #markdown_unsafe when file name corresponds to Markdown' do
|
||||
expect(helper).to receive(:gitlab_markdown?).with('foo.md').and_return(true)
|
||||
expect(Gitlab::MarkupHelper).to receive(:gitlab_markdown?).with('foo.md').and_return(true)
|
||||
expect(helper).to receive(:markdown_unsafe).and_return('NOEL')
|
||||
|
||||
expect(helper.markup('foo.md', content)).to eq('NOEL')
|
||||
end
|
||||
|
||||
it 'delegates to #asciidoc_unsafe when file name corresponds to AsciiDoc' do
|
||||
expect(helper).to receive(:asciidoc?).with('foo.adoc').and_return(true)
|
||||
expect(Gitlab::MarkupHelper).to receive(:asciidoc?).with('foo.adoc').and_return(true)
|
||||
expect(helper).to receive(:asciidoc_unsafe).and_return('NOEL')
|
||||
|
||||
expect(helper.markup('foo.adoc', content)).to eq('NOEL')
|
||||
end
|
||||
|
||||
it 'uses passed in rendered content' do
|
||||
expect(helper).not_to receive(:gitlab_markdown?)
|
||||
expect(Gitlab::MarkupHelper).not_to receive(:gitlab_markdown?)
|
||||
expect(helper).not_to receive(:markdown_unsafe)
|
||||
|
||||
expect(helper.markup('foo.md', content, rendered: '<p>NOEL</p>')).to eq('<p>NOEL</p>')
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenEncryptedValues,
|
||||
:migration,
|
||||
schema: 20220922143634 do
|
||||
it { expect(described_class).to be < Gitlab::BackgroundMigration::BatchedMigrationJob }
|
||||
|
||||
describe '#perform' do
|
||||
let(:ci_runners) { table(:ci_runners, database: :ci) }
|
||||
|
||||
let(:test_worker) do
|
||||
described_class.new(
|
||||
start_id: 1,
|
||||
end_id: 4,
|
||||
batch_table: :ci_runners,
|
||||
batch_column: :id,
|
||||
sub_batch_size: 2,
|
||||
pause_ms: 0,
|
||||
connection: Ci::ApplicationRecord.connection
|
||||
)
|
||||
end
|
||||
|
||||
subject(:perform) { test_worker.perform }
|
||||
|
||||
before do
|
||||
ci_runners.create!(id: 1, runner_type: 1, token_encrypted: 'duplicate')
|
||||
ci_runners.create!(id: 2, runner_type: 1, token_encrypted: 'a-token')
|
||||
ci_runners.create!(id: 3, runner_type: 1, token_encrypted: 'duplicate-2')
|
||||
ci_runners.create!(id: 4, runner_type: 1, token_encrypted: nil)
|
||||
ci_runners.create!(id: 5, runner_type: 1, token_encrypted: 'duplicate-2')
|
||||
ci_runners.create!(id: 6, runner_type: 1, token_encrypted: 'duplicate')
|
||||
ci_runners.create!(id: 7, runner_type: 1, token_encrypted: 'another-token')
|
||||
ci_runners.create!(id: 8, runner_type: 1, token_encrypted: 'another-token')
|
||||
end
|
||||
|
||||
it 'nullifies duplicate encrypted tokens', :aggregate_failures do
|
||||
expect { perform }.to change { ci_runners.all.order(:id).pluck(:id, :token_encrypted).to_h }
|
||||
.from(
|
||||
{
|
||||
1 => 'duplicate',
|
||||
2 => 'a-token',
|
||||
3 => 'duplicate-2',
|
||||
4 => nil,
|
||||
5 => 'duplicate-2',
|
||||
6 => 'duplicate',
|
||||
7 => 'another-token',
|
||||
8 => 'another-token'
|
||||
}
|
||||
)
|
||||
.to(
|
||||
{
|
||||
1 => nil,
|
||||
2 => 'a-token',
|
||||
3 => nil,
|
||||
4 => nil,
|
||||
5 => nil,
|
||||
6 => nil,
|
||||
7 => 'another-token',
|
||||
8 => 'another-token'
|
||||
}
|
||||
)
|
||||
expect(ci_runners.count).to eq(8)
|
||||
expect(ci_runners.pluck(:token_encrypted).uniq).to match_array [
|
||||
nil, 'a-token', 'another-token'
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenValues,
|
||||
:migration,
|
||||
schema: 20220922143143 do
|
||||
it { expect(described_class).to be < Gitlab::BackgroundMigration::BatchedMigrationJob }
|
||||
|
||||
describe '#perform' do
|
||||
let(:ci_runners) { table(:ci_runners, database: :ci) }
|
||||
|
||||
let(:test_worker) do
|
||||
described_class.new(
|
||||
start_id: 1,
|
||||
end_id: 4,
|
||||
batch_table: :ci_runners,
|
||||
batch_column: :id,
|
||||
sub_batch_size: 2,
|
||||
pause_ms: 0,
|
||||
connection: Ci::ApplicationRecord.connection
|
||||
)
|
||||
end
|
||||
|
||||
subject(:perform) { test_worker.perform }
|
||||
|
||||
before do
|
||||
ci_runners.create!(id: 1, runner_type: 1, token: 'duplicate')
|
||||
ci_runners.create!(id: 2, runner_type: 1, token: 'a-token')
|
||||
ci_runners.create!(id: 3, runner_type: 1, token: 'duplicate-2')
|
||||
ci_runners.create!(id: 4, runner_type: 1, token: nil)
|
||||
ci_runners.create!(id: 5, runner_type: 1, token: 'duplicate-2')
|
||||
ci_runners.create!(id: 6, runner_type: 1, token: 'duplicate')
|
||||
ci_runners.create!(id: 7, runner_type: 1, token: 'another-token')
|
||||
ci_runners.create!(id: 8, runner_type: 1, token: 'another-token')
|
||||
end
|
||||
|
||||
it 'nullifies duplicate tokens', :aggregate_failures do
|
||||
expect { perform }.to change { ci_runners.all.order(:id).pluck(:id, :token).to_h }
|
||||
.from(
|
||||
{
|
||||
1 => 'duplicate',
|
||||
2 => 'a-token',
|
||||
3 => 'duplicate-2',
|
||||
4 => nil,
|
||||
5 => 'duplicate-2',
|
||||
6 => 'duplicate',
|
||||
7 => 'another-token',
|
||||
8 => 'another-token'
|
||||
}
|
||||
)
|
||||
.to(
|
||||
{
|
||||
1 => nil,
|
||||
2 => 'a-token',
|
||||
3 => nil,
|
||||
4 => nil,
|
||||
5 => nil,
|
||||
6 => nil,
|
||||
7 => 'another-token',
|
||||
8 => 'another-token'
|
||||
}
|
||||
)
|
||||
expect(ci_runners.count).to eq(8)
|
||||
expect(ci_runners.pluck(:token).uniq).to match_array [
|
||||
nil, 'a-token', 'another-token'
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::BranchFormatter do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let(:commit) { create(:commit, project: project) }
|
||||
let(:repo) { double }
|
||||
let(:raw) do
|
||||
|
@ -16,19 +16,19 @@ RSpec.describe Gitlab::LegacyGithubImport::BranchFormatter do
|
|||
|
||||
describe '#exists?' do
|
||||
it 'returns true when branch exists and commit is part of the branch' do
|
||||
branch = described_class.new(project, double(raw))
|
||||
branch = described_class.new(project, raw)
|
||||
|
||||
expect(branch.exists?).to eq true
|
||||
end
|
||||
|
||||
it 'returns false when branch exists and commit is not part of the branch' do
|
||||
branch = described_class.new(project, double(raw.merge(ref: 'feature')))
|
||||
branch = described_class.new(project, raw.merge(ref: 'feature'))
|
||||
|
||||
expect(branch.exists?).to eq false
|
||||
end
|
||||
|
||||
it 'returns false when branch does not exist' do
|
||||
branch = described_class.new(project, double(raw.merge(ref: 'removed-branch')))
|
||||
branch = described_class.new(project, raw.merge(ref: 'removed-branch'))
|
||||
|
||||
expect(branch.exists?).to eq false
|
||||
end
|
||||
|
@ -36,7 +36,7 @@ RSpec.describe Gitlab::LegacyGithubImport::BranchFormatter do
|
|||
|
||||
describe '#repo' do
|
||||
it 'returns raw repo' do
|
||||
branch = described_class.new(project, double(raw))
|
||||
branch = described_class.new(project, raw)
|
||||
|
||||
expect(branch.repo).to eq repo
|
||||
end
|
||||
|
@ -44,7 +44,7 @@ RSpec.describe Gitlab::LegacyGithubImport::BranchFormatter do
|
|||
|
||||
describe '#sha' do
|
||||
it 'returns raw sha' do
|
||||
branch = described_class.new(project, double(raw))
|
||||
branch = described_class.new(project, raw)
|
||||
|
||||
expect(branch.sha).to eq commit.id
|
||||
end
|
||||
|
@ -52,19 +52,19 @@ RSpec.describe Gitlab::LegacyGithubImport::BranchFormatter do
|
|||
|
||||
describe '#valid?' do
|
||||
it 'returns true when raw sha and ref are present' do
|
||||
branch = described_class.new(project, double(raw))
|
||||
branch = described_class.new(project, raw)
|
||||
|
||||
expect(branch.valid?).to eq true
|
||||
end
|
||||
|
||||
it 'returns false when raw sha is blank' do
|
||||
branch = described_class.new(project, double(raw.merge(sha: nil)))
|
||||
branch = described_class.new(project, raw.merge(sha: nil))
|
||||
|
||||
expect(branch.valid?).to eq false
|
||||
end
|
||||
|
||||
it 'returns false when raw ref is blank' do
|
||||
branch = described_class.new(project, double(raw.merge(ref: nil)))
|
||||
branch = described_class.new(project, raw.merge(ref: nil))
|
||||
|
||||
expect(branch.valid?).to eq false
|
||||
end
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::CommentFormatter do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let(:client) { double }
|
||||
let(:project) { create(:project) }
|
||||
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
|
||||
let(:octocat) { { id: 123456, login: 'octocat', email: 'octocat@example.com' } }
|
||||
let(:created_at) { DateTime.strptime('2013-04-10T20:09:31Z') }
|
||||
let(:updated_at) { DateTime.strptime('2014-03-03T18:58:10Z') }
|
||||
let(:base) do
|
||||
|
@ -27,7 +27,7 @@ RSpec.describe Gitlab::LegacyGithubImport::CommentFormatter do
|
|||
|
||||
describe '#attributes' do
|
||||
context 'when do not reference a portion of the diff' do
|
||||
let(:raw) { double(base) }
|
||||
let(:raw) { base }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -55,7 +55,7 @@ RSpec.describe Gitlab::LegacyGithubImport::CommentFormatter do
|
|||
}
|
||||
end
|
||||
|
||||
let(:raw) { double(base.merge(diff)) }
|
||||
let(:raw) { base.merge(diff) }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -74,22 +74,22 @@ RSpec.describe Gitlab::LegacyGithubImport::CommentFormatter do
|
|||
end
|
||||
|
||||
context 'when author is a GitLab user' do
|
||||
let(:raw) { double(base.merge(user: octocat)) }
|
||||
let(:raw) { base.merge(user: octocat) }
|
||||
|
||||
it 'returns GitLab user id associated with GitHub id as author_id' do
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(comment.attributes.fetch(:author_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub email as author_id' do
|
||||
gl_user = create(:user, email: octocat.email)
|
||||
gl_user = create(:user, email: octocat[:email])
|
||||
|
||||
expect(comment.attributes.fetch(:author_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns note without created at tag line' do
|
||||
create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(comment.attributes.fetch(:note)).to eq("I'm having a problem with this.")
|
||||
end
|
||||
|
|
|
@ -59,23 +59,23 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
end
|
||||
|
||||
let(:label1) do
|
||||
double(
|
||||
{
|
||||
name: 'Bug',
|
||||
color: 'ff0000',
|
||||
url: "#{api_root}/repos/octocat/Hello-World/labels/bug"
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:label2) do
|
||||
double(
|
||||
{
|
||||
name: nil,
|
||||
color: 'ff0000',
|
||||
url: "#{api_root}/repos/octocat/Hello-World/labels/bug"
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:milestone) do
|
||||
double(
|
||||
{
|
||||
id: 1347, # For Gitea
|
||||
number: 1347,
|
||||
state: 'open',
|
||||
|
@ -86,11 +86,11 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
updated_at: updated_at,
|
||||
closed_at: nil,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/milestones/1"
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:issue1) do
|
||||
double(
|
||||
{
|
||||
number: 1347,
|
||||
milestone: nil,
|
||||
state: 'open',
|
||||
|
@ -104,12 +104,12 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
updated_at: updated_at,
|
||||
closed_at: nil,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/issues/1347",
|
||||
labels: [double(name: 'Label #1')]
|
||||
)
|
||||
labels: [{ name: 'Label #1' }]
|
||||
}
|
||||
end
|
||||
|
||||
let(:issue2) do
|
||||
double(
|
||||
{
|
||||
number: 1348,
|
||||
milestone: nil,
|
||||
state: 'open',
|
||||
|
@ -123,12 +123,12 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
updated_at: updated_at,
|
||||
closed_at: nil,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/issues/1348",
|
||||
labels: [double(name: 'Label #2')]
|
||||
)
|
||||
labels: [{ name: 'Label #2' }]
|
||||
}
|
||||
end
|
||||
|
||||
let(:release1) do
|
||||
double(
|
||||
{
|
||||
tag_name: 'v1.0.0',
|
||||
name: 'First release',
|
||||
body: 'Release v1.0.0',
|
||||
|
@ -137,11 +137,11 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
published_at: created_at,
|
||||
updated_at: updated_at,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/releases/1"
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:release2) do
|
||||
double(
|
||||
{
|
||||
tag_name: 'v1.1.0',
|
||||
name: 'Second release',
|
||||
body: nil,
|
||||
|
@ -150,7 +150,7 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
published_at: created_at,
|
||||
updated_at: updated_at,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/releases/2"
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
subject { described_class.new(project) }
|
||||
|
@ -210,18 +210,18 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
end
|
||||
|
||||
let(:project) { create(:project, :repository, :wiki_disabled, import_url: "#{repo_root}/octocat/Hello-World.git") }
|
||||
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
|
||||
let(:octocat) { { id: 123456, login: 'octocat', email: 'octocat@example.com' } }
|
||||
let(:credentials) { { user: 'joe' } }
|
||||
|
||||
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
|
||||
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
|
||||
let(:repository) { double(id: 1, fork: false) }
|
||||
let(:repository) { { id: 1, fork: false } }
|
||||
let(:source_sha) { create(:commit, project: project).id }
|
||||
let(:source_branch) { double(ref: 'branch-merged', repo: repository, sha: source_sha, user: octocat) }
|
||||
let(:source_branch) { { ref: 'branch-merged', repo: repository, sha: source_sha, user: octocat } }
|
||||
let(:target_sha) { create(:commit, project: project, git_commit: RepoHelpers.another_sample_commit).id }
|
||||
let(:target_branch) { double(ref: 'master', repo: repository, sha: target_sha, user: octocat) }
|
||||
let(:target_branch) { { ref: 'master', repo: repository, sha: target_sha, user: octocat } }
|
||||
let(:pull_request) do
|
||||
double(
|
||||
{
|
||||
number: 1347,
|
||||
milestone: nil,
|
||||
state: 'open',
|
||||
|
@ -236,12 +236,12 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
closed_at: nil,
|
||||
merged_at: nil,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/pulls/1347",
|
||||
labels: [double(name: 'Label #2')]
|
||||
)
|
||||
labels: [{ name: 'Label #2' }]
|
||||
}
|
||||
end
|
||||
|
||||
let(:closed_pull_request) do
|
||||
double(
|
||||
{
|
||||
number: 1347,
|
||||
milestone: nil,
|
||||
state: 'closed',
|
||||
|
@ -256,8 +256,8 @@ RSpec.describe Gitlab::LegacyGithubImport::Importer do
|
|||
closed_at: updated_at,
|
||||
merged_at: nil,
|
||||
url: "#{api_root}/repos/octocat/Hello-World/pulls/1347",
|
||||
labels: [double(name: 'Label #2')]
|
||||
)
|
||||
labels: [{ name: 'Label #2' }]
|
||||
}
|
||||
end
|
||||
|
||||
context 'when importing a Gitea project' do
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'fast_spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::IssuableFormatter do
|
||||
let(:raw_data) do
|
||||
double(number: 42)
|
||||
{ number: 42 }
|
||||
end
|
||||
|
||||
let(:project) { double(import_type: 'github') }
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
||||
let_it_be(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
|
||||
let(:client) { double }
|
||||
let!(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
|
||||
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
|
||||
let(:octocat) { { id: 123456, login: 'octocat', email: 'octocat@example.com' } }
|
||||
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
|
||||
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
|
||||
|
||||
|
@ -34,7 +34,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
|
||||
shared_examples 'Gitlab::LegacyGithubImport::IssueFormatter#attributes' do
|
||||
context 'when issue is open' do
|
||||
let(:raw_data) { double(base_data.merge(state: 'open')) }
|
||||
let(:raw_data) { base_data.merge(state: 'open') }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -55,7 +55,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
end
|
||||
|
||||
context 'when issue is closed' do
|
||||
let(:raw_data) { double(base_data.merge(state: 'closed')) }
|
||||
let(:raw_data) { base_data.merge(state: 'closed') }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -76,28 +76,28 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
end
|
||||
|
||||
context 'when it is assigned to someone' do
|
||||
let(:raw_data) { double(base_data.merge(assignee: octocat)) }
|
||||
let(:raw_data) { base_data.merge(assignee: octocat) }
|
||||
|
||||
it 'returns nil as assignee_id when is not a GitLab user' do
|
||||
expect(issue.attributes.fetch(:assignee_ids)).to be_empty
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub id as assignee_id' do
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(issue.attributes.fetch(:assignee_ids)).to eq [gl_user.id]
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub email as assignee_id' do
|
||||
gl_user = create(:user, email: octocat.email)
|
||||
gl_user = create(:user, email: octocat[:email])
|
||||
|
||||
expect(issue.attributes.fetch(:assignee_ids)).to eq [gl_user.id]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it has a milestone' do
|
||||
let(:milestone) { double(id: 42, number: 42) }
|
||||
let(:raw_data) { double(base_data.merge(milestone: milestone)) }
|
||||
let(:milestone) { { id: 42, number: 42 } }
|
||||
let(:raw_data) { base_data.merge(milestone: milestone) }
|
||||
|
||||
it 'returns nil when milestone does not exist' do
|
||||
expect(issue.attributes.fetch(:milestone)).to be_nil
|
||||
|
@ -111,26 +111,26 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
end
|
||||
|
||||
context 'when author is a GitLab user' do
|
||||
let(:raw_data) { double(base_data.merge(user: octocat)) }
|
||||
let(:raw_data) { base_data.merge(user: octocat) }
|
||||
|
||||
it 'returns project creator_id as author_id when is not a GitLab user' do
|
||||
expect(issue.attributes.fetch(:author_id)).to eq project.creator_id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub id as author_id' do
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(issue.attributes.fetch(:author_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub email as author_id' do
|
||||
gl_user = create(:user, email: octocat.email)
|
||||
gl_user = create(:user, email: octocat[:email])
|
||||
|
||||
expect(issue.attributes.fetch(:author_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns description without created at tag line' do
|
||||
create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(issue.attributes.fetch(:description)).to eq("I'm having a problem with this.")
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
end
|
||||
|
||||
shared_examples 'Gitlab::LegacyGithubImport::IssueFormatter#number' do
|
||||
let(:raw_data) { double(base_data.merge(number: 1347)) }
|
||||
let(:raw_data) { base_data.merge(number: 1347) }
|
||||
|
||||
it 'returns issue number' do
|
||||
expect(issue.number).to eq 1347
|
||||
|
@ -161,7 +161,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
|
||||
describe '#has_comments?' do
|
||||
context 'when number of comments is greater than zero' do
|
||||
let(:raw_data) { double(base_data.merge(comments: 1)) }
|
||||
let(:raw_data) { base_data.merge(comments: 1) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(issue.has_comments?).to eq true
|
||||
|
@ -169,7 +169,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
end
|
||||
|
||||
context 'when number of comments is equal to zero' do
|
||||
let(:raw_data) { double(base_data.merge(comments: 0)) }
|
||||
let(:raw_data) { base_data.merge(comments: 0) }
|
||||
|
||||
it 'returns false' do
|
||||
expect(issue.has_comments?).to eq false
|
||||
|
@ -179,7 +179,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
|
||||
describe '#pull_request?' do
|
||||
context 'when mention a pull request' do
|
||||
let(:raw_data) { double(base_data.merge(pull_request: double)) }
|
||||
let(:raw_data) { base_data.merge(pull_request: double) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(issue.pull_request?).to eq true
|
||||
|
@ -187,7 +187,7 @@ RSpec.describe Gitlab::LegacyGithubImport::IssueFormatter do
|
|||
end
|
||||
|
||||
context 'when does not mention a pull request' do
|
||||
let(:raw_data) { double(base_data.merge(pull_request: nil)) }
|
||||
let(:raw_data) { base_data.merge(pull_request: nil) }
|
||||
|
||||
it 'returns false' do
|
||||
expect(issue.pull_request?).to eq false
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::LabelFormatter do
|
||||
let(:project) { create(:project) }
|
||||
let(:raw) { double(name: 'improvements', color: 'e6e6e6') }
|
||||
let_it_be(:project) { create(:project) }
|
||||
let(:raw) { { name: 'improvements', color: 'e6e6e6' } }
|
||||
|
||||
subject { described_class.new(project, raw) }
|
||||
|
||||
|
@ -27,7 +27,7 @@ RSpec.describe Gitlab::LegacyGithubImport::LabelFormatter do
|
|||
|
||||
context 'when label exists' do
|
||||
it 'does not create a new label' do
|
||||
Labels::CreateService.new(name: raw.name).execute(project: project)
|
||||
Labels::CreateService.new(name: raw[:name]).execute(project: project)
|
||||
|
||||
expect { subject.create! }.not_to change(Label, :count)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::MilestoneFormatter do
|
||||
let(:project) { create(:project) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
|
||||
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
|
||||
let(:base_data) do
|
||||
|
@ -26,7 +26,7 @@ RSpec.describe Gitlab::LegacyGithubImport::MilestoneFormatter do
|
|||
let(:data) { base_data.merge(iid_attr => 1347) }
|
||||
|
||||
context 'when milestone is open' do
|
||||
let(:raw_data) { double(data.merge(state: 'open')) }
|
||||
let(:raw_data) { data.merge(state: 'open') }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -45,7 +45,7 @@ RSpec.describe Gitlab::LegacyGithubImport::MilestoneFormatter do
|
|||
end
|
||||
|
||||
context 'when milestone is closed' do
|
||||
let(:raw_data) { double(data.merge(state: 'closed')) }
|
||||
let(:raw_data) { data.merge(state: 'closed') }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -65,7 +65,7 @@ RSpec.describe Gitlab::LegacyGithubImport::MilestoneFormatter do
|
|||
|
||||
context 'when milestone has a due date' do
|
||||
let(:due_date) { DateTime.strptime('2011-01-28T19:01:12Z') }
|
||||
let(:raw_data) { double(data.merge(due_on: due_date)) }
|
||||
let(:raw_data) { data.merge(due_on: due_date) }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let(:client) { double }
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:source_sha) { create(:commit, project: project).id }
|
||||
let(:target_commit) { create(:commit, project: project, git_commit: RepoHelpers.another_sample_commit) }
|
||||
let(:target_sha) { target_commit.id }
|
||||
let(:target_short_sha) { target_commit.id.to_s[0..7] }
|
||||
let(:repository) { double(id: 1, fork: false) }
|
||||
let(:repository) { { id: 1, fork: false } }
|
||||
let(:source_repo) { repository }
|
||||
let(:source_branch) { double(ref: 'branch-merged', repo: source_repo, sha: source_sha) }
|
||||
let(:forked_source_repo) { double(id: 2, fork: true, name: 'otherproject', full_name: 'company/otherproject') }
|
||||
let(:source_branch) { { ref: 'branch-merged', repo: source_repo, sha: source_sha } }
|
||||
let(:forked_source_repo) { { id: 2, fork: true, name: 'otherproject', full_name: 'company/otherproject' } }
|
||||
let(:target_repo) { repository }
|
||||
let(:target_branch) { double(ref: 'master', repo: target_repo, sha: target_sha, user: octocat) }
|
||||
let(:removed_branch) { double(ref: 'removed-branch', repo: source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', user: octocat) }
|
||||
let(:forked_branch) { double(ref: 'master', repo: forked_source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', user: octocat) }
|
||||
let(:branch_deleted_repo) { double(ref: 'master', repo: nil, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', user: octocat) }
|
||||
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
|
||||
let(:target_branch) { { ref: 'master', repo: target_repo, sha: target_sha, user: octocat } }
|
||||
let(:removed_branch) { { ref: 'removed-branch', repo: source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', user: octocat } }
|
||||
let(:forked_branch) { { ref: 'master', repo: forked_source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', user: octocat } }
|
||||
let(:branch_deleted_repo) { { ref: 'master', repo: nil, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', user: octocat } }
|
||||
let(:octocat) { { id: 123456, login: 'octocat', email: 'octocat@example.com' } }
|
||||
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
|
||||
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
|
||||
let(:base_data) do
|
||||
|
@ -48,7 +48,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
|
||||
shared_examples 'Gitlab::LegacyGithubImport::PullRequestFormatter#attributes' do
|
||||
context 'when pull request is open' do
|
||||
let(:raw_data) { double(base_data.merge(state: 'open')) }
|
||||
let(:raw_data) { base_data.merge(state: 'open') }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -75,7 +75,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when pull request is closed' do
|
||||
let(:raw_data) { double(base_data.merge(state: 'closed')) }
|
||||
let(:raw_data) { base_data.merge(state: 'closed') }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -103,7 +103,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
|
||||
context 'when pull request is merged' do
|
||||
let(:merged_at) { DateTime.strptime('2011-01-28T13:01:12Z') }
|
||||
let(:raw_data) { double(base_data.merge(state: 'closed', merged_at: merged_at)) }
|
||||
let(:raw_data) { base_data.merge(state: 'closed', merged_at: merged_at) }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -130,54 +130,54 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when it is assigned to someone' do
|
||||
let(:raw_data) { double(base_data.merge(assignee: octocat)) }
|
||||
let(:raw_data) { base_data.merge(assignee: octocat) }
|
||||
|
||||
it 'returns nil as assignee_id when is not a GitLab user' do
|
||||
expect(pull_request.attributes.fetch(:assignee_id)).to be_nil
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub id as assignee_id' do
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(pull_request.attributes.fetch(:assignee_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub email as assignee_id' do
|
||||
gl_user = create(:user, email: octocat.email)
|
||||
gl_user = create(:user, email: octocat[:email])
|
||||
|
||||
expect(pull_request.attributes.fetch(:assignee_id)).to eq gl_user.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when author is a GitLab user' do
|
||||
let(:raw_data) { double(base_data.merge(user: octocat)) }
|
||||
let(:raw_data) { base_data.merge(user: octocat) }
|
||||
|
||||
it 'returns project creator_id as author_id when is not a GitLab user' do
|
||||
expect(pull_request.attributes.fetch(:author_id)).to eq project.creator_id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub id as author_id' do
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(pull_request.attributes.fetch(:author_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id associated with GitHub email as author_id' do
|
||||
gl_user = create(:user, email: octocat.email)
|
||||
gl_user = create(:user, email: octocat[:email])
|
||||
|
||||
expect(pull_request.attributes.fetch(:author_id)).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns description without created at tag line' do
|
||||
create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(pull_request.attributes.fetch(:description)).to eq('Please pull these awesome changes')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it has a milestone' do
|
||||
let(:milestone) { double(id: 42, number: 42) }
|
||||
let(:raw_data) { double(base_data.merge(milestone: milestone)) }
|
||||
let(:milestone) { { id: 42, number: 42 } }
|
||||
let(:raw_data) { base_data.merge(milestone: milestone) }
|
||||
|
||||
it 'returns nil when milestone does not exist' do
|
||||
expect(pull_request.attributes.fetch(:milestone)).to be_nil
|
||||
|
@ -192,7 +192,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
shared_examples 'Gitlab::LegacyGithubImport::PullRequestFormatter#number' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns pull request number' do
|
||||
expect(pull_request.number).to eq 1347
|
||||
|
@ -201,7 +201,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
|
||||
shared_examples 'Gitlab::LegacyGithubImport::PullRequestFormatter#source_branch_name' do
|
||||
context 'when source branch exists' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns branch ref' do
|
||||
expect(pull_request.source_branch_name).to eq 'branch-merged'
|
||||
|
@ -209,7 +209,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when source branch does not exist' do
|
||||
let(:raw_data) { double(base_data.merge(head: removed_branch)) }
|
||||
let(:raw_data) { base_data.merge(head: removed_branch) }
|
||||
|
||||
it 'prefixes branch name with gh-:short_sha/:number/:user pattern to avoid collision' do
|
||||
expect(pull_request.source_branch_name).to eq "gh-#{target_short_sha}/1347/octocat/removed-branch"
|
||||
|
@ -217,7 +217,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when source branch is from a fork' do
|
||||
let(:raw_data) { double(base_data.merge(head: forked_branch)) }
|
||||
let(:raw_data) { base_data.merge(head: forked_branch) }
|
||||
|
||||
it 'prefixes branch name with gh-:short_sha/:number/:user pattern to avoid collision' do
|
||||
expect(pull_request.source_branch_name).to eq "gh-#{target_short_sha}/1347/octocat/master"
|
||||
|
@ -225,7 +225,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when source branch is from a deleted fork' do
|
||||
let(:raw_data) { double(base_data.merge(head: branch_deleted_repo)) }
|
||||
let(:raw_data) { base_data.merge(head: branch_deleted_repo) }
|
||||
|
||||
it 'prefixes branch name with gh-:short_sha/:number/:user pattern to avoid collision' do
|
||||
expect(pull_request.source_branch_name).to eq "gh-#{target_short_sha}/1347/octocat/master"
|
||||
|
@ -235,7 +235,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
|
||||
shared_examples 'Gitlab::LegacyGithubImport::PullRequestFormatter#target_branch_name' do
|
||||
context 'when target branch exists' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns branch ref' do
|
||||
expect(pull_request.target_branch_name).to eq 'master'
|
||||
|
@ -243,7 +243,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when target branch does not exist' do
|
||||
let(:raw_data) { double(base_data.merge(base: removed_branch)) }
|
||||
let(:raw_data) { base_data.merge(base: removed_branch) }
|
||||
|
||||
it 'prefixes branch name with gh-:short_sha/:number/:user pattern to avoid collision' do
|
||||
expect(pull_request.target_branch_name).to eq 'gl-2e5d3239/1347/octocat/removed-branch'
|
||||
|
@ -271,7 +271,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
|
||||
describe '#valid?' do
|
||||
context 'when source, and target repos are not a fork' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pull_request.valid?).to eq true
|
||||
|
@ -279,8 +279,8 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when source repo is a fork' do
|
||||
let(:source_repo) { double(id: 2) }
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:source_repo) { { id: 2 } }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pull_request.valid?).to eq true
|
||||
|
@ -288,8 +288,8 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when target repo is a fork' do
|
||||
let(:target_repo) { double(id: 2) }
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:target_repo) { { id: 2 } }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pull_request.valid?).to eq true
|
||||
|
@ -299,7 +299,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
|
||||
describe '#cross_project?' do
|
||||
context 'when source and target repositories are different' do
|
||||
let(:raw_data) { double(base_data.merge(head: forked_branch)) }
|
||||
let(:raw_data) { base_data.merge(head: forked_branch) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pull_request.cross_project?).to eq true
|
||||
|
@ -307,7 +307,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when source repository does not exist anymore' do
|
||||
let(:raw_data) { double(base_data.merge(head: branch_deleted_repo)) }
|
||||
let(:raw_data) { base_data.merge(head: branch_deleted_repo) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pull_request.cross_project?).to eq true
|
||||
|
@ -315,7 +315,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
context 'when source and target repositories are the same' do
|
||||
let(:raw_data) { double(base_data.merge(head: source_branch)) }
|
||||
let(:raw_data) { base_data.merge(head: source_branch) }
|
||||
|
||||
it 'returns false' do
|
||||
expect(pull_request.cross_project?).to eq false
|
||||
|
@ -324,7 +324,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
describe '#source_branch_exists?' do
|
||||
let(:raw_data) { double(base_data.merge(head: forked_branch)) }
|
||||
let(:raw_data) { base_data.merge(head: forked_branch) }
|
||||
|
||||
it 'returns false when is a cross_project' do
|
||||
expect(pull_request.source_branch_exists?).to eq false
|
||||
|
@ -332,7 +332,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
describe '#url' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'return raw url' do
|
||||
expect(pull_request.url).to eq 'https://api.github.com/repos/octocat/Hello-World/pulls/1347'
|
||||
|
@ -340,7 +340,7 @@ RSpec.describe Gitlab::LegacyGithubImport::PullRequestFormatter do
|
|||
end
|
||||
|
||||
describe '#opened?' do
|
||||
let(:raw_data) { double(base_data.merge(state: 'open')) }
|
||||
let(:raw_data) { base_data.merge(state: 'open') }
|
||||
|
||||
it 'returns true when state is "open"' do
|
||||
expect(pull_request.opened?).to be_truthy
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::ReleaseFormatter do
|
||||
let!(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
|
||||
let(:octocat) { double(id: 123456, login: 'octocat') }
|
||||
let_it_be(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
|
||||
let(:octocat) { { id: 123456, login: 'octocat' } }
|
||||
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
|
||||
let(:published_at) { DateTime.strptime('2011-01-26T20:00:00Z') }
|
||||
|
||||
|
@ -22,7 +22,7 @@ RSpec.describe Gitlab::LegacyGithubImport::ReleaseFormatter do
|
|||
subject(:release) { described_class.new(project, raw_data) }
|
||||
|
||||
describe '#attributes' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns formatted attributes' do
|
||||
expected = {
|
||||
|
@ -49,7 +49,7 @@ RSpec.describe Gitlab::LegacyGithubImport::ReleaseFormatter do
|
|||
|
||||
describe '#valid' do
|
||||
context 'when release is not a draft' do
|
||||
let(:raw_data) { double(base_data) }
|
||||
let(:raw_data) { base_data }
|
||||
|
||||
it 'returns true' do
|
||||
expect(release.valid?).to eq true
|
||||
|
@ -57,7 +57,7 @@ RSpec.describe Gitlab::LegacyGithubImport::ReleaseFormatter do
|
|||
end
|
||||
|
||||
context 'when release is draft' do
|
||||
let(:raw_data) { double(base_data.merge(draft: true)) }
|
||||
let(:raw_data) { base_data.merge(draft: true) }
|
||||
|
||||
it 'returns false' do
|
||||
expect(release.valid?).to eq false
|
||||
|
@ -65,7 +65,7 @@ RSpec.describe Gitlab::LegacyGithubImport::ReleaseFormatter do
|
|||
end
|
||||
|
||||
context 'when release has NULL tag' do
|
||||
let(:raw_data) { double(base_data.merge(tag_name: '')) }
|
||||
let(:raw_data) { base_data.merge(tag_name: '') }
|
||||
|
||||
it 'returns false' do
|
||||
expect(release.valid?).to eq false
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::LegacyGithubImport::UserFormatter do
|
||||
let(:client) { double }
|
||||
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
|
||||
let(:octocat) { { id: 123456, login: 'octocat', email: 'octocat@example.com' } }
|
||||
|
||||
subject(:user) { described_class.new(client, octocat) }
|
||||
|
||||
|
@ -15,33 +15,33 @@ RSpec.describe Gitlab::LegacyGithubImport::UserFormatter do
|
|||
describe '#gitlab_id' do
|
||||
context 'when GitHub user is a GitLab user' do
|
||||
it 'return GitLab user id when user associated their account with GitHub' do
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat.id, provider: 'github')
|
||||
gl_user = create(:omniauth_user, extern_uid: octocat[:id], provider: 'github')
|
||||
|
||||
expect(user.gitlab_id).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id when user confirmed primary email matches GitHub email' do
|
||||
gl_user = create(:user, email: octocat.email)
|
||||
gl_user = create(:user, email: octocat[:email])
|
||||
|
||||
expect(user.gitlab_id).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id when user unconfirmed primary email matches GitHub email' do
|
||||
gl_user = create(:user, :unconfirmed, email: octocat.email)
|
||||
gl_user = create(:user, :unconfirmed, email: octocat[:email])
|
||||
|
||||
expect(user.gitlab_id).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns GitLab user id when user confirmed secondary email matches GitHub email' do
|
||||
gl_user = create(:user, email: 'johndoe@example.com')
|
||||
create(:email, :confirmed, user: gl_user, email: octocat.email)
|
||||
create(:email, :confirmed, user: gl_user, email: octocat[:email])
|
||||
|
||||
expect(user.gitlab_id).to eq gl_user.id
|
||||
end
|
||||
|
||||
it 'returns nil when user unconfirmed secondary email matches GitHub email' do
|
||||
gl_user = create(:user, email: 'johndoe@example.com')
|
||||
create(:email, user: gl_user, email: octocat.email)
|
||||
create(:email, user: gl_user, email: octocat[:email])
|
||||
|
||||
expect(user.gitlab_id).to be_nil
|
||||
end
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe ScheduleResetDuplicateCiRunnersTokenValues, migration: :gitlab_ci do
|
||||
let(:migration) { described_class::MIGRATION }
|
||||
|
||||
describe '#up' do
|
||||
it 'schedules background jobs for each batch of runners' do
|
||||
migrate!
|
||||
|
||||
expect(migration).to(
|
||||
have_scheduled_batched_migration(
|
||||
gitlab_schema: :gitlab_ci,
|
||||
table_name: :ci_runners,
|
||||
column_name: :id,
|
||||
interval: described_class::DELAY_INTERVAL,
|
||||
batch_size: described_class::BATCH_SIZE,
|
||||
max_batch_size: described_class::MAX_BATCH_SIZE,
|
||||
sub_batch_size: described_class::SUB_BATCH_SIZE
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'deletes all batched migration records' do
|
||||
migrate!
|
||||
schema_migrate_down!
|
||||
|
||||
expect(migration).not_to have_scheduled_batched_migration
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe ScheduleResetDuplicateCiRunnersTokenEncryptedValues, migration: :gitlab_ci do
|
||||
let(:migration) { described_class::MIGRATION }
|
||||
|
||||
describe '#up' do
|
||||
it 'schedules background jobs for each batch of runners' do
|
||||
migrate!
|
||||
|
||||
expect(migration).to(
|
||||
have_scheduled_batched_migration(
|
||||
gitlab_schema: :gitlab_ci,
|
||||
table_name: :ci_runners,
|
||||
column_name: :id,
|
||||
interval: described_class::DELAY_INTERVAL,
|
||||
batch_size: described_class::BATCH_SIZE,
|
||||
max_batch_size: described_class::MAX_BATCH_SIZE,
|
||||
sub_batch_size: described_class::SUB_BATCH_SIZE
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'deletes all batched migration records' do
|
||||
migrate!
|
||||
schema_migrate_down!
|
||||
|
||||
expect(migration).not_to have_scheduled_batched_migration
|
||||
end
|
||||
end
|
||||
end
|
|
@ -91,10 +91,6 @@ RSpec.describe Ci::PipelineArtifacts::DestroyAllExpiredService, :clean_gitlab_re
|
|||
|
||||
before do
|
||||
create_list(:ci_pipeline_artifact, 2, :artifact_unlocked, expire_at: 1.week.ago)
|
||||
end
|
||||
|
||||
context 'with ci_destroy_unlocked_pipeline_artifacts feature flag enabled' do
|
||||
before do
|
||||
allow(service).to receive(:legacy_destroy_pipeline_artifacts)
|
||||
end
|
||||
|
||||
|
@ -119,19 +115,6 @@ RSpec.describe Ci::PipelineArtifacts::DestroyAllExpiredService, :clean_gitlab_re
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with ci_destroy_unlocked_pipeline_artifacts feature flag disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_destroy_unlocked_pipeline_artifacts: false)
|
||||
end
|
||||
|
||||
it 'destroys all expired artifacts' do
|
||||
expect(service).not_to receive(:destroy_unlocked_pipeline_artifacts)
|
||||
expect { subject }.to change { Ci::PipelineArtifact.count }.by(-2)
|
||||
expect(not_expired_artifact.reload).to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.destroy_artifacts_batch' do
|
||||
|
|
|
@ -74,8 +74,8 @@ RSpec.describe ProjectCacheWorker do
|
|||
|
||||
context 'with plain readme' do
|
||||
it 'refreshes the method caches' do
|
||||
allow(MarkupHelper).to receive(:gitlab_markdown?).and_return(false)
|
||||
allow(MarkupHelper).to receive(:plain?).and_return(true)
|
||||
allow(Gitlab::MarkupHelper).to receive(:gitlab_markdown?).and_return(false)
|
||||
allow(Gitlab::MarkupHelper).to receive(:plain?).and_return(true)
|
||||
|
||||
expect_any_instance_of(Repository).to receive(:refresh_method_caches)
|
||||
.with(%i(readme))
|
||||
|
|
Loading…
Reference in New Issue