shipit-engine 0.32.0 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
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