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
@@ -2,30 +2,30 @@
2
2
  require 'test_helper'
3
3
 
4
4
  module Shipit
5
- class PullRequestsControllerTest < ActionController::TestCase
5
+ class MergeRequestsControllerTest < ActionController::TestCase
6
6
  setup do
7
7
  @stack = shipit_stacks(:shipit)
8
- @pr = shipit_pull_requests(:shipit_pending)
8
+ @pr = shipit_merge_requests(:shipit_pending)
9
9
  session[:user_id] = shipit_users(:walrus).id
10
10
  end
11
11
 
12
12
  test "#index shows pending pull requests" do
13
13
  get :index, params: { stack_id: @stack.to_param }
14
14
  assert_response :success
15
- assert_select '.pr-list .pr', @stack.pull_requests.pending.count
15
+ assert_select '.pr-list .pr', @stack.merge_requests.pending.count
16
16
  end
17
17
 
18
18
  test "#add can enqueue a pull request" do
19
- assert_difference -> { PullRequest.count }, +1 do
19
+ assert_difference -> { MergeRequest.count }, +1 do
20
20
  post :create, params: { stack_id: @stack.to_param, number_or_url: '#5' }
21
21
  end
22
- assert_redirected_to stack_pull_requests_path(@stack)
22
+ assert_redirected_to stack_merge_requests_path(@stack)
23
23
  end
24
24
 
25
25
  test "#destroy can cancel a pending pull request" do
26
26
  assert_predicate @pr, :pending?
27
27
  delete :destroy, params: { stack_id: @stack.to_param, id: @pr.id }
28
- assert_redirected_to stack_pull_requests_path(@stack)
28
+ assert_redirected_to stack_merge_requests_path(@stack)
29
29
  assert_predicate @pr.reload, :canceled?
30
30
  end
31
31
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+ require 'test_helper'
3
+
4
+ module Shipit
5
+ class RepositoriesControllerTest < ActionController::TestCase
6
+ setup do
7
+ @routes = Shipit::Engine.routes
8
+ @repository = shipit_repositories(:shipit)
9
+ session[:user_id] = shipit_users(:walrus).id
10
+ end
11
+
12
+ test "GitHub authentication is mandatory" do
13
+ session[:user_id] = nil
14
+ get :index
15
+ assert_redirected_to '/github/auth/github?origin=http%3A%2F%2Ftest.host%2Frepositories'
16
+ end
17
+
18
+ test "current_user must be a member of at least a Shipit.github_teams" do
19
+ session[:user_id] = shipit_users(:bob).id
20
+ Shipit.stubs(:github_teams).returns([shipit_teams(:cyclimse_cooks), shipit_teams(:shopify_developers)])
21
+ get :index
22
+ assert_response :forbidden
23
+ assert_equal(
24
+ 'You must be a member of cyclimse/cooks or shopify/developers to access this application.',
25
+ response.body,
26
+ )
27
+ end
28
+
29
+ test "#show is success" do
30
+ get :show, params: { id: @repository.to_param }
31
+ assert_response :ok
32
+ end
33
+
34
+ test "#create creates a repository and redirects to it" do
35
+ assert_difference "Repository.count" do
36
+ post :create, params: {
37
+ repository: {
38
+ name: 'valid',
39
+ owner: 'repository',
40
+ },
41
+ }
42
+ end
43
+ assert_redirected_to repository_path(Repository.last)
44
+ end
45
+
46
+ test "#create when not valid renders new" do
47
+ assert_no_difference "Repository.count" do
48
+ post :create, params: {
49
+ repository: {
50
+ owner: 'some',
51
+ name: 'owner/path',
52
+ },
53
+ }
54
+ end
55
+ assert_response :success
56
+ end
57
+
58
+ test "#destroy enqueues a DestroyRepositoryJob" do
59
+ assert_enqueued_with(job: DestroyRepositoryJob, args: [@repository]) do
60
+ delete :destroy, params: { id: @repository.to_param }
61
+ end
62
+
63
+ assert_redirected_to repositories_path
64
+ end
65
+
66
+ test "#settings is success" do
67
+ get :settings, params: { id: @repository.to_param }
68
+ assert_response :success
69
+ end
70
+ end
71
+ end
@@ -48,11 +48,17 @@ module Shipit
48
48
  end
49
49
 
50
50
  test "#index list all stacks" do
51
- get :index
51
+ get :index, params: { show_archived: true }
52
52
  assert_response :ok
53
53
  assert_select ".stack", count: Stack.count
54
54
  end
55
55
 
56
+ test "#index list all not archived stacks" do
57
+ get :index
58
+ assert_response :ok
59
+ assert_select ".stack", count: Stack.not_archived.count
60
+ end
61
+
56
62
  test "#index list a repo stacks if the :repo params is passed" do
57
63
  repo = shipit_repositories(:shipit)
58
64
  get :index, params: { repo: repo.full_name }
@@ -175,6 +181,8 @@ module Shipit
175
181
  @stack.reload
176
182
  refute @stack.archived?
177
183
  refute @stack.locked?
184
+ assert_nil @stack.locked_since
185
+ assert_nil @stack.lock_reason
178
186
  assert_instance_of AnonymousUser, @stack.lock_author
179
187
  end
180
188
 
@@ -101,12 +101,24 @@ module Shipit
101
101
 
102
102
  test ":tail returns the task status, output, and next url" do
103
103
  @task = shipit_deploys(:shipit_running)
104
- last_chunk = @task.chunks.last
104
+ @task.write("dummy output")
105
+ last_chunk = @task.chunk_output.bytesize
105
106
 
106
- get :tail, params: { stack_id: @stack.to_param, id: @task.id, last_id: last_chunk.id }, format: :json
107
+ get :tail, params: { stack_id: @stack.to_param, id: @task.id }, format: :json
107
108
  assert_response :success
108
109
  assert_json_keys %w(url status output)
109
110
  assert_json 'status', @task.status
111
+ assert_json 'output', @task.chunk_output
112
+ assert_json 'url', "/shopify/shipit-engine/production/tasks/#{@task.id}/tail?last_byte=#{last_chunk}"
113
+ end
114
+
115
+ test ":tail can handle last_byte as string" do
116
+ @task = shipit_deploys(:shipit_running)
117
+ @task.write("dummy output")
118
+
119
+ get :tail, params: { stack_id: @stack.to_param, id: @task.id, last_byte: "50" }, format: :json
120
+ assert_response :success
121
+ assert_json_keys %w(url status output)
110
122
  end
111
123
 
112
124
  test ":tail doesn't returns the next url if the task is finished" do
@@ -22,14 +22,15 @@ module Shipit
22
22
  test ":push with the target branch queues a GithubSyncJob" do
23
23
  request.headers['X-Github-Event'] = 'push'
24
24
 
25
+ body = JSON.parse(payload(:push_master)).to_json
25
26
  assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
26
- post :create, body: payload(:push_master), as: :json
27
+ post :create, body: body, as: :json
27
28
  end
28
29
  end
29
30
 
30
31
  test ":push does not enqueue a job if not the target branch" do
31
32
  request.headers['X-Github-Event'] = 'push'
32
- params = payload(:push_not_master)
33
+ params = JSON.parse(payload(:push_not_master)).to_json
33
34
  assert_no_enqueued_jobs do
34
35
  post :create, body: params, as: :json
35
36
  end
@@ -40,8 +41,9 @@ module Shipit
40
41
 
41
42
  commit = shipit_commits(:first)
42
43
 
44
+ body = JSON.parse(payload(:status_master)).merge(repository_params).to_json
43
45
  assert_difference 'commit.statuses.count', 1 do
44
- post :create, body: payload(:status_master), as: :json
46
+ post :create, body: body, as: :json
45
47
  end
46
48
 
47
49
  status = commit.statuses.last
@@ -55,14 +57,14 @@ module Shipit
55
57
 
56
58
  test ":state with a unexisting commit respond with 200 OK" do
57
59
  request.headers['X-Github-Event'] = 'status'
58
- params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [{ 'name' => 'master' }] }.to_json
60
+ params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [{ 'name' => 'master' }] }.merge(repository_params).to_json
59
61
  post :create, body: params, as: :json
60
62
  assert_response :ok
61
63
  end
62
64
 
63
65
  test ":state in an untracked branche bails out" do
64
66
  request.headers['X-Github-Event'] = 'status'
65
- params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [] }.to_json
67
+ params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [] }.merge(repository_params).to_json
66
68
  post :create, body: params, as: :json
67
69
  assert_response :ok
68
70
  end
@@ -70,8 +72,9 @@ module Shipit
70
72
  test ":check_suite with the target branch queues a RefreshCheckRunsJob" do
71
73
  request.headers['X-Github-Event'] = 'check_suite'
72
74
 
75
+ body = JSON.parse(payload(:check_suite_master)).to_json
73
76
  assert_enqueued_with(job: RefreshCheckRunsJob) do
74
- post :create, body: payload(:check_suite_master), as: :json
77
+ post :create, body: body, as: :json
75
78
  assert_response :ok
76
79
  end
77
80
  end
@@ -88,13 +91,13 @@ module Shipit
88
91
  test "verifies webhook signature" do
89
92
  commit = shipit_commits(:first)
90
93
 
91
- payload = { "sha" => commit.sha, "state" => "pending", "target_url" => "https://ci.example.com/1000/output" }.to_json
94
+ payload = { "sha" => commit.sha, "state" => "pending", "target_url" => "https://ci.example.com/1000/output" }.merge(repository_params).to_json
92
95
  signature = 'sha1=4848deb1c9642cd938e8caa578d201ca359a8249'
93
96
 
94
97
  @request.headers['X-Github-Event'] = 'push'
95
98
  @request.headers['X-Hub-Signature'] = signature
96
99
 
97
- Shipit.github.expects(:verify_webhook_signature).with(signature, payload).returns(false)
100
+ Shipit.github(organization: 'shopify').expects(:verify_webhook_signature).with(signature, payload).returns(false)
98
101
 
99
102
  post :create, body: payload, as: :json
100
103
  assert_response :unprocessable_entity
@@ -157,28 +160,40 @@ module Shipit
157
160
  test "other events trigger custom handlers" do
158
161
  event = 'pull_request'
159
162
  mock_handler = mock
160
- mock_handler.expects(:call).with(pull_request_params.stringify_keys).once
161
- Shipit::Webhooks.register_handler(event, mock_handler)
163
+ mock_handler.expects(:call).with(pull_request_params.deep_stringify_keys).once
164
+ Shipit::Webhooks.handlers["pull_request"] = [mock_handler]
162
165
 
163
166
  @request.headers['X-Github-Event'] = event
164
167
  post :create, body: pull_request_params.to_json, as: :json
165
168
  assert_response :ok
166
169
  end
167
170
 
171
+ test "events with no handler are dropped" do
172
+ event = 'not_a_real_event'
173
+
174
+ @request.headers['X-Github-Event'] = event
175
+ post :create, body: pull_request_params.to_json, as: :json
176
+ assert_response 204
177
+ end
178
+
168
179
  private
169
180
 
170
181
  def pull_request_params
171
- { action: 'opened', number: 2, pull_request: 'foobar' }
182
+ { action: 'opened', number: 2, pull_request: 'foobar' }.merge(repository_params)
172
183
  end
173
184
 
174
185
  def membership_params
175
- { action: 'added', team: team_params, organization: { login: 'shopify' }, member: { login: 'walrus' } }
186
+ { action: 'added', team: team_params, organization: { login: 'shopify' }, member: { login: 'walrus' } }.merge(repository_params)
176
187
  end
177
188
 
178
189
  def team_params
179
190
  { id: shipit_teams(:shopify_developers).id, slug: 'developers', name: 'Developers', url: 'http://example.com' }
180
191
  end
181
192
 
193
+ def repository_params
194
+ { repository: { owner: { login: 'shopify' } } }
195
+ end
196
+
182
197
  def george
183
198
  stub(
184
199
  id: 42,
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -1,6 +1,11 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- require 'rails/all'
3
+ require 'active_record/railtie'
4
+ require 'action_controller/railtie'
5
+ require 'action_view/railtie'
6
+ require 'active_job/railtie'
7
+ require 'rails/test_unit/railtie'
8
+ require 'sprockets/railtie'
4
9
 
5
10
  Bundler.require(*Rails.groups)
6
11
  require "shipit"
@@ -12,7 +17,7 @@ end
12
17
 
13
18
  module Shipit
14
19
  class Application < Rails::Application
15
- config.load_defaults 6.0
20
+ config.load_defaults 6.1
16
21
  end
17
22
  end
18
23
 
@@ -1,3 +1,11 @@
1
+ <% if ENV['DATABASE_URL'].present? %>
2
+ development:
3
+ database: shipit_engine_development
4
+
5
+ test:
6
+ database: shipit_engine_test
7
+
8
+ <% else %>
1
9
  default: &default
2
10
  adapter: sqlite3
3
11
 
@@ -8,3 +16,4 @@ development:
8
16
  test:
9
17
  <<: *default
10
18
  database: db/test.sqlite3
19
+ <% end %>
@@ -28,9 +28,6 @@ Rails.application.configure do
28
28
  config.cache_store = :null_store
29
29
  end
30
30
 
31
- # Don't care if the mailer can't send.
32
- config.action_mailer.raise_delivery_errors = false
33
-
34
31
  # Print deprecation notices to the Rails logger.
35
32
  config.active_support.deprecation = :log
36
33
 
@@ -53,7 +50,7 @@ Rails.application.configure do
53
50
 
54
51
  # Raises error for missing translations
55
52
  # config.action_view.raise_on_missing_translations = true
56
- if Rails.application.config_for(:database)['adapter'] == 'sqlite3'
53
+ if Rails.application.config_for(:database)&.dig('adapter') == 'sqlite3'
57
54
  config.to_prepare do
58
55
  Shipit::DeferredTouch.enabled = false
59
56
  end
@@ -26,11 +26,6 @@ Rails.application.configure do
26
26
  # Disable request forgery protection in test environment.
27
27
  config.action_controller.allow_forgery_protection = false
28
28
 
29
- # Tell Action Mailer not to deliver emails to the real world.
30
- # The :test delivery method accumulates sent emails in the
31
- # ActionMailer::Base.deliveries array.
32
- config.action_mailer.delivery_method = :test
33
-
34
29
  # Randomize the order test cases are executed.
35
30
  config.active_support.test_order = :random
36
31
 
@@ -0,0 +1,79 @@
1
+ github:
2
+ OrgOne:
3
+ domain: # defaults to github.com
4
+ app_id: 42
5
+ installation_id: 43
6
+ bot_login: "shipit[bot]"
7
+ webhook_secret: # nil
8
+ # Randomly generated
9
+ private_key: |
10
+ -----BEGIN RSA PRIVATE KEY-----
11
+ MIIEpAIBAAKCAQEA7iUQC2uUq/gtQg0gxtyaccuicYgmq1LUr1mOWbmwM1Cv63+S
12
+ 73qo8h87FX+YyclY5fZF6SMXIys02JOkImGgbnvEOLcHnImCYrWs03msOzEIO/pG
13
+ M0YedAPtQ2MEiLIu4y8htosVxeqfEOPiq9kQgFxNKyETzjdIA9q1md8sofuJUmPv
14
+ ibacW1PecuAMnn+P8qf0XIDp7uh6noB751KvhCaCNTAPtVE9NZ18OmNG9GOyX/pu
15
+ pQHIrPgTpTG6KlAe3r6LWvemzwsMtuRGU+K+KhK9dFIlSE+v9rA32KScO8efOh6s
16
+ Gu3rWorV4iDu14U62rzEfdzzc63YL94sUbZxbwIDAQABAoIBADLJ8r8MxZtbhYN1
17
+ u0zOFZ45WL6v09dsBfITvnlCUeLPzYUDIzoxxcBFittN6C744x3ARS6wjimw+EdM
18
+ TZALlCSb/sA9wMDQzt7wchhz9Zh2H5RzDu+2f54sjDh38KqancdT8PO2fAFGxX/b
19
+ qicOVyeZB9gv6MJtJc20olBbuXAeBNfcDABF9oxF+0i+Ssg7B4VXiqgcjtGbr/Og
20
+ qRll7AqyTArVx2xEcVfZxeZ4zGnigzcJq4te7yYpxzwk+RxblkPh54Yt4WxZ+8DI
21
+ Rsn3r6ajlpwzpwvsJFU2Txq7xBTzGQMFmy/Pnjk83kP2cogxB2+tRyjITGqTwD8b
22
+ gg9PFCkCgYEA+7u8A0l0Cz6p0SI6c7ftVePVRiIhpawWN7og/wEmI6zUjm/3rA+R
23
+ hrhaVKuOD8QF/HdDsqTck5gjGAjTmJz6r33/cl1Tz+pr62znsrB4r0yMKvQbKN81
24
+ WGaWOsi2+ZXqLNv5h5wpUF0MTKlXHeKnwP5kuEvGwVn6WURFCh6PhLMCgYEA8i5e
25
+ JjulJVGyd5HuoY3xyO7E6DjidsqRnVRq+hYpORjnHvTmSwe4+tH4ha2p9Kv2Y6k3
26
+ C1NYY/fSMQoYCCRaYyJleI+la/9tsZqAmtms4ZB8KhFmPHf9fW75i6G0xKWyZ8K+
27
+ E2Ft/UaEiM282593cguV6+Kt5uExnyPxLLK4FlUCgYEAwRJ/JGI8/7bjFkTTYheq
28
+ j5q75BufhOrU6471acAe2XPgXxLfefdC3Xodxh0CS3NESBvNL4Ikr4sbN37lk4Kq
29
+ /th7iOKtuqUIeru/hZy2I3VpeDRbdGCmEJQ2GwYA2LKztg5Nd0Y9paaIHXAwIfrK
30
+ QUqcQ4HTAk8ZpUeoUBeaaeMCgYANLmbjb9WiPVsYVPIHCwHA7PX8qbPxwT7BsGmO
31
+ KQyfVfKmZa/vH4F67Vi4deZNMdrcO8aKMEQcVM2065a5QrlEsgeR00eupB1lUEJ1
32
+ qylUsZeAdqf43JMIc7TTW77KATa/nQLZbTEeWus1wvTngztuEqFbUGAks9cOkVc8
33
+ FpIcbQKBgQDVIL8gPLmn0f+4oLF8MBC+oxtKpz14X5iJ1saGFkzW5I+nIEskpS0S
34
+ qtirnTCnJFGdCrFwctnxiuiCmyGwpBYdjIfHyvYAHnqAtMnESzCUyeSFZiquVW5W
35
+ MvbMmDPoV27XOHU9kIq6NXtfrkpufiyo6/VEYWozXalxKLNuqLYfPQ==
36
+ -----END RSA PRIVATE KEY-----
37
+ oauth:
38
+ id: Iv1.bf2c2c45b449bfd9
39
+ secret: ef694cd6e45223075d78d138ef014049052665f1
40
+ teams:
41
+ OrgTwo:
42
+ domain: # defaults to github.com
43
+ app_id: 42
44
+ installation_id: 43
45
+ bot_login: "shipit[bot]"
46
+ webhook_secret: # nil
47
+ # Randomly generated
48
+ private_key: |
49
+ -----BEGIN RSA PRIVATE KEY-----
50
+ MIIEpAIBAAKCAQEA7iUQC2uUq/gtQg0gxtyaccuicYgmq1LUr1mOWbmwM1Cv63+S
51
+ 73qo8h87FX+YyclY5fZF6SMXIys02JOkImGgbnvEOLcHnImCYrWs03msOzEIO/pG
52
+ M0YedAPtQ2MEiLIu4y8htosVxeqfEOPiq9kQgFxNKyETzjdIA9q1md8sofuJUmPv
53
+ ibacW1PecuAMnn+P8qf0XIDp7uh6noB751KvhCaCNTAPtVE9NZ18OmNG9GOyX/pu
54
+ pQHIrPgTpTG6KlAe3r6LWvemzwsMtuRGU+K+KhK9dFIlSE+v9rA32KScO8efOh6s
55
+ Gu3rWorV4iDu14U62rzEfdzzc63YL94sUbZxbwIDAQABAoIBADLJ8r8MxZtbhYN1
56
+ u0zOFZ45WL6v09dsBfITvnlCUeLPzYUDIzoxxcBFittN6C744x3ARS6wjimw+EdM
57
+ TZALlCSb/sA9wMDQzt7wchhz9Zh2H5RzDu+2f54sjDh38KqancdT8PO2fAFGxX/b
58
+ qicOVyeZB9gv6MJtJc20olBbuXAeBNfcDABF9oxF+0i+Ssg7B4VXiqgcjtGbr/Og
59
+ qRll7AqyTArVx2xEcVfZxeZ4zGnigzcJq4te7yYpxzwk+RxblkPh54Yt4WxZ+8DI
60
+ Rsn3r6ajlpwzpwvsJFU2Txq7xBTzGQMFmy/Pnjk83kP2cogxB2+tRyjITGqTwD8b
61
+ gg9PFCkCgYEA+7u8A0l0Cz6p0SI6c7ftVePVRiIhpawWN7og/wEmI6zUjm/3rA+R
62
+ hrhaVKuOD8QF/HdDsqTck5gjGAjTmJz6r33/cl1Tz+pr62znsrB4r0yMKvQbKN81
63
+ WGaWOsi2+ZXqLNv5h5wpUF0MTKlXHeKnwP5kuEvGwVn6WURFCh6PhLMCgYEA8i5e
64
+ JjulJVGyd5HuoY3xyO7E6DjidsqRnVRq+hYpORjnHvTmSwe4+tH4ha2p9Kv2Y6k3
65
+ C1NYY/fSMQoYCCRaYyJleI+la/9tsZqAmtms4ZB8KhFmPHf9fW75i6G0xKWyZ8K+
66
+ E2Ft/UaEiM282593cguV6+Kt5uExnyPxLLK4FlUCgYEAwRJ/JGI8/7bjFkTTYheq
67
+ j5q75BufhOrU6471acAe2XPgXxLfefdC3Xodxh0CS3NESBvNL4Ikr4sbN37lk4Kq
68
+ /th7iOKtuqUIeru/hZy2I3VpeDRbdGCmEJQ2GwYA2LKztg5Nd0Y9paaIHXAwIfrK
69
+ QUqcQ4HTAk8ZpUeoUBeaaeMCgYANLmbjb9WiPVsYVPIHCwHA7PX8qbPxwT7BsGmO
70
+ KQyfVfKmZa/vH4F67Vi4deZNMdrcO8aKMEQcVM2065a5QrlEsgeR00eupB1lUEJ1
71
+ qylUsZeAdqf43JMIc7TTW77KATa/nQLZbTEeWus1wvTngztuEqFbUGAks9cOkVc8
72
+ FpIcbQKBgQDVIL8gPLmn0f+4oLF8MBC+oxtKpz14X5iJ1saGFkzW5I+nIEskpS0S
73
+ qtirnTCnJFGdCrFwctnxiuiCmyGwpBYdjIfHyvYAHnqAtMnESzCUyeSFZiquVW5W
74
+ MvbMmDPoV27XOHU9kIq6NXtfrkpufiyo6/VEYWozXalxKLNuqLYfPQ==
75
+ -----END RSA PRIVATE KEY-----
76
+ oauth:
77
+ id: Iv1.bf2c2c45b449bfd9
78
+ secret: ef694cd6e45223075d78d138ef014049052665f1
79
+ teams:
@@ -2,15 +2,15 @@
2
2
  # of editing this file, please use the migrations feature of Active Record to
3
3
  # incrementally modify your database, and then regenerate this schema definition.
4
4
  #
5
- # This file is the source Rails uses to define your schema when running `rails
6
- # db:schema:load`. When creating a new database, `rails db:schema:load` tends to
5
+ # This file is the source Rails uses to define your schema when running `bin/rails
6
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
7
  # be faster and is potentially less error prone than running all of your
8
8
  # migrations from scratch. Old migrations may fail to apply correctly if those
9
9
  # migrations use external dependencies or application code.
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2020_06_15_181558) do
13
+ ActiveRecord::Schema.define(version: 2021_08_23_075617) do
14
14
 
15
15
  create_table "api_clients", force: :cascade do |t|
16
16
  t.text "permissions", limit: 65535
@@ -33,6 +33,7 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
33
33
  t.string "html_url"
34
34
  t.datetime "created_at", null: false
35
35
  t.datetime "updated_at", null: false
36
+ t.datetime "github_updated_at"
36
37
  t.index ["commit_id"], name: "index_check_runs_on_commit_id"
37
38
  t.index ["github_id", "commit_id"], name: "index_check_runs_on_github_id_and_commit_id", unique: true
38
39
  t.index ["stack_id"], name: "index_check_runs_on_stack_id"
@@ -75,7 +76,7 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
75
76
  t.integer "deletions", limit: 4
76
77
  t.integer "pull_request_number"
77
78
  t.string "pull_request_title", limit: 1024
78
- t.integer "pull_request_id"
79
+ t.integer "merge_request_id"
79
80
  t.boolean "locked", default: false, null: false
80
81
  t.integer "lock_author_id", limit: 4
81
82
  t.string "pull_request_head_sha", limit: 40
@@ -138,15 +139,7 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
138
139
  t.index ["user_id"], name: "index_memberships_on_user_id"
139
140
  end
140
141
 
141
- create_table "output_chunks", force: :cascade do |t|
142
- t.integer "task_id", limit: 4
143
- t.text "text", limit: 16777215
144
- t.datetime "created_at"
145
- t.datetime "updated_at"
146
- t.index ["task_id"], name: "index_output_chunks_on_task_id"
147
- end
148
-
149
- create_table "pull_requests", force: :cascade do |t|
142
+ create_table "merge_requests", force: :cascade do |t|
150
143
  t.integer "stack_id", null: false
151
144
  t.integer "number", null: false
152
145
  t.string "title", limit: 256
@@ -168,11 +161,46 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
168
161
  t.datetime "merged_at"
169
162
  t.string "base_ref", limit: 1024
170
163
  t.integer "base_commit_id"
164
+ t.index ["head_id"], name: "index_merge_requests_on_head_id"
165
+ t.index ["merge_requested_by_id"], name: "index_merge_requests_on_merge_requested_by_id"
166
+ t.index ["merge_status"], name: "index_merge_requests_on_merge_status"
167
+ t.index ["stack_id", "github_id"], name: "index_merge_requests_on_stack_id_and_github_id", unique: true
168
+ t.index ["stack_id", "merge_status"], name: "index_merge_requests_on_stack_id_and_merge_status"
169
+ t.index ["stack_id", "number"], name: "index_merge_requests_on_stack_id_and_number", unique: true
170
+ t.index ["stack_id"], name: "index_merge_requests_on_stack_id"
171
+ end
172
+
173
+ create_table "output_chunks", force: :cascade do |t|
174
+ t.integer "task_id", limit: 4
175
+ t.text "text", limit: 16777215
176
+ t.datetime "created_at"
177
+ t.datetime "updated_at"
178
+ t.index ["task_id"], name: "index_output_chunks_on_task_id"
179
+ end
180
+
181
+ create_table "pull_request_assignments", force: :cascade do |t|
182
+ t.integer "pull_request_id"
183
+ t.integer "user_id"
184
+ t.index ["pull_request_id"], name: "index_pull_request_assignments_on_pull_request_id"
185
+ t.index ["user_id"], name: "index_pull_request_assignments_on_user_id"
186
+ end
187
+
188
+ create_table "pull_requests", force: :cascade do |t|
189
+ t.integer "stack_id", null: false
190
+ t.integer "number", null: false
191
+ t.string "title", limit: 256
192
+ t.integer "github_id", limit: 8
193
+ t.string "api_url", limit: 1024
194
+ t.string "state"
195
+ t.integer "additions", default: 0, null: false
196
+ t.integer "deletions", default: 0, null: false
197
+ t.integer "user_id"
198
+ t.text "labels"
199
+ t.integer "head_id"
200
+ t.datetime "created_at", precision: 6, null: false
201
+ t.datetime "updated_at", precision: 6, null: false
171
202
  t.index ["head_id"], name: "index_pull_requests_on_head_id"
172
- t.index ["merge_requested_by_id"], name: "index_pull_requests_on_merge_requested_by_id"
173
- t.index ["merge_status"], name: "index_pull_requests_on_merge_status"
174
203
  t.index ["stack_id", "github_id"], name: "index_pull_requests_on_stack_id_and_github_id", unique: true
175
- t.index ["stack_id", "merge_status"], name: "index_pull_requests_on_stack_id_and_merge_status"
176
204
  t.index ["stack_id", "number"], name: "index_pull_requests_on_stack_id_and_number", unique: true
177
205
  t.index ["stack_id"], name: "index_pull_requests_on_stack_id"
178
206
  end
@@ -197,6 +225,9 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
197
225
  t.string "name", limit: 100, null: false
198
226
  t.datetime "created_at", precision: 6, null: false
199
227
  t.datetime "updated_at", precision: 6, null: false
228
+ t.boolean "review_stacks_enabled", default: false
229
+ t.string "provisioning_behavior", default: "allow_all"
230
+ t.string "provisioning_label_name"
200
231
  t.index ["owner", "name"], name: "repository_unicity", unique: true
201
232
  end
202
233
 
@@ -204,7 +235,7 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
204
235
  t.string "environment", limit: 50, default: "production", null: false
205
236
  t.datetime "created_at"
206
237
  t.datetime "updated_at"
207
- t.string "branch", limit: 255, default: "master", null: false
238
+ t.string "branch", limit: 255, null: false
208
239
  t.string "deploy_url", limit: 255
209
240
  t.string "lock_reason", limit: 4096
210
241
  t.integer "tasks_count", limit: 4, default: 0, null: false
@@ -221,9 +252,15 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
221
252
  t.datetime "last_deployed_at"
222
253
  t.integer "repository_id", null: false
223
254
  t.datetime "archived_since"
255
+ t.string "provision_status", default: "deprovisioned", null: false
256
+ t.string "type", default: "Shipit::Stack"
257
+ t.boolean "awaiting_provision", default: false, null: false
224
258
  t.index ["archived_since"], name: "index_stacks_on_archived_since"
259
+ t.index ["awaiting_provision"], name: "index_stacks_on_awaiting_provision"
260
+ t.index ["provision_status"], name: "index_stacks_on_provision_status"
225
261
  t.index ["repository_id", "environment"], name: "stack_unicity", unique: true
226
262
  t.index ["repository_id"], name: "index_stacks_on_repository_id"
263
+ t.index ["type"], name: "index_stacks_on_type"
227
264
  end
228
265
 
229
266
  create_table "statuses", force: :cascade do |t|
@@ -262,6 +299,8 @@ ActiveRecord::Schema.define(version: 2020_06_15_181558) do
262
299
  t.boolean "ignored_safeties", default: false, null: false
263
300
  t.integer "aborted_by_id"
264
301
  t.integer "rollback_once_aborted_to_id"
302
+ t.integer "retry_attempt", default: 0, null: false
303
+ t.integer "max_retries"
265
304
  t.index ["rolled_up", "created_at", "status"], name: "index_tasks_on_rolled_up_and_created_at_and_status"
266
305
  t.index ["since_commit_id"], name: "index_tasks_on_since_commit_id"
267
306
  t.index ["stack_id", "allow_concurrency", "status"], name: "index_active_tasks"