shipit-engine 0.32.0 → 0.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -2
  3. data/app/assets/images/magic-solid.svg +1 -0
  4. data/app/assets/javascripts/shipit/repositories_search.js.coffee +60 -0
  5. data/app/assets/javascripts/shipit/{search.js.coffee → stack_search.js.coffee} +0 -0
  6. data/app/assets/stylesheets/_pages/_deploy.scss +2 -3
  7. data/app/assets/stylesheets/_pages/_repositories.scss +148 -0
  8. data/app/assets/stylesheets/_pages/_stacks.scss +19 -0
  9. data/app/assets/stylesheets/shipit.scss +1 -0
  10. data/app/controllers/shipit/api/ccmenu_controller.rb +1 -1
  11. data/app/controllers/shipit/api/deploys_controller.rb +2 -0
  12. data/app/controllers/shipit/api/{pull_requests_controller.rb → merge_requests_controller.rb} +8 -8
  13. data/app/controllers/shipit/api/rollbacks_controller.rb +2 -1
  14. data/app/controllers/shipit/api/stacks_controller.rb +15 -1
  15. data/app/controllers/shipit/deploys_controller.rb +1 -1
  16. data/app/controllers/shipit/merge_requests_controller.rb +31 -0
  17. data/app/controllers/shipit/merge_status_controller.rb +15 -15
  18. data/app/controllers/shipit/repositories_controller.rb +74 -0
  19. data/app/controllers/shipit/stacks_controller.rb +2 -2
  20. data/app/controllers/shipit/tasks_controller.rb +2 -2
  21. data/app/controllers/shipit/webhooks_controller.rb +23 -4
  22. data/app/helpers/shipit/chunks_helper.rb +2 -2
  23. data/app/helpers/shipit/github_url_helper.rb +8 -0
  24. data/app/helpers/shipit/shipit_helper.rb +0 -1
  25. data/app/helpers/shipit/stacks_helper.rb +4 -0
  26. data/app/jobs/shipit/create_on_github_job.rb +1 -0
  27. data/app/jobs/shipit/deliver_hook_job.rb +1 -1
  28. data/app/jobs/shipit/destroy_repository_job.rb +24 -0
  29. data/app/jobs/shipit/destroy_stack_job.rb +2 -2
  30. data/app/jobs/shipit/github_sync_job.rb +13 -9
  31. data/app/jobs/shipit/perform_task_job.rb +4 -98
  32. data/app/jobs/shipit/process_merge_requests_job.rb +32 -0
  33. data/app/jobs/shipit/refresh_merge_request_job.rb +11 -0
  34. data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +1 -1
  35. data/app/models/shipit/anonymous_user.rb +10 -2
  36. data/app/models/shipit/check_run.rb +38 -2
  37. data/app/models/shipit/command_line_user.rb +4 -0
  38. data/app/models/shipit/commit.rb +31 -20
  39. data/app/models/shipit/commit_checks.rb +14 -13
  40. data/app/models/shipit/commit_deployment.rb +3 -3
  41. data/app/models/shipit/commit_deployment_status.rb +3 -3
  42. data/app/models/shipit/deploy.rb +17 -11
  43. data/app/models/shipit/deploy_spec/file_system.rb +11 -5
  44. data/app/models/shipit/deploy_spec/lerna_discovery.rb +12 -4
  45. data/app/models/shipit/deploy_spec.rb +16 -4
  46. data/app/models/shipit/duration.rb +2 -0
  47. data/app/models/shipit/hook.rb +28 -2
  48. data/app/models/shipit/merge_request.rb +304 -0
  49. data/app/models/shipit/provisioning_handler/base.rb +30 -0
  50. data/app/models/shipit/provisioning_handler/unregistered_provisioning_handler.rb +35 -0
  51. data/app/models/shipit/provisioning_handler.rb +32 -0
  52. data/app/models/shipit/pull_request.rb +26 -265
  53. data/app/models/shipit/pull_request_assignment.rb +10 -0
  54. data/app/models/shipit/release_status.rb +1 -1
  55. data/app/models/shipit/repository.rb +63 -3
  56. data/app/models/shipit/review_stack.rb +130 -0
  57. data/app/models/shipit/review_stack_provisioning_queue.rb +39 -0
  58. data/app/models/shipit/rollback.rb +5 -0
  59. data/app/models/shipit/stack.rb +78 -30
  60. data/app/models/shipit/status/group.rb +1 -1
  61. data/app/models/shipit/task.rb +62 -9
  62. data/app/models/shipit/task_execution_strategy/base.rb +20 -0
  63. data/app/models/shipit/task_execution_strategy/default.rb +109 -0
  64. data/app/models/shipit/team.rb +4 -2
  65. data/app/models/shipit/user.rb +10 -1
  66. data/app/models/shipit/webhooks/handlers/pull_request/assigned_handler.rb +74 -0
  67. data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +68 -0
  68. data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +74 -0
  69. data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +127 -0
  70. data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +106 -0
  71. data/app/models/shipit/webhooks/handlers/pull_request/opened_handler.rb +83 -0
  72. data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +88 -0
  73. data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +103 -0
  74. data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +107 -0
  75. data/app/models/shipit/webhooks/handlers/push_handler.rb +4 -1
  76. data/app/models/shipit/webhooks.rb +10 -0
  77. data/app/serializers/shipit/deploy_serializer.rb +6 -0
  78. data/app/serializers/shipit/merge_request_serializer.rb +21 -0
  79. data/app/serializers/shipit/pull_request_serializer.rb +5 -8
  80. data/app/serializers/shipit/review_stack_serializer.rb +7 -0
  81. data/app/serializers/shipit/stack_serializer.rb +7 -6
  82. data/app/serializers/shipit/tail_task_serializer.rb +10 -2
  83. data/app/serializers/shipit/task_serializer.rb +1 -1
  84. data/app/validators/subset_validator.rb +1 -1
  85. data/app/views/layouts/merge_status.html.erb +1 -1
  86. data/app/views/shipit/merge_requests/_merge_request.html.erb +29 -0
  87. data/app/views/shipit/{pull_requests → merge_requests}/index.html.erb +2 -2
  88. data/app/views/shipit/merge_requests/merge_requests/_pull_request.html.erb +29 -0
  89. data/app/views/shipit/merge_requests/merge_requests/index.html.erb +20 -0
  90. data/app/views/shipit/merge_status/_merge_queue_button.html.erb +3 -3
  91. data/app/views/shipit/merge_status/backlogged.html.erb +1 -1
  92. data/app/views/shipit/merge_status/failure.html.erb +1 -1
  93. data/app/views/shipit/merge_status/locked.html.erb +1 -1
  94. data/app/views/shipit/merge_status/success.html.erb +2 -2
  95. data/app/views/shipit/repositories/_header.html.erb +19 -0
  96. data/app/views/shipit/repositories/index.html.erb +31 -0
  97. data/app/views/shipit/repositories/new.html.erb +23 -0
  98. data/app/views/shipit/repositories/settings.html.erb +53 -0
  99. data/app/views/shipit/repositories/show.html.erb +30 -0
  100. data/app/views/shipit/stacks/_banners.html.erb +15 -1
  101. data/app/views/shipit/stacks/_header.html.erb +5 -2
  102. data/app/views/shipit/stacks/_stack.html.erb +8 -0
  103. data/app/views/shipit/stacks/index.html.erb +2 -1
  104. data/app/views/shipit/stacks/new.html.erb +1 -1
  105. data/app/views/shipit/stacks/settings.html.erb +5 -5
  106. data/app/views/shipit/stacks/show.html.erb +1 -1
  107. data/app/views/shipit/tasks/_task_output.html.erb +1 -1
  108. data/config/routes.rb +15 -5
  109. data/config/secrets.development.example.yml +24 -0
  110. data/config/secrets.development.shopify.yml +20 -9
  111. data/db/migrate/20200706145406_add_review_stacks.rb +12 -0
  112. data/db/migrate/20200804144639_rename_pull_request_to_merge_request.rb +7 -0
  113. data/db/migrate/20200804161512_rename_commits_pull_request_id_to_merge_request_id.rb +5 -0
  114. data/db/migrate/20200813134712_recreate_shipit_pull_requests.rb +22 -0
  115. data/db/migrate/20200813194056_create_pull_request_assignments.rb +8 -0
  116. data/db/migrate/20201001125502_add_provision_pr_stacks_flag_to_repositories.rb +7 -0
  117. data/db/migrate/20201008145809_add_retry_attempt_to_tasks.rb +5 -0
  118. data/db/migrate/20201008152744_add_max_retries_to_tasks.rb +5 -0
  119. data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
  120. data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
  121. data/db/migrate/20210823075617_change_check_runs_github_updated_at_default.rb +5 -0
  122. data/lib/shipit/command.rb +7 -6
  123. data/lib/shipit/commands.rb +18 -5
  124. data/lib/shipit/engine.rb +2 -0
  125. data/lib/shipit/flock.rb +8 -1
  126. data/lib/shipit/github_app.rb +8 -6
  127. data/lib/shipit/octokit_iterator.rb +3 -3
  128. data/lib/shipit/review_stack_commands.rb +8 -0
  129. data/lib/shipit/simple_message_verifier.rb +2 -2
  130. data/lib/shipit/stack_commands.rb +36 -7
  131. data/lib/shipit/task_commands.rb +8 -1
  132. data/lib/shipit/version.rb +1 -1
  133. data/lib/shipit.rb +50 -16
  134. data/lib/snippets/publish-lerna-independent-packages +35 -34
  135. data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
  136. data/lib/tasks/cron.rake +11 -2
  137. data/test/controllers/api/ccmenu_controller_test.rb +1 -1
  138. data/test/controllers/api/deploys_controller_test.rb +17 -0
  139. data/test/controllers/api/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +12 -12
  140. data/test/controllers/api/outputs_controller_test.rb +1 -0
  141. data/test/controllers/api/rollback_controller_test.rb +1 -1
  142. data/test/controllers/api/stacks_controller_test.rb +42 -8
  143. data/test/controllers/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +6 -6
  144. data/test/controllers/repositories_controller_test.rb +71 -0
  145. data/test/controllers/stacks_controller_test.rb +9 -1
  146. data/test/controllers/tasks_controller_test.rb +14 -2
  147. data/test/controllers/webhooks_controller_test.rb +27 -12
  148. data/test/dummy/app/assets/config/manifest.js +3 -0
  149. data/test/dummy/config/application.rb +7 -2
  150. data/test/dummy/config/database.yml +9 -0
  151. data/test/dummy/config/environments/development.rb +1 -4
  152. data/test/dummy/config/environments/test.rb +0 -5
  153. data/test/dummy/config/secrets_double_github_app.yml +79 -0
  154. data/test/dummy/db/schema.rb +56 -17
  155. data/test/dummy/db/seeds.rb +2 -1
  156. data/test/fixtures/payloads/check_suite_master.json +4 -32
  157. data/test/fixtures/payloads/invalid_pull_request.json +117 -0
  158. data/test/fixtures/payloads/provision_disabled_pull_request.json +454 -0
  159. data/test/fixtures/payloads/pull_request_assigned.json +480 -0
  160. data/test/fixtures/payloads/pull_request_closed.json +454 -0
  161. data/test/fixtures/payloads/pull_request_labeled.json +461 -0
  162. data/test/fixtures/payloads/pull_request_opened.json +454 -0
  163. data/test/fixtures/payloads/pull_request_reopened.json +454 -0
  164. data/test/fixtures/payloads/pull_request_unlabeled.json +454 -0
  165. data/test/fixtures/payloads/pull_request_with_no_repo.json +454 -0
  166. data/test/fixtures/payloads/push_master.json +1 -1
  167. data/test/fixtures/payloads/push_not_master.json +1 -1
  168. data/test/fixtures/shipit/commits.yml +17 -4
  169. data/test/fixtures/shipit/hooks.yml +1 -0
  170. data/test/fixtures/shipit/merge_requests.yml +141 -0
  171. data/test/fixtures/shipit/pull_request_assignments.yml +3 -0
  172. data/test/fixtures/shipit/pull_requests.yml +10 -131
  173. data/test/fixtures/shipit/repositories.yml +1 -0
  174. data/test/fixtures/shipit/stacks.yml +145 -0
  175. data/test/fixtures/shipit/statuses.yml +9 -0
  176. data/test/fixtures/shipit/tasks.yml +4 -1
  177. data/test/fixtures/shipit/users.yml +7 -0
  178. data/test/helpers/json_helper.rb +5 -1
  179. data/test/helpers/payloads_helper.rb +4 -0
  180. data/test/jobs/chunk_rollup_job_test.rb +15 -1
  181. data/test/jobs/destroy_repository_job_test.rb +27 -0
  182. data/test/jobs/github_sync_job_test.rb +2 -1
  183. data/test/jobs/perform_task_job_test.rb +8 -8
  184. data/test/jobs/{merge_pull_requests_job_test.rb → process_merge_requests_job_test.rb} +18 -18
  185. data/test/lib/shipit/deploy_commands_test.rb +16 -0
  186. data/test/lib/shipit/task_commands_test.rb +17 -0
  187. data/test/models/commit_deployment_status_test.rb +3 -3
  188. data/test/models/commits_test.rb +24 -13
  189. data/test/models/deploy_spec_test.rb +64 -24
  190. data/test/models/deploys_test.rb +188 -14
  191. data/test/models/hook_test.rb +30 -1
  192. data/test/models/{pull_request_test.rb → merge_request_test.rb} +49 -34
  193. data/test/models/pull_request_assignment_test.rb +16 -0
  194. data/test/models/shipit/check_run_test.rb +124 -5
  195. data/test/models/shipit/provisioning_handler/base_test.rb +33 -0
  196. data/test/models/shipit/provisioning_handler/unregistered_provisioning_handler_test.rb +49 -0
  197. data/test/models/shipit/provisioning_handler_test.rb +64 -0
  198. data/test/models/shipit/pull_request_test.rb +52 -0
  199. data/test/models/shipit/repository_test.rb +5 -1
  200. data/test/models/shipit/review_stack_provision_status_test.rb +77 -0
  201. data/test/models/shipit/review_stack_provisioning_queue_test.rb +63 -0
  202. data/test/models/shipit/review_stack_test.rb +91 -0
  203. data/test/models/{stacks_test.rb → shipit/stacks_test.rb} +52 -8
  204. data/test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb +45 -0
  205. data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +192 -0
  206. data/test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb +47 -0
  207. data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +209 -0
  208. data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +332 -0
  209. data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +238 -0
  210. data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +282 -0
  211. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +107 -0
  212. data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +324 -0
  213. data/test/models/shipit/{wehbooks → webhooks}/handlers_test.rb +0 -0
  214. data/test/models/tasks_test.rb +66 -3
  215. data/test/serializers/shipit/pull_request_serializer_test.rb +29 -0
  216. data/test/test_helper.rb +15 -0
  217. data/test/unit/anonymous_user_serializer_test.rb +1 -1
  218. data/test/unit/command_test.rb +8 -3
  219. data/test/unit/commit_serializer_test.rb +1 -1
  220. data/test/unit/deploy_commands_test.rb +73 -17
  221. data/test/unit/deploy_serializer_test.rb +1 -1
  222. data/test/unit/github_app_test.rb +2 -3
  223. data/test/unit/github_apps_test.rb +416 -0
  224. data/test/unit/github_url_helper_test.rb +5 -0
  225. data/test/unit/shipit_deployment_checks_test.rb +77 -0
  226. data/test/unit/shipit_task_execution_strategy_test.rb +47 -0
  227. data/test/unit/shipit_test.rb +14 -0
  228. data/test/unit/user_serializer_test.rb +1 -1
  229. metadata +306 -188
  230. data/app/controllers/shipit/pull_requests_controller.rb +0 -31
  231. data/app/jobs/shipit/merge_pull_requests_job.rb +0 -32
  232. data/app/jobs/shipit/refresh_pull_request_job.rb +0 -11
  233. data/app/views/shipit/pull_requests/_pull_request.html.erb +0 -29
  234. data/test/fixtures/shipit/output_chunks.yml +0 -47
  235. data/test/models/output_chunk_test.rb +0 -21
@@ -36,6 +36,35 @@ module Shipit
36
36
  end
37
37
  end
38
38
 
39
+ test ".deliver! sends request with correct method, headers, and body" do
40
+ stub_request(:post, @hook.delivery_url).to_return(body: 'OK')
41
+ body = { 'foo' => 42 }
42
+ expected_body = JSON.pretty_generate(body)
43
+ expected_signature = Hook::DeliverySigner.new(@hook.secret).sign(expected_body)
44
+
45
+ perform_enqueued_jobs(only: DeliverHookJob) do
46
+ @hook.deliver!(:deploy, body)
47
+ end
48
+ assert_performed_jobs 1
49
+ assert_requested :post, @hook.delivery_url do |req|
50
+ req.headers['X-Shipit-Signature'] == expected_signature
51
+ end
52
+ end
53
+
54
+ test ".deliver! sends without signature if no secret is configured" do
55
+ stub_request(:post, @hook.delivery_url).to_return(body: 'OK')
56
+ @hook.update!(secret: '')
57
+ body = { 'foo' => 42 }
58
+
59
+ perform_enqueued_jobs(only: DeliverHookJob) do
60
+ @hook.deliver!(:deploy, body)
61
+ end
62
+ assert_performed_jobs 1
63
+ assert_requested :post, @hook.delivery_url do |req|
64
+ !req.headers.key?('X-Shipit-Signature')
65
+ end
66
+ end
67
+
39
68
  test ".scoped? returns true if the hook has a stack_id" do
40
69
  @hook.stack_id = nil
41
70
  refute @hook.scoped?
@@ -73,7 +102,7 @@ module Shipit
73
102
  locked_stack = Stack.first
74
103
  locked_stack.lock("Some Reason", nil)
75
104
  serialized = Hook.coerce_payload(stack: locked_stack)
76
- assert_json("stack.lock_author.anonymous", true, document: serialized)
105
+ assert_json_document(serialized, "stack.lock_author.anonymous", true)
77
106
  end
78
107
  end
79
108
  end
@@ -2,24 +2,24 @@
2
2
  require 'test_helper'
3
3
 
4
4
  module Shipit
5
- class PullRequestTest < ActiveSupport::TestCase
5
+ class MergeRequestTest < ActiveSupport::TestCase
6
6
  setup do
7
7
  @stack = shipit_stacks(:shipit)
8
- @pr = shipit_pull_requests(:shipit_pending)
8
+ @pr = shipit_merge_requests(:shipit_pending)
9
9
  @user = shipit_users(:walrus)
10
10
  end
11
11
 
12
12
  test ".request_merge! creates a record and schedule a refresh" do
13
- pull_request = nil
14
- assert_enqueued_with(job: RefreshPullRequestJob) do
15
- pull_request = PullRequest.request_merge!(@stack, 64, @user)
13
+ merge_request = nil
14
+ assert_enqueued_with(job: RefreshMergeRequestJob) do
15
+ merge_request = MergeRequest.request_merge!(@stack, 64, @user)
16
16
  end
17
- assert_predicate pull_request, :persisted?
17
+ assert_predicate merge_request, :persisted?
18
18
  end
19
19
 
20
20
  test ".request_merge! only track pull requests once" do
21
- assert_difference -> { PullRequest.count }, +1 do
22
- 5.times { PullRequest.request_merge!(@stack, 999, @user) }
21
+ assert_difference -> { MergeRequest.count }, +1 do
22
+ 5.times { MergeRequest.request_merge!(@stack, 999, @user) }
23
23
  end
24
24
  end
25
25
 
@@ -27,7 +27,7 @@ module Shipit
27
27
  original_merge_requested_at = @pr.merge_requested_at
28
28
  @pr.cancel!
29
29
  assert_predicate @pr, :canceled?
30
- PullRequest.request_merge!(@stack, @pr.number, @user)
30
+ MergeRequest.request_merge!(@stack, @pr.number, @user)
31
31
  assert_predicate @pr.reload, :pending?
32
32
  assert_not_equal original_merge_requested_at, @pr.merge_requested_at
33
33
  assert_in_delta Time.now.utc, @pr.merge_requested_at, 2
@@ -37,7 +37,7 @@ module Shipit
37
37
  original_merge_requested_at = @pr.merge_requested_at
38
38
  @pr.reject!('merge_conflict')
39
39
  assert_predicate @pr, :rejected?
40
- PullRequest.request_merge!(@stack, @pr.number, @user)
40
+ MergeRequest.request_merge!(@stack, @pr.number, @user)
41
41
  assert_predicate @pr.reload, :pending?
42
42
  assert_not_equal original_merge_requested_at, @pr.merge_requested_at
43
43
  assert_in_delta Time.now.utc, @pr.merge_requested_at, 2
@@ -48,29 +48,29 @@ module Shipit
48
48
  original_merge_requested_at = @pr.merge_requested_at
49
49
  @pr.revalidate!
50
50
  assert_predicate @pr, :revalidating?
51
- PullRequest.request_merge!(@stack, @pr.number, @user)
51
+ MergeRequest.request_merge!(@stack, @pr.number, @user)
52
52
  assert_predicate @pr.reload, :pending?
53
53
  assert_equal original_merge_requested_at, @pr.merge_requested_at
54
54
  end
55
55
 
56
56
  test ".extract_number can get a pull request number from different formats" do
57
- assert_equal 42, PullRequest.extract_number(@stack, '42')
58
- assert_equal 42, PullRequest.extract_number(@stack, '#42')
59
- assert_equal 42, PullRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
57
+ assert_equal 42, MergeRequest.extract_number(@stack, '42')
58
+ assert_equal 42, MergeRequest.extract_number(@stack, '#42')
59
+ assert_equal 42, MergeRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
60
60
 
61
- assert_nil PullRequest.extract_number(@stack, 'https://github.com/ACME/shipit-engine/pull/42')
61
+ assert_nil MergeRequest.extract_number(@stack, 'https://github.com/ACME/shipit-engine/pull/42')
62
62
 
63
- Shipit.github.expects(:domain).returns('github.acme.com').at_least_once
64
- assert_equal 42, PullRequest.extract_number(@stack, 'https://github.acme.com/Shopify/shipit-engine/pull/42')
65
- assert_nil PullRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
63
+ Shipit.github.class.any_instance.expects(:domain).returns('github.acme.com').at_least_once
64
+ assert_equal 42, MergeRequest.extract_number(@stack, 'https://github.acme.com/Shopify/shipit-engine/pull/42')
65
+ assert_nil MergeRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
66
66
  end
67
67
 
68
68
  test "refresh! pulls state from GitHub" do
69
- pull_request = shipit_pull_requests(:shipit_fetching)
69
+ merge_request = shipit_merge_requests(:shipit_fetching)
70
70
 
71
71
  head_sha = '64b3833d39def7ec65b57b42f496eb27ab4980b6'
72
72
  base_sha = 'ba7ab50e02286f7d6c60c1ef75258133dd9ea763'
73
- Shipit.github.api.expects(:pull_request).with(@stack.github_repo_name, pull_request.number).returns(
73
+ Shipit.github.api.expects(:pull_request).with(@stack.github_repo_name, merge_request.number).returns(
74
74
  stub(
75
75
  id: 4_857_578,
76
76
  url: 'https://api.github.com/repos/Shopify/shipit-engine/pulls/64',
@@ -125,15 +125,30 @@ module Shipit
125
125
  created_at: 1.day.ago,
126
126
  )])
127
127
 
128
- pull_request.refresh!
129
-
130
- assert_predicate pull_request, :mergeable?
131
- assert_predicate pull_request, :pending?
132
- assert_equal 'super-branch', pull_request.branch
133
-
134
- assert_not_nil pull_request.head
135
- assert_predicate pull_request.head, :detached?
136
- assert_predicate pull_request.head, :success?
128
+ Shipit.github.api.expects(:check_runs).with(@stack.github_repo_name, head_sha).returns(stub(
129
+ check_runs: [stub(
130
+ id: 123456,
131
+ name: 'check run',
132
+ conclusion: 'success',
133
+ output: stub(
134
+ title: 'a test checkrun',
135
+ ),
136
+ details_url: 'http://example.com',
137
+ html_url: 'http://example.com',
138
+ completed_at: Time.now,
139
+ started_at: 1.minute.ago,
140
+ )]
141
+ ))
142
+
143
+ merge_request.refresh!
144
+
145
+ assert_predicate merge_request, :mergeable?
146
+ assert_predicate merge_request, :pending?
147
+ assert_equal 'super-branch', merge_request.branch
148
+
149
+ assert_not_nil merge_request.head
150
+ assert_predicate merge_request.head, :detached?
151
+ assert_predicate merge_request.head, :success?
137
152
  end
138
153
 
139
154
  test "#reject! records the reason" do
@@ -216,11 +231,11 @@ module Shipit
216
231
  assert_equal 'requires_rebase', @pr.rejection_reason
217
232
  end
218
233
 
219
- test "#merge! raises a PullRequest::NotReady if the PR isn't mergeable yet" do
234
+ test "#merge! raises a MergeRequest::NotReady if the PR isn't mergeable yet" do
220
235
  @pr.update!(mergeable: nil)
221
236
 
222
237
  assert_predicate @pr, :not_mergeable_yet?
223
- assert_raises PullRequest::NotReady do
238
+ assert_raises MergeRequest::NotReady do
224
239
  @pr.merge!
225
240
  end
226
241
  @pr.reload
@@ -233,9 +248,9 @@ module Shipit
233
248
  end
234
249
  params = job.arguments.first
235
250
  assert_equal 'merge', params[:event]
236
- assert_json 'status', 'rejected', document: params[:payload]
237
- assert_json 'pull_request.rejection_reason', 'merge_conflict', document: params[:payload]
238
- assert_json 'pull_request.number', @pr.number, document: params[:payload]
251
+ assert_json_document params[:payload], 'status', 'rejected'
252
+ assert_json_document params[:payload], 'merge_request.rejection_reason', 'merge_conflict'
253
+ assert_json_document params[:payload], 'merge_request.number', @pr.number
239
254
  end
240
255
 
241
256
  test "#merge! doesnt delete the branch if there are open PRs against it" do
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Shipit
6
+ class PullRequestAssignmentTest < ActiveSupport::TestCase
7
+ setup do
8
+ @assignment = shipit_pull_request_assignments(:walrus_shopify_developers)
9
+ end
10
+
11
+ test "no duplicates are accepted" do
12
+ assignment = PullRequestAssignment.new(user: @assignment.user, pull_request: @assignment.pull_request)
13
+ refute assignment.valid?
14
+ end
15
+ end
16
+ end
@@ -9,13 +9,130 @@ module Shipit
9
9
  @check_run = shipit_check_runs(:second_pending_travis)
10
10
  end
11
11
 
12
+ test ".create_or_update_from_github! updates successfully" do
13
+ completed_at = Time.now
14
+ assert_difference -> { @commit.check_runs.count }, +1 do
15
+ @commit.check_runs.create_or_update_from_github!(
16
+ @stack.id,
17
+ github_check_run(conclusion: nil, completed_at: '2021-04-29T18:05:12Z')
18
+ )
19
+ end
20
+
21
+ assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
22
+ @commit.check_runs.create_or_update_from_github!(
23
+ @stack.id,
24
+ github_check_run(conclusion: 'success', completed_at: completed_at + 1.minute)
25
+ )
26
+ end
27
+
28
+ assert_equal 'success', @commit.check_runs.last.conclusion
29
+ end
30
+
31
+ test ".create_or_update_from_github! updates successfully using latest timestamp" do
32
+ completed_at = Time.now
33
+ assert_difference -> { @commit.check_runs.count }, +1 do
34
+ @commit.check_runs.create_or_update_from_github!(
35
+ @stack.id,
36
+ github_check_run(conclusion: 'success', completed_at: completed_at)
37
+ )
38
+ end
39
+
40
+ assert_enqueued_with(job: RefreshCheckRunsJob) do
41
+ @commit.check_runs.create_or_update_from_github!(
42
+ @stack.id,
43
+ github_check_run(conclusion: nil, completed_at: completed_at)
44
+ )
45
+ end
46
+
47
+ # RefreshCheckRunsJob would enqueue if the timestamp was older/equivalent
48
+ assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
49
+ @commit.check_runs.create_or_update_from_github!(
50
+ @stack.id,
51
+ github_check_run(
52
+ conclusion: 'action_required',
53
+ completed_at: completed_at,
54
+ started_at: completed_at + 1.minute,
55
+ ),
56
+ )
57
+ end
58
+
59
+ assert_equal 'action_required', @commit.check_runs.last.conclusion
60
+ end
61
+
12
62
  test ".create_or_update_from_github! is idempotent" do
63
+ completed_at = Time.now
64
+ assert_difference -> { @commit.check_runs.count }, +1 do
65
+ @commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run(completed_at: completed_at))
66
+ end
67
+
68
+ assert_no_difference -> { @commit.check_runs.count } do
69
+ assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
70
+ @commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run(completed_at: completed_at))
71
+ end
72
+ end
73
+ end
74
+
75
+ test ".create_or_update_from_github! enqueues refresh and updates record when new statuses have stale timestamps" do
76
+ completed_at = Time.now
13
77
  assert_difference -> { @commit.check_runs.count }, +1 do
14
- @commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run)
78
+ @commit.check_runs.create_or_update_from_github!(
79
+ @stack.id,
80
+ github_check_run(conclusion: 'success', completed_at: completed_at)
81
+ )
82
+ end
83
+
84
+ assert_equal 'success', @commit.check_runs.last.conclusion
85
+
86
+ updated_conclusion = 'action_required'
87
+ updated_check_run = github_check_run(conclusion: updated_conclusion, completed_at: completed_at - 1.minute)
88
+
89
+ assert_no_difference -> { @commit.check_runs.count } do
90
+ assert_enqueued_with(job: RefreshCheckRunsJob) do
91
+ @commit.check_runs.create_or_update_from_github!(@stack.id, updated_check_run)
92
+ end
93
+ end
94
+
95
+ assert_equal updated_conclusion, @commit.check_runs.last.conclusion
96
+
97
+ # If the refresh returns the same data, then the record should end up the same, but no refresh should be necessary
98
+ assert_no_difference -> { @commit.check_runs.count } do
99
+ assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
100
+ @commit.check_runs.create_or_update_from_github!(@stack.id, updated_check_run)
101
+ end
15
102
  end
16
103
 
104
+ assert_equal updated_conclusion, @commit.check_runs.last.conclusion
105
+ end
106
+
107
+ test ".create_or_update_from_github! does not enqueues refresh when old statuses has no timestamp" do
108
+ completed_at = Time.now
109
+ assert_difference -> { @commit.check_runs.count }, +1 do
110
+ @commit.check_runs.create_or_update_from_github!(
111
+ @stack.id,
112
+ github_check_run(conclusion: 'success', completed_at: completed_at)
113
+ )
114
+ end
115
+
116
+ @commit.check_runs.last.update!(github_updated_at: nil)
117
+
118
+ assert_no_difference -> { @commit.check_runs.count } do
119
+ assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
120
+ @commit.check_runs.create_or_update_from_github!(
121
+ @stack.id,
122
+ github_check_run(conclusion: nil, completed_at: completed_at - 1.minute)
123
+ )
124
+ end
125
+ end
126
+ end
127
+
128
+ test ".create_or_update_from_github! enqueues refresh when new statuses have no timestamps" do
17
129
  assert_no_difference -> { @commit.check_runs.count } do
18
- @commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run)
130
+ assert_enqueued_with(job: RefreshCheckRunsJob, args: [stack_id: @stack.id]) do
131
+ @commit.check_runs.create_or_update_from_github!(
132
+ @stack.id,
133
+ github_check_run(conclusion: nil, completed_at: nil, started_at: nil)
134
+ )
135
+ end
19
136
  end
20
137
  end
21
138
 
@@ -36,16 +153,18 @@ module Shipit
36
153
 
37
154
  private
38
155
 
39
- def github_check_run
40
- @github_check_run ||= OpenStruct.new(
156
+ def github_check_run(conclusion: 'success', completed_at: Time.now, started_at: Time.now - 1.minute)
157
+ OpenStruct.new(
41
158
  id: 424_242,
42
- conclusion: 'success',
159
+ conclusion: conclusion,
43
160
  output: OpenStruct.new(
44
161
  description: 'This is a description',
45
162
  ),
46
163
  name: 'Test Suite',
47
164
  html_url: 'http://example.com/run',
48
165
  details_url: 'http://example.com/details',
166
+ completed_at: completed_at,
167
+ started_at: started_at,
49
168
  )
50
169
  end
51
170
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Shipit
6
+ module ProvisioningHandler
7
+ class BaseTest < ActiveSupport::TestCase
8
+ test "provides a default #up handler" do
9
+ assert(
10
+ handler.respond_to?(:up),
11
+ "expected #{handler.class.name} to provide a default #up handler"
12
+ )
13
+ end
14
+
15
+ test "provides a default #down handler" do
16
+ assert(
17
+ handler.respond_to?(:down),
18
+ "expected #{handler.class.name} to provide a default #down handler"
19
+ )
20
+ end
21
+
22
+ test "provides a default #provision? handler" do
23
+ assert_equal true, handler.provision?
24
+ end
25
+
26
+ private
27
+
28
+ def handler
29
+ ProvisioningHandler::Base.new(mock("Stack"))
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Shipit
6
+ module ProvisioningHandler
7
+ class UnregisteredProvisioningHandlerTest < ActiveSupport::TestCase
8
+ test "#up stops transitions" do
9
+ stack = shipit_stacks(:shipit)
10
+ stack.update(provision_status: :deprovisioned)
11
+
12
+ assert_throws :halt do
13
+ UnregisteredProvisioningHandler.new(stack).up
14
+ end
15
+ end
16
+
17
+ test "#up locks the stack" do
18
+ stack = shipit_stacks(:shipit)
19
+ stack.update(provision_status: :deprovisioned)
20
+
21
+ assert_changes -> { stack.locked? }, from: false, to: true do
22
+ catch :halt do
23
+ UnregisteredProvisioningHandler.new(stack).up
24
+ end
25
+ end
26
+ end
27
+
28
+ test "#down stops transitions" do
29
+ stack = shipit_stacks(:shipit)
30
+ stack.update(provision_status: :deprovisioned)
31
+
32
+ assert_throws :halt do
33
+ UnregisteredProvisioningHandler.new(stack).down
34
+ end
35
+ end
36
+
37
+ test "#down prevents transitions" do
38
+ stack = shipit_stacks(:shipit)
39
+ stack.update(provision_status: :deprovisioned)
40
+
41
+ assert_changes -> { stack.locked? }, from: false, to: true do
42
+ catch :halt do
43
+ UnregisteredProvisioningHandler.new(stack).down
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end