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
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Shipit
6
+ class StackProvisioningHandlerTest < ActiveSupport::TestCase
7
+ teardown do
8
+ Shipit::ProvisioningHandler.reset_registry!
9
+ end
10
+
11
+ test "uses the no-op handler as default when no default handler is registered" do
12
+ assert_equal Shipit::ProvisioningHandler::Base, Shipit::ProvisioningHandler.default
13
+ end
14
+
15
+ test "allows registration of a default handler" do
16
+ mock_handler = mock("Mock Provisioning Handler")
17
+
18
+ Shipit::ProvisioningHandler.default = mock_handler
19
+
20
+ assert_equal mock_handler, Shipit::ProvisioningHandler.default
21
+ end
22
+
23
+ test "UnregisteredProvisioningHandler is returned when an attempt to fetch an unregistered handler is made" do
24
+ unregistered_handler = mock("Mock Provisioning Handler")
25
+
26
+ assert_equal(
27
+ Shipit::ProvisioningHandler::UnregisteredProvisioningHandler,
28
+ Shipit::ProvisioningHandler.fetch(unregistered_handler)
29
+ )
30
+ end
31
+
32
+ test "registers handlers so they become fetchable" do
33
+ mock_handler = mock("Mock Provisioning Handler")
34
+
35
+ Shipit::ProvisioningHandler.register(mock_handler)
36
+
37
+ assert_equal mock_handler, Shipit::ProvisioningHandler.fetch(mock_handler.to_s)
38
+ end
39
+
40
+ test "handlers are called during provisioning" do
41
+ stack = shipit_stacks(:review_stack)
42
+ stack.update(
43
+ provision_status: :deprovisioned
44
+ )
45
+ handler = Shipit::ProvisioningHandler.default
46
+
47
+ handler.any_instance.expects(:up)
48
+
49
+ assert stack.provision!, "stack should have provisioned."
50
+ end
51
+
52
+ test "handlers are called during deprovisioning" do
53
+ stack = shipit_stacks(:review_stack)
54
+ stack.update(
55
+ provision_status: :provisioned
56
+ )
57
+ handler = Shipit::ProvisioningHandler.default
58
+
59
+ handler.any_instance.expects(:down)
60
+
61
+ assert stack.deprovision!, "stack should have deprovisioned."
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ class PullRequestTest < ActiveSupport::TestCase
7
+ test "github_pull_request= parses into a a Shipit::PullRequest" do
8
+ github_pull_request = resource(
9
+ {
10
+ url: "https://api.github.com/repos/Codertocat/Hello-World/pulls/2",
11
+ id: 279147437,
12
+ number: 2,
13
+ state: "open",
14
+ additions: 100,
15
+ deletions: 101,
16
+ title: "Update the README with new information.",
17
+ head: {
18
+ sha: "ec26c3e57ca3a959ca5aad62de7213c562f8c821",
19
+ },
20
+ user: {
21
+ login: "Codertocat",
22
+ },
23
+ assignees: [
24
+ {
25
+ login: "bob",
26
+ },
27
+ ],
28
+ labels: [
29
+ {
30
+ name: "deploy",
31
+ },
32
+ ],
33
+ }
34
+ )
35
+ stack = shipit_stacks(:review_stack)
36
+ pull_request = stack.pull_request
37
+
38
+ stack.pull_request.github_pull_request = github_pull_request
39
+
40
+ assert_equal 279147437, pull_request.github_id
41
+ assert_equal 2, pull_request.number
42
+ assert_equal "https://api.github.com/repos/Codertocat/Hello-World/pulls/2", pull_request.api_url
43
+ assert_equal "Update the README with new information.", pull_request.title
44
+ assert_equal "open", pull_request.state
45
+ assert_equal 100, pull_request.additions
46
+ assert_equal 101, pull_request.deletions
47
+ assert_equal shipit_users(:codertocat), pull_request.user
48
+ assert_equal [shipit_users(:bob)], pull_request.assignees
49
+ assert_equal ["deploy"], pull_request.labels
50
+ end
51
+ end
52
+ end
@@ -20,7 +20,7 @@ module Shipit
20
20
 
21
21
  test "owner and name are case insensitive" do
22
22
  assert_no_difference -> { Repository.count } do
23
- error = assert_raises ActiveRecord::RecordInvalid do
23
+ error = assert_raises(ActiveRecord::RecordInvalid) do
24
24
  Repository.create!(
25
25
  owner: @repository.owner.upcase,
26
26
  name: @repository.name.upcase,
@@ -63,6 +63,10 @@ module Shipit
63
63
  assert_equal "https://github.com/#{@repository.owner}/#{@repository.name}.git", @repository.git_url
64
64
  end
65
65
 
66
+ test "review_stacks_enabled defaults to false" do
67
+ assert_equal false, Repository.new.review_stacks_enabled
68
+ end
69
+
66
70
  test "from_github_repo_name" do
67
71
  owner = "repository-owner"
68
72
  name = "repository-name"
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Shipit
6
+ class ReviewStackProvisionStatusTest < ActiveSupport::TestCase
7
+ test "stacks default to deprovisioned state" do
8
+ stack = Shipit::ReviewStack.new
9
+
10
+ assert_equal 'deprovisioned', stack.provision_status
11
+ end
12
+
13
+ test "non-review stacks don't transition" do
14
+ stack = Shipit::ReviewStack.new
15
+ stack.provision
16
+
17
+ assert_equal 'deprovisioned', stack.provision_status
18
+ end
19
+
20
+ test "review stacks that are deprovisioned can be provisioned" do
21
+ stack = review_stack(provision_status: :deprovisioned)
22
+
23
+ stack.provision
24
+
25
+ assert_equal 'provisioning', stack.provision_status
26
+ end
27
+
28
+ test "review stacks that are provisioning can succeed" do
29
+ stack = review_stack(provision_status: :provisioning)
30
+
31
+ stack.provision_success
32
+
33
+ assert_equal 'provisioned', stack.provision_status
34
+ end
35
+
36
+ test "review stacks that are provisioning can fail" do
37
+ stack = review_stack(provision_status: :provisioning)
38
+
39
+ stack.provision_failure
40
+
41
+ assert_equal 'deprovisioned', stack.provision_status
42
+ end
43
+
44
+ test "review stacks are provisioned can be deprovisioned" do
45
+ stack = review_stack(provision_status: :provisioned)
46
+
47
+ stack.deprovision
48
+
49
+ assert 'deprovisioning', stack.provision_status
50
+ end
51
+
52
+ test "review stacks that are deprovisioning can succeed" do
53
+ stack = review_stack(provision_status: :deprovisioning)
54
+
55
+ stack.deprovision_success
56
+
57
+ assert_equal 'deprovisioned', stack.provision_status
58
+ end
59
+
60
+ test "review stacks that are deprovisioning can fail" do
61
+ stack = review_stack(provision_status: :deprovisioning)
62
+
63
+ stack.deprovision_failure
64
+
65
+ assert_equal 'provisioned', stack.provision_status
66
+ end
67
+
68
+ def review_stack(provision_status: :deprovisioned)
69
+ stack = shipit_stacks(:review_stack)
70
+ stack.provision_status = provision_status
71
+
72
+ stack.save!
73
+
74
+ stack
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ class ReviewStackProvisioningQueueTest < ActiveSupport::TestCase
7
+ test ".add en-queues a stack for provisioning" do
8
+ review_stack = shipit_stacks(:review_stack)
9
+ review_stack.update(lock_reason: nil)
10
+
11
+ assert_changes -> { review_stack.awaiting_provision }, from: false, to: true do
12
+ queue.add(review_stack)
13
+ end
14
+ end
15
+
16
+ test ".work provisions resource stacks when they are provision-able" do
17
+ review_stack = provisionable_review_stack
18
+ setup_provisioning_handler(for_stack: review_stack, provision: true)
19
+ queue.add(review_stack)
20
+
21
+ assert_changes -> { review_stack.reload.provision_status }, from: "deprovisioned", to: "provisioning" do
22
+ queue.work
23
+ end
24
+ end
25
+
26
+ test ".work does not provision resource stacks when they are not provisionable" do
27
+ review_stack = provisionable_review_stack
28
+ setup_provisioning_handler(for_stack: review_stack, provision: false)
29
+ queue.add(review_stack)
30
+
31
+ assert_equal "deprovisioned", review_stack.provision_status
32
+ assert_no_changes -> { review_stack.reload.provision_status } do
33
+ queue.work
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def setup_provisioning_handler(for_stack:, provision:)
40
+ provisioning_handler_instance = mock("ProvisioningHandler instance")
41
+ provisioning_handler_instance.expects(:provision?).returns(provision)
42
+ provisioning_handler_instance.expects(:up).returns(true) if !!provision
43
+ provisioning_handler_class = mock("ProvisioningHandler class")
44
+ provisioning_handler_class.expects(:new).at_least_once.with(for_stack).returns(provisioning_handler_instance)
45
+ Shipit::ProvisioningHandler.expects(:fetch).at_least_once.returns(provisioning_handler_class)
46
+
47
+ provisioning_handler_instance
48
+ end
49
+
50
+ def provisionable_review_stack
51
+ review_stack = shipit_stacks(:review_stack)
52
+ review_stack.update(
53
+ provision_status: :deprovisioned,
54
+ )
55
+
56
+ review_stack
57
+ end
58
+
59
+ def queue
60
+ ReviewStackProvisioningQueue
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ class ReviewStackTest < ActiveSupport::TestCase
7
+ setup do
8
+ @review_stack = shipit_stacks(:review_stack)
9
+ end
10
+
11
+ test "clearing stale caches" do
12
+ stale_stack = shipit_stacks(:archived_6hours_ago)
13
+ FileUtils.mkdir_p(stale_stack.base_path)
14
+ path = File.join(stale_stack.base_path, 'foo')
15
+ File.write(path, 'bar')
16
+
17
+ not_stale_stack = shipit_stacks(:archived_30minutes_ago)
18
+ FileUtils.mkdir_p(not_stale_stack.base_path)
19
+ path = File.join(not_stale_stack.base_path, 'foo')
20
+ File.write(path, 'bar')
21
+
22
+ ReviewStack.clear_stale_caches
23
+
24
+ refute File.exist?(stale_stack.base_path)
25
+ assert File.exist?(not_stale_stack.base_path)
26
+ end
27
+
28
+ test "creating a review stack emits a hook" do
29
+ new_review_stack = @review_stack.dup
30
+ new_review_stack.environment = "new-review-stack-environment"
31
+
32
+ expect_hook(:review_stack, new_review_stack, action: :added, review_stack: new_review_stack) do
33
+ new_review_stack.save!
34
+ end
35
+ end
36
+
37
+ test "updating a review stack emit a hook" do
38
+ expect_hook(:review_stack, @review_stack, action: :updated, review_stack: @review_stack) do
39
+ @review_stack.update(environment: 'foo')
40
+ end
41
+ end
42
+
43
+ test "updating a review stack doesn't emit a hook if only `updated_at` is changed" do
44
+ # force a save to make sure `cached_deploy_spec` serialization is consistent with how Active Record would
45
+ # serialize it.
46
+ @review_stack.update(updated_at: 2.days.ago)
47
+
48
+ expect_no_hook(:review_stack) do
49
+ @review_stack.update(updated_at: Time.zone.now)
50
+ end
51
+ end
52
+
53
+ test "deleteing a review stack emits a hook" do
54
+ expect_hook(:review_stack, @review_stack, action: :removed, review_stack: @review_stack) do
55
+ @review_stack.destroy!
56
+ end
57
+ end
58
+
59
+ test "#env includes the stack's pull request labels" do
60
+ stack = shipit_stacks(:review_stack)
61
+ stack.pull_request.labels = ["wip", "bug"]
62
+
63
+ assert_equal stack.env["WIP"], "true"
64
+ assert_equal stack.env["BUG"], "true"
65
+ end
66
+
67
+ test "#unarchive! triggers a GithubSync job" do
68
+ stack = shipit_stacks(:review_stack)
69
+ assert_no_enqueued_jobs(only: GithubSyncJob) do
70
+ stack.archive!(shipit_users(:codertocat))
71
+ end
72
+
73
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id]) do
74
+ stack.unarchive!
75
+ end
76
+ end
77
+
78
+ test "#trigger_continuous_delivery does not enqueue deployment ref update job" do
79
+ Shipit.stubs(:update_latest_deployed_ref).returns(true)
80
+ @stack = shipit_stacks(:review_stack)
81
+ assert_no_enqueued_jobs(only: Shipit::UpdateGithubLastDeployedRefJob) do
82
+ task = @stack.trigger_continuous_delivery
83
+ task.update!(status: "running")
84
+ end
85
+
86
+ assert_no_enqueued_jobs(only: Shipit::UpdateGithubLastDeployedRefJob) do
87
+ @stack.last_active_task.complete!
88
+ end
89
+ end
90
+ end
91
+ end
@@ -10,10 +10,20 @@ module Shipit
10
10
  GithubHook.any_instance.stubs(:teardown!)
11
11
  end
12
12
 
13
- test "branch defaults to master" do
13
+ test "branch defaults to default branch name" do
14
14
  @stack.branch = ""
15
+ Shipit.github.api.expects(:repo).with("shopify/shipit-engine").returns(
16
+ Struct.new(:default_branch).new('something')
17
+ )
15
18
  assert @stack.save
16
- assert_equal 'master', @stack.branch
19
+ assert_equal 'something', @stack.branch
20
+ end
21
+
22
+ test "branch is blank when default cannot be determined" do
23
+ @stack.branch = ""
24
+ Shipit.github.api.expects(:repo).raises(Octokit::NotFound)
25
+ assert_not @stack.save
26
+ assert_nil @stack.branch
17
27
  end
18
28
 
19
29
  test "environment defaults to production" do
@@ -201,7 +211,7 @@ module Shipit
201
211
 
202
212
  test "#create queues a GithubSyncJob" do
203
213
  assert_enqueued_with(job: GithubSyncJob) do
204
- Stack.create!(repository: shipit_repositories(:rails))
214
+ Stack.create!(repository: shipit_repositories(:rails), branch: 'main')
205
215
  end
206
216
  end
207
217
 
@@ -252,6 +262,7 @@ module Shipit
252
262
  stack = Stack.create!(
253
263
  repository: Repository.new(owner: "foo", name: "bar"),
254
264
  environment: 'production',
265
+ branch: 'main',
255
266
  )
256
267
  commit = shipit_commits(:first)
257
268
  stack.commits << commit
@@ -267,8 +278,9 @@ module Shipit
267
278
  end
268
279
  end
269
280
 
270
- test "#deployable? returns true if the stack is not locked and is not deploying" do
281
+ test "#deployable? returns true if the stack is not locked, not awaiting provision, and is not deploying" do
271
282
  @stack.deploys.destroy_all
283
+ @stack.update!(lock_reason: nil, awaiting_provision: false)
272
284
  assert_predicate @stack, :deployable?
273
285
  end
274
286
 
@@ -282,6 +294,11 @@ module Shipit
282
294
  refute_predicate @stack, :deployable?
283
295
  end
284
296
 
297
+ test "#deployable? returns false if the stack is awaiting provisioning" do
298
+ @stack.update!(lock_reason: nil, awaiting_provision: true)
299
+ refute_predicate @stack, :deployable?
300
+ end
301
+
285
302
  test "#allows_merges? returns true if the stack is not locked and the branch is green" do
286
303
  assert_predicate @stack, :allows_merges?
287
304
  end
@@ -345,24 +362,35 @@ module Shipit
345
362
  end
346
363
  end
347
364
 
348
- test "unlocking the stack triggers a MergePullRequests job" do
349
- assert_no_enqueued_jobs(only: MergePullRequestsJob) do
365
+ test "unlocking the stack triggers a MergeMergeRequests job" do
366
+ assert_no_enqueued_jobs(only: ProcessMergeRequestsJob) do
350
367
  @stack.update(lock_reason: "Just for fun", lock_author: shipit_users(:walrus))
351
368
  end
352
369
 
353
- assert_enqueued_with(job: MergePullRequestsJob, args: [@stack]) do
370
+ assert_enqueued_with(job: ProcessMergeRequestsJob, args: [@stack]) do
354
371
  @stack.update(lock_reason: nil)
355
372
  end
356
373
  end
357
374
 
358
375
  test "the git cache lock prevent concurrent access to the git cache" do
359
- @stack.acquire_git_cache_lock do
376
+ second_stack = Shipit::Stack.find(@stack.id)
377
+ second_stack.acquire_git_cache_lock do
360
378
  assert_raises Flock::TimeoutError do
361
379
  @stack.acquire_git_cache_lock(timeout: 0.1) {}
362
380
  end
363
381
  end
364
382
  end
365
383
 
384
+ test "the git cache lock is reentrant if called on the same Stack instance" do
385
+ called = false
386
+ @stack.acquire_git_cache_lock(timeout: 0.01) do
387
+ @stack.acquire_git_cache_lock(timeout: 0.01) do
388
+ called = true
389
+ end
390
+ end
391
+ assert called
392
+ end
393
+
366
394
  test "the git cache lock is scoped to the stack" do
367
395
  called = false
368
396
  shipit_stacks(:cyclimse).acquire_git_cache_lock do
@@ -920,6 +948,22 @@ module Shipit
920
948
  )
921
949
  end
922
950
 
951
+ test "#unarchive! triggers a GithubSync job" do
952
+ assert_no_enqueued_jobs(only: GithubSyncJob) do
953
+ @stack.archive!(shipit_users(:codertocat))
954
+ end
955
+
956
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
957
+ @stack.unarchive!
958
+ end
959
+ end
960
+
961
+ test "#update that changes the branch name triggers a GithubSync job" do
962
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
963
+ @stack.update!(branch: 'test')
964
+ end
965
+ end
966
+
923
967
  private
924
968
 
925
969
  def generate_revert_commit(stack:, reverted_commit:, author: reverted_commit.author)