shipit-engine 0.32.0 → 0.33.0

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/magic-solid.svg +1 -0
  3. data/app/assets/javascripts/shipit/repositories_search.js.coffee +60 -0
  4. data/app/assets/javascripts/shipit/{search.js.coffee → stack_search.js.coffee} +0 -0
  5. data/app/assets/stylesheets/_pages/_repositories.scss +148 -0
  6. data/app/assets/stylesheets/_pages/_stacks.scss +19 -0
  7. data/app/assets/stylesheets/shipit.scss +1 -0
  8. data/app/controllers/shipit/api/{pull_requests_controller.rb → merge_requests_controller.rb} +8 -8
  9. data/app/controllers/shipit/api/stacks_controller.rb +14 -1
  10. data/app/controllers/shipit/deploys_controller.rb +2 -2
  11. data/app/controllers/shipit/merge_requests_controller.rb +31 -0
  12. data/app/controllers/shipit/merge_status_controller.rb +15 -15
  13. data/app/controllers/shipit/repositories_controller.rb +74 -0
  14. data/app/controllers/shipit/tasks_controller.rb +4 -4
  15. data/app/helpers/shipit/chunks_helper.rb +2 -2
  16. data/app/helpers/shipit/github_url_helper.rb +8 -0
  17. data/app/helpers/shipit/stacks_helper.rb +4 -0
  18. data/app/jobs/shipit/create_on_github_job.rb +1 -0
  19. data/app/jobs/shipit/destroy_repository_job.rb +24 -0
  20. data/app/jobs/shipit/destroy_stack_job.rb +2 -2
  21. data/app/jobs/shipit/perform_task_job.rb +4 -98
  22. data/app/jobs/shipit/process_merge_requests_job.rb +32 -0
  23. data/app/jobs/shipit/refresh_merge_request_job.rb +11 -0
  24. data/app/models/shipit/anonymous_user.rb +4 -0
  25. data/app/models/shipit/check_run.rb +2 -2
  26. data/app/models/shipit/command_line_user.rb +4 -0
  27. data/app/models/shipit/commit.rb +11 -11
  28. data/app/models/shipit/commit_checks.rb +1 -0
  29. data/app/models/shipit/deploy.rb +1 -0
  30. data/app/models/shipit/deploy_spec.rb +16 -4
  31. data/app/models/shipit/deploy_spec/file_system.rb +11 -5
  32. data/app/models/shipit/hook.rb +2 -0
  33. data/app/models/shipit/merge_request.rb +302 -0
  34. data/app/models/shipit/provisioning_handler.rb +32 -0
  35. data/app/models/shipit/provisioning_handler/base.rb +30 -0
  36. data/app/models/shipit/provisioning_handler/unregistered_provisioning_handler.rb +35 -0
  37. data/app/models/shipit/pull_request.rb +25 -264
  38. data/app/models/shipit/pull_request_assignment.rb +10 -0
  39. data/app/models/shipit/repository.rb +54 -0
  40. data/app/models/shipit/review_stack.rb +116 -0
  41. data/app/models/shipit/review_stack_provisioning_queue.rb +39 -0
  42. data/app/models/shipit/stack.rb +22 -8
  43. data/app/models/shipit/task.rb +56 -7
  44. data/app/models/shipit/task_execution_strategy/base.rb +20 -0
  45. data/app/models/shipit/task_execution_strategy/default.rb +110 -0
  46. data/app/models/shipit/user.rb +6 -1
  47. data/app/models/shipit/webhooks.rb +10 -0
  48. data/app/models/shipit/webhooks/handlers/pull_request/assigned_handler.rb +74 -0
  49. data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +68 -0
  50. data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +74 -0
  51. data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +127 -0
  52. data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +106 -0
  53. data/app/models/shipit/webhooks/handlers/pull_request/opened_handler.rb +83 -0
  54. data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +88 -0
  55. data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +103 -0
  56. data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +107 -0
  57. data/app/serializers/shipit/deploy_serializer.rb +6 -0
  58. data/app/serializers/shipit/merge_request_serializer.rb +21 -0
  59. data/app/serializers/shipit/pull_request_serializer.rb +5 -8
  60. data/app/serializers/shipit/review_stack_serializer.rb +7 -0
  61. data/app/serializers/shipit/stack_serializer.rb +7 -6
  62. data/app/serializers/shipit/tail_task_serializer.rb +10 -2
  63. data/app/serializers/shipit/task_serializer.rb +1 -1
  64. data/app/views/shipit/merge_requests/_merge_request.html.erb +29 -0
  65. data/app/views/shipit/{pull_requests → merge_requests}/index.html.erb +2 -2
  66. data/app/views/shipit/merge_requests/merge_requests/_pull_request.html.erb +29 -0
  67. data/app/views/shipit/merge_requests/merge_requests/index.html.erb +20 -0
  68. data/app/views/shipit/merge_status/_merge_queue_button.html.erb +3 -3
  69. data/app/views/shipit/merge_status/backlogged.html.erb +1 -1
  70. data/app/views/shipit/merge_status/failure.html.erb +1 -1
  71. data/app/views/shipit/merge_status/locked.html.erb +1 -1
  72. data/app/views/shipit/merge_status/success.html.erb +2 -2
  73. data/app/views/shipit/repositories/_header.html.erb +19 -0
  74. data/app/views/shipit/repositories/index.html.erb +31 -0
  75. data/app/views/shipit/repositories/new.html.erb +23 -0
  76. data/app/views/shipit/repositories/settings.html.erb +53 -0
  77. data/app/views/shipit/repositories/show.html.erb +30 -0
  78. data/app/views/shipit/stacks/_banners.html.erb +13 -0
  79. data/app/views/shipit/stacks/_header.html.erb +5 -2
  80. data/app/views/shipit/stacks/_stack.html.erb +8 -0
  81. data/app/views/shipit/stacks/index.html.erb +2 -1
  82. data/app/views/shipit/stacks/settings.html.erb +5 -5
  83. data/app/views/shipit/stacks/show.html.erb +1 -1
  84. data/app/views/shipit/tasks/_task_output.html.erb +1 -1
  85. data/config/routes.rb +15 -5
  86. data/db/migrate/20200706145406_add_review_stacks.rb +12 -0
  87. data/db/migrate/20200804144639_rename_pull_request_to_merge_request.rb +7 -0
  88. data/db/migrate/20200804161512_rename_commits_pull_request_id_to_merge_request_id.rb +5 -0
  89. data/db/migrate/20200813134712_recreate_shipit_pull_requests.rb +22 -0
  90. data/db/migrate/20200813194056_create_pull_request_assignments.rb +8 -0
  91. data/db/migrate/20201001125502_add_provision_pr_stacks_flag_to_repositories.rb +7 -0
  92. data/db/migrate/20201008145809_add_retry_attempt_to_tasks.rb +5 -0
  93. data/db/migrate/20201008152744_add_max_retries_to_tasks.rb +5 -0
  94. data/lib/shipit.rb +11 -1
  95. data/lib/shipit/github_app.rb +1 -1
  96. data/lib/shipit/review_stack_commands.rb +8 -0
  97. data/lib/shipit/stack_commands.rb +6 -1
  98. data/lib/shipit/task_commands.rb +1 -0
  99. data/lib/shipit/version.rb +1 -1
  100. data/lib/tasks/cron.rake +11 -2
  101. data/test/controllers/api/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +12 -12
  102. data/test/controllers/api/outputs_controller_test.rb +1 -0
  103. data/test/controllers/api/rollback_controller_test.rb +1 -1
  104. data/test/controllers/api/stacks_controller_test.rb +21 -1
  105. data/test/controllers/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +6 -6
  106. data/test/controllers/repositories_controller_test.rb +71 -0
  107. data/test/controllers/stacks_controller_test.rb +9 -1
  108. data/test/controllers/tasks_controller_test.rb +14 -2
  109. data/test/controllers/webhooks_controller_test.rb +1 -1
  110. data/test/dummy/config/application.rb +6 -1
  111. data/test/dummy/config/environments/development.rb +0 -3
  112. data/test/dummy/config/environments/test.rb +0 -5
  113. data/test/dummy/db/schema.rb +52 -14
  114. data/test/dummy/db/seeds.rb +1 -1
  115. data/test/fixtures/payloads/check_suite_master.json +2 -2
  116. data/test/fixtures/payloads/invalid_pull_request.json +117 -0
  117. data/test/fixtures/payloads/provision_disabled_pull_request.json +454 -0
  118. data/test/fixtures/payloads/pull_request_assigned.json +480 -0
  119. data/test/fixtures/payloads/pull_request_closed.json +454 -0
  120. data/test/fixtures/payloads/pull_request_labeled.json +461 -0
  121. data/test/fixtures/payloads/pull_request_opened.json +454 -0
  122. data/test/fixtures/payloads/pull_request_reopened.json +454 -0
  123. data/test/fixtures/payloads/pull_request_unlabeled.json +454 -0
  124. data/test/fixtures/payloads/pull_request_with_no_repo.json +454 -0
  125. data/test/fixtures/shipit/commits.yml +15 -2
  126. data/test/fixtures/shipit/merge_requests.yml +141 -0
  127. data/test/fixtures/shipit/pull_request_assignments.yml +3 -0
  128. data/test/fixtures/shipit/pull_requests.yml +10 -131
  129. data/test/fixtures/shipit/repositories.yml +1 -0
  130. data/test/fixtures/shipit/stacks.yml +145 -0
  131. data/test/fixtures/shipit/statuses.yml +9 -0
  132. data/test/fixtures/shipit/tasks.yml +3 -0
  133. data/test/fixtures/shipit/users.yml +7 -0
  134. data/test/helpers/payloads_helper.rb +4 -0
  135. data/test/jobs/chunk_rollup_job_test.rb +15 -1
  136. data/test/jobs/destroy_repository_job_test.rb +27 -0
  137. data/test/jobs/perform_task_job_test.rb +8 -8
  138. data/test/jobs/{merge_pull_requests_job_test.rb → process_merge_requests_job_test.rb} +18 -18
  139. data/test/lib/shipit/deploy_commands_test.rb +16 -0
  140. data/test/lib/shipit/task_commands_test.rb +17 -0
  141. data/test/models/commits_test.rb +22 -13
  142. data/test/models/deploy_spec_test.rb +57 -24
  143. data/test/models/deploys_test.rb +148 -14
  144. data/test/models/{pull_request_test.rb → merge_request_test.rb} +30 -30
  145. data/test/models/pull_request_assignment_test.rb +16 -0
  146. data/test/models/shipit/provisioning_handler/base_test.rb +33 -0
  147. data/test/models/shipit/provisioning_handler/unregistered_provisioning_handler_test.rb +49 -0
  148. data/test/models/shipit/provisioning_handler_test.rb +64 -0
  149. data/test/models/shipit/pull_request_test.rb +52 -0
  150. data/test/models/shipit/repository_test.rb +5 -1
  151. data/test/models/shipit/review_stack_provision_status_test.rb +77 -0
  152. data/test/models/shipit/review_stack_provisioning_queue_test.rb +63 -0
  153. data/test/models/shipit/review_stack_test.rb +59 -0
  154. data/test/models/{stacks_test.rb → shipit/stacks_test.rb} +10 -4
  155. data/test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb +45 -0
  156. data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +192 -0
  157. data/test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb +47 -0
  158. data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +209 -0
  159. data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +332 -0
  160. data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +238 -0
  161. data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +282 -0
  162. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +83 -0
  163. data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +324 -0
  164. data/test/models/shipit/{wehbooks → webhooks}/handlers_test.rb +0 -0
  165. data/test/models/tasks_test.rb +44 -3
  166. data/test/serializers/shipit/pull_request_serializer_test.rb +29 -0
  167. data/test/unit/command_test.rb +3 -3
  168. data/test/unit/github_url_helper_test.rb +5 -0
  169. data/test/unit/shipit_task_execution_strategy_test.rb +47 -0
  170. metadata +260 -154
  171. data/app/controllers/shipit/pull_requests_controller.rb +0 -31
  172. data/app/jobs/shipit/merge_pull_requests_job.rb +0 -32
  173. data/app/jobs/shipit/refresh_pull_request_job.rb +0 -11
  174. data/app/views/shipit/pull_requests/_pull_request.html.erb +0 -29
  175. data/test/fixtures/shipit/output_chunks.yml +0 -47
  176. data/test/models/output_chunk_test.rb +0 -21
@@ -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,59 @@
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
+ # Asserting that :archived_25hours_ago, :archived_30minutes_ago and :shipit are not queued.
13
+ assert_enqueued_jobs 1 do
14
+ assert_enqueued_with(job: Shipit::ClearGitCacheJob, args: [shipit_stacks(:archived_6hours_ago)]) do
15
+ ReviewStack.clear_stale_caches
16
+ end
17
+ end
18
+ end
19
+
20
+ test "creating a review stack emits a hook" do
21
+ new_review_stack = @review_stack.dup
22
+ new_review_stack.environment = "new-review-stack-environment"
23
+
24
+ expect_hook(:review_stack, new_review_stack, action: :added, review_stack: new_review_stack) do
25
+ new_review_stack.save!
26
+ end
27
+ end
28
+
29
+ test "updating a review stack emit a hook" do
30
+ expect_hook(:review_stack, @review_stack, action: :updated, review_stack: @review_stack) do
31
+ @review_stack.update(environment: 'foo')
32
+ end
33
+ end
34
+
35
+ test "updating a review stack doesn't emit a hook if only `updated_at` is changed" do
36
+ # force a save to make sure `cached_deploy_spec` serialization is consistent with how Active Record would
37
+ # serialize it.
38
+ @review_stack.update(updated_at: 2.days.ago)
39
+
40
+ expect_no_hook(:review_stack) do
41
+ @review_stack.update(updated_at: Time.zone.now)
42
+ end
43
+ end
44
+
45
+ test "deleteing a review stack emits a hook" do
46
+ expect_hook(:review_stack, @review_stack, action: :removed, review_stack: @review_stack) do
47
+ @review_stack.destroy!
48
+ end
49
+ end
50
+
51
+ test "#env includes the stack's pull request labels" do
52
+ stack = shipit_stacks(:review_stack)
53
+ stack.pull_request.labels = ["wip", "bug"]
54
+
55
+ assert_equal stack.env["WIP"], "true"
56
+ assert_equal stack.env["BUG"], "true"
57
+ end
58
+ end
59
+ end
@@ -267,8 +267,9 @@ module Shipit
267
267
  end
268
268
  end
269
269
 
270
- test "#deployable? returns true if the stack is not locked and is not deploying" do
270
+ test "#deployable? returns true if the stack is not locked, not awaiting provision, and is not deploying" do
271
271
  @stack.deploys.destroy_all
272
+ @stack.update!(lock_reason: nil, awaiting_provision: false)
272
273
  assert_predicate @stack, :deployable?
273
274
  end
274
275
 
@@ -282,6 +283,11 @@ module Shipit
282
283
  refute_predicate @stack, :deployable?
283
284
  end
284
285
 
286
+ test "#deployable? returns false if the stack is awaiting provisioning" do
287
+ @stack.update!(lock_reason: nil, awaiting_provision: true)
288
+ refute_predicate @stack, :deployable?
289
+ end
290
+
285
291
  test "#allows_merges? returns true if the stack is not locked and the branch is green" do
286
292
  assert_predicate @stack, :allows_merges?
287
293
  end
@@ -345,12 +351,12 @@ module Shipit
345
351
  end
346
352
  end
347
353
 
348
- test "unlocking the stack triggers a MergePullRequests job" do
349
- assert_no_enqueued_jobs(only: MergePullRequestsJob) do
354
+ test "unlocking the stack triggers a MergeMergeRequests job" do
355
+ assert_no_enqueued_jobs(only: ProcessMergeRequestsJob) do
350
356
  @stack.update(lock_reason: "Just for fun", lock_author: shipit_users(:walrus))
351
357
  end
352
358
 
353
- assert_enqueued_with(job: MergePullRequestsJob, args: [@stack]) do
359
+ assert_enqueued_with(job: ProcessMergeRequestsJob, args: [@stack]) do
354
360
  @stack.update(lock_reason: nil)
355
361
  end
356
362
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ module Webhooks
7
+ module Handlers
8
+ module PullRequest
9
+ class AssignedHandlerTest < ActiveSupport::TestCase
10
+ test "validates payload" do
11
+ assert_raise(StandardError) { AssignedHandler.new(payload_parsed(:invalid_pull_request)) }
12
+ end
13
+
14
+ test "ignores irrelevant PR actions" do
15
+ assert_no_enqueued_jobs do
16
+ AssignedHandler.new(payload_parsed(:pull_request_assigned).merge(action: "labeled")).process
17
+ end
18
+ end
19
+
20
+ test "updates the existing PullRequest's assignees" do
21
+ pull_request = shipit_pull_requests(:review_stack_review)
22
+ pull_request.assignees.clear
23
+ payload = payload_parsed(:pull_request_assigned)
24
+ payload["number"] = pull_request.number
25
+ payload["pull_request"]["number"] = pull_request.number
26
+
27
+ AssignedHandler.new(payload).process
28
+
29
+ assert [shipit_users(:codertocat)], pull_request.reload.assignees
30
+ end
31
+
32
+ test "does not attempt to update when PullRequest does not exist" do
33
+ unknown_pull_request_number = 999
34
+ payload = payload_parsed(:pull_request_assigned)
35
+ payload["number"] = unknown_pull_request_number
36
+
37
+ assert_no_changes -> { Shipit::PullRequestAssignment.count } do
38
+ AssignedHandler.new(payload).process
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ module Webhooks
7
+ module Handlers
8
+ module PullRequest
9
+ class ClosedHandlerTest < ActiveSupport::TestCase
10
+ test "validates payload" do
11
+ assert_raise(StandardError) { Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:invalid_pull_request)) }
12
+ end
13
+
14
+ test "ignores irrelevant PR actions" do
15
+ assert_no_difference -> { Shipit::Stack.not_archived.count } do
16
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_opened).merge(action: "assigned")).process
17
+ end
18
+ end
19
+
20
+ test "does not error for repos that are not tracked" do
21
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_with_no_repo).merge(action: "closed")).process
22
+ end
23
+
24
+ test "archives stacks for repos that are tracked" do
25
+ create_stack
26
+ assert_difference -> { Shipit::Stack.not_archived.count }, -1 do
27
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_closed)).process
28
+ end
29
+ end
30
+
31
+ test "ignored duplicate deliveries" do
32
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_opened)).process
33
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_closed)).process
34
+ assert_no_difference -> { Shipit::Stack.not_archived.count } do
35
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_closed)).process
36
+ end
37
+ end
38
+
39
+ test "archives stacks for repos that allow_all" do
40
+ stack = create_stack
41
+ repository = shipit_repositories(:shipit)
42
+ configure_provisioning_behavior(
43
+ repository: repository,
44
+ behavior: :allow_all
45
+ )
46
+
47
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload_parsed(:pull_request_closed)).process
48
+
49
+ assert stack.reload.archived?, "Expected stack to be archived"
50
+ end
51
+
52
+ test "archives stacks for repos that allow_with_label when label is present" do
53
+ stack = create_stack
54
+ repository = shipit_repositories(:shipit)
55
+ configure_provisioning_behavior(
56
+ repository: repository,
57
+ behavior: :allow_with_label,
58
+ label: "pull-requests-label"
59
+ )
60
+ payload = payload_parsed(:pull_request_closed)
61
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
62
+
63
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload).process
64
+
65
+ assert stack.reload.archived?, "Expected stack to be archived"
66
+ end
67
+
68
+ test "archives stacks for repos that allow_with_label when label is absent" do
69
+ stack = create_stack
70
+ repository = shipit_repositories(:shipit)
71
+ configure_provisioning_behavior(
72
+ repository: repository,
73
+ behavior: :allow_with_label,
74
+ label: "pull-requests-label"
75
+ )
76
+ payload = payload_parsed(:pull_request_closed)
77
+ payload["pull_request"]["labels"] = []
78
+
79
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload).process
80
+
81
+ assert stack.reload.archived?, "Expected stack to be archived"
82
+ end
83
+
84
+ test "archives stacks for repos that prevent_with_label when label is absent" do
85
+ stack = create_stack
86
+ repository = shipit_repositories(:shipit)
87
+ configure_provisioning_behavior(
88
+ repository: repository,
89
+ behavior: :prevent_with_label,
90
+ label: "pull-requests-label"
91
+ )
92
+ payload = payload_parsed(:pull_request_closed)
93
+ payload["pull_request"]["labels"] = []
94
+
95
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload).process
96
+
97
+ assert stack.reload.archived?, "Expected stack to be archived"
98
+ end
99
+
100
+ test "archives stacks for repos that prevent_with_label when label is present" do
101
+ stack = create_stack
102
+ repository = shipit_repositories(:shipit)
103
+ configure_provisioning_behavior(
104
+ repository: repository,
105
+ behavior: :prevent_with_label,
106
+ label: "pull-requests-label"
107
+ )
108
+ payload = payload_parsed(:pull_request_closed)
109
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
110
+
111
+ Shipit::Webhooks::Handlers::PullRequest::ClosedHandler.new(payload).process
112
+
113
+ assert stack.reload.archived?, "Expected stack to be archived"
114
+ end
115
+
116
+ def configure_provisioning_behavior(repository:, provisioning_enabled: true, behavior: :allow_all, label: nil)
117
+ repository.review_stacks_enabled = provisioning_enabled
118
+ repository.provisioning_behavior = behavior
119
+ repository.provisioning_label_name = label
120
+ repository.save!
121
+
122
+ repository
123
+ end
124
+
125
+ def create_archived_stack
126
+ stack = create_stack
127
+ stack.archive!(shipit_users(:codertocat))
128
+
129
+ stack
130
+ end
131
+
132
+ def create_stack
133
+ repository = shipit_repositories(:shipit)
134
+ repository.provisioning_behavior = :allow_all
135
+ repository.save!
136
+
137
+ payload = payload_parsed(:pull_request_labeled)
138
+ payload["action"] = "opened"
139
+
140
+ OpenedHandler.new(payload).process
141
+
142
+ stack = repository.stacks.last
143
+ stack.update(provision_status: :provisioned)
144
+ complete_active_tasks(stack)
145
+
146
+ stack
147
+ end
148
+
149
+ def complete_active_tasks(stack)
150
+ active_tasks = stack
151
+ .tasks
152
+ .active
153
+
154
+ active_tasks.map(&:run)
155
+ active_tasks.reload
156
+ active_tasks.map(&:complete)
157
+ end
158
+
159
+ setup do
160
+ Shipit.github.api.stubs(:commit)
161
+ .with("shopify/shipit-engine", "ec26c3e57ca3a959ca5aad62de7213c562f8c821")
162
+ .returns(
163
+ resource(
164
+ {
165
+ sha: "ec26c3e57ca3a959ca5aad62de7213c562f8c821",
166
+ commit: {
167
+ author: {
168
+ name: "Codertocat",
169
+ email: "21031067+Codertocat@users.noreply.github.com",
170
+ date: "2019-05-15 15:20:30",
171
+ },
172
+ committer: {
173
+ name: "Codertocat",
174
+ email: "21031067+Codertocat@users.noreply.github.com",
175
+ date: "2019-05-15 15:20:30",
176
+ },
177
+ message: "Update README.md",
178
+ },
179
+ stats: {
180
+ total: 2,
181
+ additions: 1,
182
+ deletions: 1,
183
+ },
184
+ }
185
+ )
186
+ )
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end