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
@@ -106,6 +106,12 @@ module Shipit
106
106
  refute @spec.bundle_install.last.include?('--frozen')
107
107
  end
108
108
 
109
+ test "#provisioning_handler returns `provision.handler` if present" do
110
+ @spec.stubs(:load_config).returns('provision' => { 'handler_name' => 'ExpectedProvisioningHandler' })
111
+
112
+ assert_equal "ExpectedProvisioningHandler", @spec.provisioning_handler_name
113
+ end
114
+
109
115
  test '#deploy_steps returns `deploy.override` if present' do
110
116
  @spec.stubs(:load_config).returns('deploy' => { 'override' => %w(foo bar baz) })
111
117
  assert_equal %w(foo bar baz), @spec.deploy_steps
@@ -175,11 +181,31 @@ module Shipit
175
181
  end
176
182
  end
177
183
 
184
+ test '#retries_on_deploy returns `deploy.retries` if present' do
185
+ @spec.stubs(:load_config).returns('deploy' => { 'retries' => 5 })
186
+ assert_equal 5, @spec.retries_on_deploy
187
+ end
188
+
189
+ test '#retries_on_deploy returns a default value if `deploy.retries` is not present' do
190
+ @spec.stubs(:load_config).returns('deploy' => {})
191
+ assert_nil @spec.retries_on_deploy
192
+ end
193
+
178
194
  test '#rollback_steps returns `rollback.override` if present' do
179
195
  @spec.stubs(:load_config).returns('rollback' => { 'override' => %w(foo bar baz) })
180
196
  assert_equal %w(foo bar baz), @spec.rollback_steps
181
197
  end
182
198
 
199
+ test '#retries_on_rollback returns `rollback.retries` if present' do
200
+ @spec.stubs(:load_config).returns('rollback' => { 'retries' => 5 })
201
+ assert_equal 5, @spec.retries_on_rollback
202
+ end
203
+
204
+ test '#retries_on_rollback returns a default value if `rollback.retries` is not present' do
205
+ @spec.stubs(:load_config).returns('rollback' => {})
206
+ assert_nil @spec.retries_on_rollback
207
+ end
208
+
183
209
  test '#rollback_steps returns `cap $ENVIRONMENT deploy:rollback` if a `Capfile` is present' do
184
210
  @spec.expects(:bundler?).returns(true).at_least_once
185
211
  @spec.expects(:capistrano?).returns(true)
@@ -364,13 +390,20 @@ module Shipit
364
390
  },
365
391
  'dependencies' => { 'override' => [] },
366
392
  'plugins' => {},
393
+ 'provision' => {
394
+ 'handler_name' => nil,
395
+ },
367
396
  'deploy' => {
368
397
  'override' => nil,
369
398
  'variables' => [],
370
399
  'max_commits' => 8,
371
400
  'interval' => 0,
401
+ 'retries' => nil,
402
+ },
403
+ 'rollback' => {
404
+ 'override' => nil,
405
+ 'retries' => nil,
372
406
  },
373
- 'rollback' => { 'override' => nil },
374
407
  'fetch' => nil,
375
408
  'tasks' => {},
376
409
  }
@@ -559,40 +592,40 @@ module Shipit
559
592
  assert_equal %w(ci/circleci soc/compliance), @spec.required_statuses
560
593
  end
561
594
 
562
- test "pull_request_merge_method defaults to `nil`" do
595
+ test "merge_request_merge_method defaults to `nil`" do
563
596
  @spec.expects(:load_config).returns({})
564
- assert_nil @spec.pull_request_merge_method
597
+ assert_nil @spec.merge_request_merge_method
565
598
  end
566
599
 
567
- test "pull_request_merge_method returns `merge.method`" do
600
+ test "merge_request_merge_method returns `merge.method`" do
568
601
  @spec.expects(:load_config).returns(
569
602
  'merge' => {
570
603
  'method' => 'squash',
571
604
  },
572
605
  )
573
- assert_equal 'squash', @spec.pull_request_merge_method
606
+ assert_equal 'squash', @spec.merge_request_merge_method
574
607
  end
575
608
 
576
- test "pull_request_merge_method returns `nil` if `merge.method` is invalid" do
609
+ test "merge_request_merge_method returns `nil` if `merge.method` is invalid" do
577
610
  @spec.expects(:load_config).returns(
578
611
  'merge' => {
579
612
  'method' => 'squashing',
580
613
  },
581
614
  )
582
- assert_nil @spec.pull_request_merge_method
615
+ assert_nil @spec.merge_request_merge_method
583
616
  end
584
617
 
585
- test "pull_request_ignored_statuses defaults to the union of ci.hide and ci.allow_failures" do
618
+ test "merge_request_ignored_statuses defaults to the union of ci.hide and ci.allow_failures" do
586
619
  @spec.expects(:load_config).returns(
587
620
  'ci' => {
588
621
  'hide' => %w(ci/circleci ci/jenkins),
589
622
  'allow_failures' => %w(ci/circleci ci/travis),
590
623
  },
591
624
  )
592
- assert_equal %w(ci/circleci ci/jenkins ci/travis).sort, @spec.pull_request_ignored_statuses.sort
625
+ assert_equal %w(ci/circleci ci/jenkins ci/travis).sort, @spec.merge_request_ignored_statuses.sort
593
626
  end
594
627
 
595
- test "pull_request_ignored_statuses defaults to empty if `merge.require` is present" do
628
+ test "merge_request_ignored_statuses defaults to empty if `merge.require` is present" do
596
629
  @spec.expects(:load_config).returns(
597
630
  'merge' => {
598
631
  'require' => 'bar',
@@ -602,10 +635,10 @@ module Shipit
602
635
  'allow_failures' => %w(ci/circleci ci/travis),
603
636
  },
604
637
  )
605
- assert_equal [], @spec.pull_request_ignored_statuses
638
+ assert_equal [], @spec.merge_request_ignored_statuses
606
639
  end
607
640
 
608
- test "pull_request_ignored_statuses returns `merge.ignore` if present" do
641
+ test "merge_request_ignored_statuses returns `merge.ignore` if present" do
609
642
  @spec.expects(:load_config).returns(
610
643
  'merge' => {
611
644
  'ignore' => 'bar',
@@ -615,19 +648,19 @@ module Shipit
615
648
  'allow_failures' => %w(ci/circleci ci/travis),
616
649
  },
617
650
  )
618
- assert_equal ['bar'], @spec.pull_request_ignored_statuses
651
+ assert_equal ['bar'], @spec.merge_request_ignored_statuses
619
652
  end
620
653
 
621
- test "pull_request_required_statuses defaults to ci.require" do
654
+ test "merge_request_required_statuses defaults to ci.require" do
622
655
  @spec.expects(:load_config).returns(
623
656
  'ci' => {
624
657
  'require' => %w(ci/circleci ci/jenkins),
625
658
  },
626
659
  )
627
- assert_equal %w(ci/circleci ci/jenkins), @spec.pull_request_required_statuses
660
+ assert_equal %w(ci/circleci ci/jenkins), @spec.merge_request_required_statuses
628
661
  end
629
662
 
630
- test "pull_request_required_statuses defaults to empty if `merge.ignore` is present" do
663
+ test "merge_request_required_statuses defaults to empty if `merge.ignore` is present" do
631
664
  @spec.expects(:load_config).returns(
632
665
  'merge' => {
633
666
  'ignore' => 'bar',
@@ -636,10 +669,10 @@ module Shipit
636
669
  'require' => %w(ci/circleci ci/jenkins),
637
670
  },
638
671
  )
639
- assert_equal [], @spec.pull_request_required_statuses
672
+ assert_equal [], @spec.merge_request_required_statuses
640
673
  end
641
674
 
642
- test "pull_request_required_statuses returns `merge.require` if present" do
675
+ test "merge_request_required_statuses returns `merge.require` if present" do
643
676
  @spec.expects(:load_config).returns(
644
677
  'merge' => {
645
678
  'require' => 'bar',
@@ -649,21 +682,21 @@ module Shipit
649
682
  'allow_failures' => %w(ci/circleci ci/travis),
650
683
  },
651
684
  )
652
- assert_equal ['bar'], @spec.pull_request_required_statuses
685
+ assert_equal ['bar'], @spec.merge_request_required_statuses
653
686
  end
654
687
 
655
- test "revalidate_pull_requests_after defaults to `nil" do
688
+ test "revalidate_merge_requests_after defaults to `nil" do
656
689
  @spec.expects(:load_config).returns({})
657
- assert_nil @spec.revalidate_pull_requests_after
690
+ assert_nil @spec.revalidate_merge_requests_after
658
691
  end
659
692
 
660
- test "revalidate_pull_requests_after defaults to `nil` if `merge.timeout` cannot be parsed" do
693
+ test "revalidate_merge_requests_after defaults to `nil` if `merge.timeout` cannot be parsed" do
661
694
  @spec.expects(:load_config).returns(
662
695
  'merge' => {
663
696
  'revalidate_after' => 'ALSKhfjsdkf',
664
697
  },
665
698
  )
666
- assert_nil @spec.revalidate_pull_requests_after
699
+ assert_nil @spec.revalidate_merge_requests_after
667
700
  end
668
701
 
669
702
  test "revalidate_after returns `merge.revalidate_after` if present" do
@@ -672,7 +705,7 @@ module Shipit
672
705
  'revalidate_after' => '5m30s',
673
706
  },
674
707
  )
675
- assert_equal 330, @spec.revalidate_pull_requests_after.to_i
708
+ assert_equal 330, @spec.revalidate_merge_requests_after.to_i
676
709
  end
677
710
 
678
711
  test "#file is impacted by `machine.directory`" do
@@ -795,6 +828,13 @@ module Shipit
795
828
  @spec.stubs(:lerna?).returns(true)
796
829
  @spec.stubs(:lerna_config).returns('lerna' => '2.0.0', 'version' => 'independent')
797
830
  assert_equal 'assert-lerna-independent-version-tags', @spec.deploy_steps[0]
831
+ assert_equal 'publish-lerna-independent-packages-legacy', @spec.deploy_steps[1]
832
+ end
833
+
834
+ test '#publish_lerna_packages checks if independent version tags exist, checks if a newer version of lerna is used, and then invokes lerna deploy script' do
835
+ @spec.stubs(:lerna?).returns(true)
836
+ @spec.stubs(:lerna_config).returns('lerna' => '3.0.0', 'version' => 'independent')
837
+ assert_equal 'assert-lerna-independent-version-tags', @spec.deploy_steps[0]
798
838
  assert_equal 'publish-lerna-independent-packages', @spec.deploy_steps[1]
799
839
  end
800
840
 
@@ -5,6 +5,7 @@ module Shipit
5
5
  class DeploysTest < ActiveSupport::TestCase
6
6
  def setup
7
7
  @deploy = shipit_deploys(:shipit)
8
+ @deploy.write("dummy output")
8
9
  @deploy.pid = 42
9
10
  @stack = shipit_stacks(:shipit)
10
11
  @user = shipit_users(:walrus)
@@ -60,6 +61,146 @@ module Shipit
60
61
  assert_equal [], @deploy.commits
61
62
  end
62
63
 
64
+ test "deploys retry up to limit upon timeout when configured" do
65
+ runnable_deploy = shipit_deploys(:shipit_pending)
66
+ deploy_stack = runnable_deploy.stack
67
+
68
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock).twice
69
+ .raises(Shipit::Command::TimedOut, 'Deploy timed out')
70
+ .then.raises(Shipit::Command::Error, "Second command error failure")
71
+
72
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
73
+ runnable_deploy.enqueue
74
+ end
75
+ assert_performed_jobs 2
76
+
77
+ runnable_deploy.reload
78
+ assert_equal 'timedout', runnable_deploy.status
79
+
80
+ retried_deploy = deploy_stack.deploys.last
81
+ assert_not_equal runnable_deploy.id, retried_deploy.id
82
+ assert_equal runnable_deploy.since_commit, retried_deploy.since_commit
83
+ assert_equal runnable_deploy.until_commit, retried_deploy.until_commit
84
+ assert_equal 'failed', retried_deploy.status
85
+ assert_equal 1, retried_deploy.retry_attempt
86
+ end
87
+
88
+ test "deploys retry up to limit upon failure when configured" do
89
+ runnable_deploy = shipit_deploys(:shipit_pending)
90
+ deploy_stack = runnable_deploy.stack
91
+
92
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock).twice
93
+ .raises(Shipit::Command::Error, 'Deploy failed')
94
+ .then.raises(Shipit::Command::Error, "Second deploy failed")
95
+
96
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
97
+ runnable_deploy.enqueue
98
+ end
99
+ assert_performed_jobs 2
100
+
101
+ runnable_deploy.reload
102
+ assert_equal 'failed', runnable_deploy.status
103
+
104
+ retried_deploy = deploy_stack.deploys.last
105
+ assert_not_equal runnable_deploy.id, retried_deploy.id
106
+ assert_equal runnable_deploy.since_commit, retried_deploy.since_commit
107
+ assert_equal runnable_deploy.until_commit, retried_deploy.until_commit
108
+ assert_equal 'failed', retried_deploy.status
109
+ assert_equal 1, retried_deploy.retry_attempt
110
+ end
111
+
112
+ test "deploys retry up to limit upon error when configured" do
113
+ runnable_deploy = shipit_deploys(:shipit_pending)
114
+ deploy_stack = runnable_deploy.stack
115
+
116
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock).twice
117
+ .raises(StandardError, 'Deploy failed')
118
+ .then.raises(StandardError, "Second deploy failed")
119
+
120
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
121
+ runnable_deploy.enqueue
122
+ end
123
+ assert_performed_jobs 2
124
+
125
+ runnable_deploy.reload
126
+ assert_equal 'error', runnable_deploy.status
127
+
128
+ retried_deploy = deploy_stack.deploys.last
129
+ assert_not_equal runnable_deploy.id, retried_deploy.id
130
+ assert_equal runnable_deploy.since_commit, retried_deploy.since_commit
131
+ assert_equal runnable_deploy.until_commit, retried_deploy.until_commit
132
+ assert_equal 'error', retried_deploy.status
133
+ assert_equal 1, retried_deploy.retry_attempt
134
+ end
135
+
136
+ test "deploys do not retry upon timeout when not configured" do
137
+ runnable_deploy = shipit_deploys(:shipit_pending)
138
+ runnable_deploy.update!(retry_attempt: 0, max_retries: 0)
139
+
140
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock)
141
+ .raises(Shipit::Command::TimedOut, 'Deploy timed out')
142
+
143
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
144
+ runnable_deploy.enqueue
145
+ end
146
+ assert_performed_jobs 1
147
+
148
+ runnable_deploy.reload
149
+
150
+ assert_equal 'timedout', runnable_deploy.status
151
+ end
152
+
153
+ test "rollbacks retry on timeouts if configured" do
154
+ deploy = shipit_deploys(:shipit)
155
+ deploy_stack = deploy.stack
156
+
157
+ DeploySpec.any_instance.expects(:retries_on_rollback).returns(1)
158
+
159
+ Shipit::Command.any_instance.expects(:run).twice
160
+ .raises(Shipit::Command::TimedOut, 'Rollback timed out')
161
+ .then.raises(Shipit::Command::Error, "Second command error failure")
162
+
163
+ first_rollback = nil
164
+
165
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
166
+ first_rollback = deploy.trigger_rollback(@user, force: true)
167
+ end
168
+ assert_performed_jobs 2
169
+
170
+ first_rollback.reload
171
+
172
+ assert_equal 'timedout', first_rollback.status
173
+ retried_rollback = deploy_stack.deploys_and_rollbacks.last
174
+
175
+ assert_not_equal first_rollback.id, retried_rollback.id
176
+ assert_equal first_rollback.since_commit, retried_rollback.since_commit
177
+ assert_equal first_rollback.until_commit, retried_rollback.until_commit
178
+ assert_equal 'failed', retried_rollback.status
179
+ assert_equal 1, retried_rollback.max_retries
180
+ end
181
+
182
+ test "rollbacks do not retry if not configured" do
183
+ deploy_stack = @deploy.stack
184
+
185
+ DeploySpec.any_instance.expects(:retries_on_rollback).returns(0)
186
+
187
+ Shipit::Command.any_instance.expects(:run).once
188
+ .raises(Shipit::Command::TimedOut, 'Rollback timed out')
189
+ .then.raises(Shipit::Command::Error, "Second command error failure")
190
+
191
+ first_rollback = nil
192
+
193
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
194
+ first_rollback = @deploy.trigger_rollback(@user, force: true)
195
+ end
196
+ assert_performed_jobs 1
197
+
198
+ first_rollback.reload
199
+
200
+ assert_equal 'timedout', first_rollback.status
201
+ assert_equal first_rollback, deploy_stack.deploys_and_rollbacks.last
202
+ end
203
+
63
204
  test "additions and deletions are denormalized on before create" do
64
205
  stack = shipit_stacks(:shipit)
65
206
  first = shipit_commits(:first)
@@ -200,7 +341,7 @@ module Shipit
200
341
  since_commit: shipit.commits.first,
201
342
  until_commit: shipit.commits.last,
202
343
  )
203
- deploy.stubs(:pull_request_head_for_commit).returns(nil)
344
+ deploy.stubs(:merge_request_head_for_commit).returns(nil)
204
345
 
205
346
  expect_event(deploy)
206
347
  deploy.save!
@@ -263,9 +404,9 @@ module Shipit
263
404
  assert_in_delta @deploy.ended_at, @stack.last_deployed_at, 2
264
405
  end
265
406
 
266
- test "transitioning to success schedule a MergePullRequests job" do
407
+ test "transitioning to success schedule a MergeMergeRequests job" do
267
408
  @deploy = shipit_deploys(:shipit_running)
268
- assert_enqueued_with(job: MergePullRequestsJob, args: [@deploy.stack]) do
409
+ assert_enqueued_with(job: ProcessMergeRequestsJob, args: [@deploy.stack]) do
269
410
  @deploy.complete!
270
411
  end
271
412
  end
@@ -393,7 +534,7 @@ module Shipit
393
534
  # Check that the next item in the series is 1 greater than the last.
394
535
  def assert_generated_record_ids_are_sequential(record_id_series)
395
536
  record_id_series[0..-2].each_with_index do |id_element, index|
396
- assert_equal id_element + 1, record_id_series[index + 1]
537
+ assert_equal(id_element + 1, record_id_series[index + 1])
397
538
  end
398
539
  end
399
540
 
@@ -661,6 +802,12 @@ module Shipit
661
802
  assert_equal @user, @stack.lock_author
662
803
  end
663
804
 
805
+ test "#trigger_rollback does not lock the stack if not requested" do
806
+ refute @stack.locked?
807
+ @deploy.trigger_rollback(@user, lock: false)
808
+ refute @stack.reload.locked?
809
+ end
810
+
664
811
  test "#trigger_rollback marks the rollback as `ignored_safeties` if the force option was used" do
665
812
  rollback = @deploy.trigger_rollback(@user, force: true)
666
813
  assert_predicate rollback, :ignored_safeties?
@@ -699,20 +846,13 @@ module Shipit
699
846
  assert_predicate @deploy, :error?
700
847
  end
701
848
 
702
- test "destroy deletes the related output chunks" do
703
- assert_difference -> { @deploy.chunks.count }, -@deploy.chunks.count do
704
- @deploy.destroy
705
- end
706
- end
707
-
708
- test "#chunk_output joins all chunk test if logs not rolled up" do
709
- assert_equal @deploy.chunks.count, @deploy.chunks.count
710
- assert_equal @deploy.chunks.pluck(:text).join, @deploy.chunk_output
849
+ test "#chunk_output fetches from Redis if logs not rolled up" do
850
+ assert_equal Shipit.redis.get(@deploy.send(:output_key)), @deploy.chunk_output
711
851
  refute @deploy.rolled_up
712
852
  end
713
853
 
714
854
  test "#chunk_output returns logs from records if rolled up" do
715
- expected_output = @deploy.chunks.pluck(:text).join
855
+ expected_output = Shipit.redis.get(@deploy.send(:output_key))
716
856
  @deploy.rollup_chunks
717
857
 
718
858
  assert_no_queries do
@@ -833,6 +973,18 @@ module Shipit
833
973
  end
834
974
  end
835
975
 
976
+ test "succeeding a deploy sets the release status as pending and does not schedule job if the status delay is negative (-1)" do
977
+ @deploy = shipit_deploys(:canaries_running)
978
+ @deploy.stack.expects(:release_status_delay).at_least_once.returns(Duration.parse(-1))
979
+
980
+ assert_difference -> { ReleaseStatus.count }, +1 do
981
+ assert_not_equal 'success', @deploy.last_release_status.state
982
+ @deploy.report_complete!
983
+ assert_equal 'validating', @deploy.status
984
+ assert_equal 'pending', @deploy.last_release_status.state
985
+ end
986
+ end
987
+
836
988
  test "triggering a rollback via abort! sets the release status as failure" do
837
989
  @deploy = shipit_deploys(:canaries_running)
838
990
  @deploy.ping
@@ -878,6 +1030,28 @@ module Shipit
878
1030
  end
879
1031
  end
880
1032
 
1033
+ test "manually triggered rollbacks sets rollbacked deploys as faulty and not the rollback task" do
1034
+ @deploy = shipit_deploys(:canaries_validating)
1035
+ @middle_deploy = shipit_deploys(:canaries_faulty)
1036
+ @rollback_to_deploy = shipit_deploys(:canaries_success)
1037
+
1038
+ @rollback_task = @rollback_to_deploy.trigger_rollback(force: true)
1039
+
1040
+ @rollback_task.run!
1041
+ @rollback_task.complete!
1042
+ @rollback_task.reload
1043
+ @deploy.reload
1044
+ @middle_deploy.reload
1045
+
1046
+ assert_equal 'faulty', @deploy.status
1047
+ assert_equal 'failure', @deploy.last_release_status.state
1048
+
1049
+ assert_equal 'faulty', @middle_deploy.status
1050
+ assert_equal 'failure', @middle_deploy.last_release_status.state
1051
+
1052
+ assert_equal 'success', @rollback_task.status
1053
+ end
1054
+
881
1055
  test "succeeding a deploy creates CommitDeploymentStatuses" do
882
1056
  @deploy = shipit_deploys(:shipit_running)
883
1057
  refute_empty @deploy.commit_deployments