shipit-engine 0.28.1 → 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 (410) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -2
  3. data/Rakefile +4 -2
  4. data/app/assets/images/archive-solid.svg +1 -0
  5. data/app/assets/images/magic-solid.svg +1 -0
  6. data/app/assets/javascripts/shipit/repositories_search.js.coffee +60 -0
  7. data/app/assets/javascripts/shipit/{search.js.coffee → stack_search.js.coffee} +0 -0
  8. data/app/assets/stylesheets/_pages/_repositories.scss +148 -0
  9. data/app/assets/stylesheets/_pages/_stacks.scss +95 -3
  10. data/app/assets/stylesheets/merge_status.scss +0 -3
  11. data/app/assets/stylesheets/shipit.scss +1 -0
  12. data/app/controllers/concerns/shipit/active_model_serializers_patch.rb +13 -0
  13. data/app/controllers/concerns/shipit/api/cacheable.rb +1 -0
  14. data/app/controllers/concerns/shipit/api/paginable.rb +3 -2
  15. data/app/controllers/concerns/shipit/api/rendering.rb +5 -4
  16. data/app/controllers/concerns/shipit/authentication.rb +3 -2
  17. data/app/controllers/concerns/shipit/pagination.rb +2 -1
  18. data/app/controllers/shipit/api/base_controller.rb +11 -6
  19. data/app/controllers/shipit/api/ccmenu_controller.rb +2 -1
  20. data/app/controllers/shipit/api/commits_controller.rb +2 -1
  21. data/app/controllers/shipit/api/deploys_controller.rb +4 -3
  22. data/app/controllers/shipit/api/hooks_controller.rb +6 -5
  23. data/app/controllers/shipit/api/locks_controller.rb +5 -4
  24. data/app/controllers/shipit/api/merge_requests_controller.rb +37 -0
  25. data/app/controllers/shipit/api/outputs_controller.rb +2 -1
  26. data/app/controllers/shipit/api/release_statuses_controller.rb +3 -2
  27. data/app/controllers/shipit/api/rollbacks_controller.rb +33 -0
  28. data/app/controllers/shipit/api/stacks_controller.rb +50 -5
  29. data/app/controllers/shipit/api/tasks_controller.rb +6 -5
  30. data/app/controllers/shipit/api_clients_controller.rb +50 -0
  31. data/app/controllers/shipit/ccmenu_url_controller.rb +4 -3
  32. data/app/controllers/shipit/commit_checks_controller.rb +2 -1
  33. data/app/controllers/shipit/commits_controller.rb +2 -1
  34. data/app/controllers/shipit/deploys_controller.rb +5 -4
  35. data/app/controllers/shipit/github_authentication_controller.rb +4 -3
  36. data/app/controllers/shipit/merge_requests_controller.rb +31 -0
  37. data/app/controllers/shipit/merge_status_controller.rb +33 -28
  38. data/app/controllers/shipit/release_statuses_controller.rb +3 -2
  39. data/app/controllers/shipit/repositories_controller.rb +74 -0
  40. data/app/controllers/shipit/rollbacks_controller.rb +3 -2
  41. data/app/controllers/shipit/shipit_controller.rb +2 -1
  42. data/app/controllers/shipit/stacks_controller.rb +78 -14
  43. data/app/controllers/shipit/status_controller.rb +2 -1
  44. data/app/controllers/shipit/tasks_controller.rb +9 -8
  45. data/app/controllers/shipit/webhooks_controller.rb +5 -132
  46. data/app/helpers/shipit/chunks_helper.rb +3 -2
  47. data/app/helpers/shipit/deploys_helper.rb +4 -3
  48. data/app/helpers/shipit/github_url_helper.rb +9 -0
  49. data/app/helpers/shipit/merge_status_helper.rb +1 -0
  50. data/app/helpers/shipit/shipit_helper.rb +1 -0
  51. data/app/helpers/shipit/stacks_helper.rb +9 -0
  52. data/app/helpers/shipit/tasks_helper.rb +1 -0
  53. data/app/jobs/shipit/background_job.rb +4 -0
  54. data/app/jobs/shipit/background_job/unique.rb +4 -1
  55. data/app/jobs/shipit/cache_deploy_spec_job.rb +1 -0
  56. data/app/jobs/shipit/chunk_rollup_job.rb +4 -0
  57. data/app/jobs/shipit/clear_git_cache_job.rb +1 -0
  58. data/app/jobs/shipit/continuous_delivery_job.rb +3 -1
  59. data/app/jobs/shipit/create_on_github_job.rb +7 -1
  60. data/app/jobs/shipit/create_release_statuses_job.rb +1 -0
  61. data/app/jobs/shipit/deferred_touch_job.rb +4 -0
  62. data/app/jobs/shipit/deliver_hook_job.rb +1 -0
  63. data/app/jobs/shipit/destroy_job.rb +1 -0
  64. data/app/jobs/shipit/destroy_repository_job.rb +24 -0
  65. data/app/jobs/shipit/destroy_stack_job.rb +5 -4
  66. data/app/jobs/shipit/emit_event_job.rb +2 -1
  67. data/app/jobs/shipit/fetch_commit_stats_job.rb +1 -0
  68. data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -0
  69. data/app/jobs/shipit/github_sync_job.rb +2 -1
  70. data/app/jobs/shipit/{mark_deploy_healty_job.rb → mark_deploy_healthy_job.rb} +1 -0
  71. data/app/jobs/shipit/perform_commit_checks_job.rb +1 -0
  72. data/app/jobs/shipit/perform_task_job.rb +5 -90
  73. data/app/jobs/shipit/process_merge_requests_job.rb +32 -0
  74. data/app/jobs/shipit/purge_old_deliveries_job.rb +1 -0
  75. data/app/jobs/shipit/reap_dead_tasks_job.rb +21 -0
  76. data/app/jobs/shipit/refresh_check_runs_job.rb +1 -0
  77. data/app/jobs/shipit/refresh_github_user_job.rb +1 -0
  78. data/app/jobs/shipit/refresh_merge_request_job.rb +11 -0
  79. data/app/jobs/shipit/refresh_statuses_job.rb +1 -0
  80. data/app/jobs/shipit/setup_github_hook_job.rb +1 -0
  81. data/app/jobs/shipit/update_estimated_deploy_duration_job.rb +1 -0
  82. data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +4 -3
  83. data/app/models/concerns/shipit/deferred_touch.rb +4 -3
  84. data/app/models/shipit/anonymous_user.rb +9 -0
  85. data/app/models/shipit/api_client.rb +3 -2
  86. data/app/models/shipit/application_record.rb +2 -1
  87. data/app/models/shipit/check_run.rb +5 -4
  88. data/app/models/shipit/command_line_user.rb +5 -0
  89. data/app/models/shipit/commit.rb +41 -22
  90. data/app/models/shipit/commit_checks.rb +2 -0
  91. data/app/models/shipit/commit_deployment.rb +17 -12
  92. data/app/models/shipit/commit_deployment_status.rb +8 -3
  93. data/app/models/shipit/commit_message.rb +1 -0
  94. data/app/models/shipit/delivery.rb +4 -3
  95. data/app/models/shipit/deploy.rb +41 -10
  96. data/app/models/shipit/deploy_spec.rb +38 -7
  97. data/app/models/shipit/deploy_spec/bundler_discovery.rb +2 -1
  98. data/app/models/shipit/deploy_spec/capistrano_discovery.rb +1 -0
  99. data/app/models/shipit/deploy_spec/file_system.rb +20 -7
  100. data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +1 -0
  101. data/app/models/shipit/deploy_spec/lerna_discovery.rb +1 -0
  102. data/app/models/shipit/deploy_spec/npm_discovery.rb +5 -4
  103. data/app/models/shipit/deploy_spec/pypi_discovery.rb +1 -0
  104. data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -0
  105. data/app/models/shipit/deploy_stats.rb +58 -0
  106. data/app/models/shipit/duration.rb +3 -2
  107. data/app/models/shipit/ephemeral_commit_checks.rb +1 -0
  108. data/app/models/shipit/github_hook.rb +2 -1
  109. data/app/models/shipit/github_status.rb +2 -1
  110. data/app/models/shipit/hook.rb +8 -5
  111. data/app/models/shipit/membership.rb +3 -2
  112. data/app/models/shipit/merge_request.rb +302 -0
  113. data/app/models/shipit/output_chunk.rb +7 -2
  114. data/app/models/shipit/provisioning_handler.rb +32 -0
  115. data/app/models/shipit/provisioning_handler/base.rb +30 -0
  116. data/app/models/shipit/provisioning_handler/unregistered_provisioning_handler.rb +35 -0
  117. data/app/models/shipit/pull_request.rb +27 -260
  118. data/app/models/shipit/pull_request_assignment.rb +10 -0
  119. data/app/models/shipit/record.rb +18 -0
  120. data/app/models/shipit/release_status.rb +3 -2
  121. data/app/models/shipit/repository.rb +97 -0
  122. data/app/models/shipit/review_stack.rb +116 -0
  123. data/app/models/shipit/review_stack_provisioning_queue.rb +39 -0
  124. data/app/models/shipit/rollback.rb +1 -0
  125. data/app/models/shipit/stack.rb +130 -57
  126. data/app/models/shipit/status.rb +3 -2
  127. data/app/models/shipit/status/common.rb +7 -6
  128. data/app/models/shipit/status/group.rb +1 -0
  129. data/app/models/shipit/status/missing.rb +2 -1
  130. data/app/models/shipit/status/unknown.rb +2 -1
  131. data/app/models/shipit/task.rb +118 -14
  132. data/app/models/shipit/task_definition.rb +1 -0
  133. data/app/models/shipit/task_execution_strategy/base.rb +20 -0
  134. data/app/models/shipit/task_execution_strategy/default.rb +110 -0
  135. data/app/models/shipit/team.rb +2 -1
  136. data/app/models/shipit/undeployed_commit.rb +1 -0
  137. data/app/models/shipit/unlimited_api_client.rb +1 -0
  138. data/app/models/shipit/user.rb +15 -8
  139. data/app/models/shipit/variable_definition.rb +1 -0
  140. data/app/models/shipit/webhooks.rb +43 -0
  141. data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +20 -0
  142. data/app/models/shipit/webhooks/handlers/handler.rb +41 -0
  143. data/app/models/shipit/webhooks/handlers/membership_handler.rb +46 -0
  144. data/app/models/shipit/webhooks/handlers/pull_request/assigned_handler.rb +74 -0
  145. data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +68 -0
  146. data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +74 -0
  147. data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +127 -0
  148. data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +106 -0
  149. data/app/models/shipit/webhooks/handlers/pull_request/opened_handler.rb +83 -0
  150. data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +88 -0
  151. data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +103 -0
  152. data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +107 -0
  153. data/app/models/shipit/webhooks/handlers/push_handler.rb +21 -0
  154. data/app/models/shipit/webhooks/handlers/status_handler.rb +27 -0
  155. data/app/serializers/concerns/shipit/conditional_attributes.rb +1 -0
  156. data/app/serializers/shipit/anonymous_user_serializer.rb +1 -0
  157. data/app/serializers/shipit/command_line_user_serializer.rb +1 -0
  158. data/app/serializers/shipit/commit_serializer.rb +1 -0
  159. data/app/serializers/shipit/deploy_serializer.rb +8 -1
  160. data/app/serializers/shipit/hook_serializer.rb +1 -0
  161. data/app/serializers/shipit/merge_request_serializer.rb +21 -0
  162. data/app/serializers/shipit/pull_request_serializer.rb +6 -8
  163. data/app/serializers/shipit/review_stack_serializer.rb +7 -0
  164. data/app/serializers/shipit/rollback_serializer.rb +1 -0
  165. data/app/serializers/shipit/short_commit_serializer.rb +1 -0
  166. data/app/serializers/shipit/stack_serializer.rb +12 -5
  167. data/app/serializers/shipit/tail_task_serializer.rb +11 -2
  168. data/app/serializers/shipit/task_serializer.rb +2 -17
  169. data/app/serializers/shipit/user_serializer.rb +6 -1
  170. data/app/validators/ascii_only_validator.rb +4 -3
  171. data/app/validators/subset_validator.rb +1 -0
  172. data/app/views/layouts/_head.html.erb +0 -0
  173. data/app/views/layouts/shipit.html.erb +5 -3
  174. data/app/views/shipit/_variables.html.erb +1 -1
  175. data/app/views/shipit/api_clients/index.html.erb +36 -0
  176. data/app/views/shipit/api_clients/new.html.erb +33 -0
  177. data/app/views/shipit/api_clients/show.html.erb +35 -0
  178. data/app/views/shipit/ccmenu/project.xml.builder +2 -1
  179. data/app/views/shipit/deploys/show.html.erb +2 -2
  180. data/app/views/shipit/merge_requests/_merge_request.html.erb +29 -0
  181. data/app/views/shipit/{pull_requests → merge_requests}/index.html.erb +2 -2
  182. data/app/views/shipit/merge_requests/merge_requests/_pull_request.html.erb +29 -0
  183. data/app/views/shipit/merge_requests/merge_requests/index.html.erb +20 -0
  184. data/app/views/shipit/merge_status/_merge_queue_button.html.erb +3 -3
  185. data/app/views/shipit/merge_status/backlogged.html.erb +1 -1
  186. data/app/views/shipit/merge_status/failure.html.erb +1 -1
  187. data/app/views/shipit/merge_status/locked.html.erb +1 -1
  188. data/app/views/shipit/merge_status/logged_out.erb +1 -1
  189. data/app/views/shipit/merge_status/success.html.erb +2 -2
  190. data/app/views/shipit/repositories/_header.html.erb +19 -0
  191. data/app/views/shipit/repositories/index.html.erb +31 -0
  192. data/app/views/shipit/repositories/new.html.erb +23 -0
  193. data/app/views/shipit/repositories/settings.html.erb +53 -0
  194. data/app/views/shipit/repositories/show.html.erb +30 -0
  195. data/app/views/shipit/stacks/_banners.html.erb +13 -0
  196. data/app/views/shipit/stacks/_header.html.erb +30 -12
  197. data/app/views/shipit/stacks/_links.html.erb +1 -0
  198. data/app/views/shipit/stacks/_stack.html.erb +8 -0
  199. data/app/views/shipit/stacks/all_tasks.html.erb +28 -0
  200. data/app/views/shipit/stacks/index.html.erb +9 -3
  201. data/app/views/shipit/stacks/settings.html.erb +22 -3
  202. data/app/views/shipit/stacks/show.html.erb +1 -1
  203. data/app/views/shipit/stacks/statistics.html.erb +82 -0
  204. data/app/views/shipit/tasks/_task_output.html.erb +1 -1
  205. data/app/views/shipit/tasks/show.html.erb +1 -1
  206. data/config/initializers/inflections.rb +2 -1
  207. data/config/locales/en.yml +18 -5
  208. data/config/routes.rb +29 -7
  209. data/db/migrate/20191209231045_create_shipit_repositories.rb +12 -0
  210. data/db/migrate/20191209231307_add_repository_reference_to_stacks.rb +15 -0
  211. data/db/migrate/20191216162728_backfill_repository_data.rb +22 -0
  212. data/db/migrate/20191216163010_remove_repository_information_from_stacks.rb +20 -0
  213. data/db/migrate/20191219205202_add_archived_since_to_stacks.rb +6 -0
  214. data/db/migrate/20200102175621_optional_task_commits.rb +6 -0
  215. data/db/migrate/20200109132519_add_sha_to_commit_deployments.rb +5 -0
  216. data/db/migrate/20200226211925_add_index_to_tasks_status.rb +5 -0
  217. data/db/migrate/20200427135152_add_pull_request_head_sha_to_commit.rb +5 -0
  218. data/db/migrate/20200615181558_add_rollback_once_aborted_to.rb +5 -0
  219. data/db/migrate/20200706145406_add_review_stacks.rb +12 -0
  220. data/db/migrate/20200804144639_rename_pull_request_to_merge_request.rb +7 -0
  221. data/db/migrate/20200804161512_rename_commits_pull_request_id_to_merge_request_id.rb +5 -0
  222. data/db/migrate/20200813134712_recreate_shipit_pull_requests.rb +22 -0
  223. data/db/migrate/20200813194056_create_pull_request_assignments.rb +8 -0
  224. data/db/migrate/20201001125502_add_provision_pr_stacks_flag_to_repositories.rb +7 -0
  225. data/db/migrate/20201008145809_add_retry_attempt_to_tasks.rb +5 -0
  226. data/db/migrate/20201008152744_add_max_retries_to_tasks.rb +5 -0
  227. data/lib/shipit.rb +23 -3
  228. data/lib/shipit/cast_value.rb +1 -0
  229. data/lib/shipit/command.rb +14 -18
  230. data/lib/shipit/commands.rb +5 -4
  231. data/lib/shipit/csv_serializer.rb +1 -0
  232. data/lib/shipit/deploy_commands.rb +1 -0
  233. data/lib/shipit/engine.rb +11 -2
  234. data/lib/shipit/environment_variables.rb +11 -1
  235. data/lib/shipit/first_parent_commits_iterator.rb +1 -0
  236. data/lib/shipit/flock.rb +1 -0
  237. data/lib/shipit/github_app.rb +41 -10
  238. data/lib/shipit/github_http_cache_middleware.rb +1 -0
  239. data/lib/shipit/null_serializer.rb +1 -0
  240. data/lib/shipit/octokit_check_runs.rb +3 -2
  241. data/lib/shipit/octokit_iterator.rb +3 -2
  242. data/lib/shipit/paginator.rb +3 -2
  243. data/lib/shipit/review_stack_commands.rb +8 -0
  244. data/lib/shipit/rollback_commands.rb +1 -0
  245. data/lib/shipit/same_site_cookie_middleware.rb +29 -0
  246. data/lib/shipit/simple_message_verifier.rb +1 -0
  247. data/lib/shipit/stack_commands.rb +12 -4
  248. data/lib/shipit/stat.rb +1 -0
  249. data/lib/shipit/task_commands.rb +23 -14
  250. data/lib/shipit/version.rb +2 -1
  251. data/lib/snippets/release-gem +5 -1
  252. data/lib/tasks/cron.rake +13 -2
  253. data/lib/tasks/dev.rake +3 -2
  254. data/lib/tasks/shipit.rake +16 -17
  255. data/lib/tasks/teams.rake +1 -0
  256. data/test/controllers/api/base_controller_test.rb +3 -2
  257. data/test/controllers/api/ccmenu_controller_test.rb +9 -8
  258. data/test/controllers/api/commits_controller_test.rb +3 -2
  259. data/test/controllers/api/deploys_controller_test.rb +15 -14
  260. data/test/controllers/api/hooks_controller_test.rb +8 -7
  261. data/test/controllers/api/locks_controller_test.rb +7 -6
  262. data/test/controllers/api/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +17 -16
  263. data/test/controllers/api/outputs_controller_test.rb +4 -2
  264. data/test/controllers/api/release_statuses_controller_test.rb +2 -1
  265. data/test/controllers/api/rollback_controller_test.rb +113 -0
  266. data/test/controllers/api/stacks_controller_test.rb +65 -16
  267. data/test/controllers/api/tasks_controller_test.rb +13 -12
  268. data/test/controllers/api_clients_controller_test.rb +104 -0
  269. data/test/controllers/ccmenu_controller_test.rb +4 -3
  270. data/test/controllers/commit_checks_controller_test.rb +4 -3
  271. data/test/controllers/commits_controller_test.rb +3 -2
  272. data/test/controllers/deploys_controller_test.rb +33 -22
  273. data/test/controllers/github_authentication_controller_test.rb +1 -0
  274. data/test/controllers/merge_requests_controller_test.rb +32 -0
  275. data/test/controllers/merge_status_controller_test.rb +27 -9
  276. data/test/controllers/release_statuses_controller_test.rb +3 -2
  277. data/test/controllers/repositories_controller_test.rb +71 -0
  278. data/test/controllers/rollbacks_controller_test.rb +9 -8
  279. data/test/controllers/stacks_controller_test.rb +72 -15
  280. data/test/controllers/status_controller_test.rb +1 -0
  281. data/test/controllers/tasks_controller_test.rb +33 -20
  282. data/test/controllers/webhooks_controller_test.rb +36 -9
  283. data/test/dummy/config/application.rb +7 -2
  284. data/test/dummy/config/environments/development.rb +23 -6
  285. data/test/dummy/config/environments/test.rb +2 -5
  286. data/test/dummy/db/schema.rb +76 -24
  287. data/test/dummy/db/seeds.rb +30 -16
  288. data/test/fixtures/payloads/check_suite_master.json +2 -2
  289. data/test/fixtures/payloads/invalid_pull_request.json +117 -0
  290. data/test/fixtures/payloads/provision_disabled_pull_request.json +454 -0
  291. data/test/fixtures/payloads/pull_request_assigned.json +480 -0
  292. data/test/fixtures/payloads/pull_request_closed.json +454 -0
  293. data/test/fixtures/payloads/pull_request_labeled.json +461 -0
  294. data/test/fixtures/payloads/pull_request_opened.json +454 -0
  295. data/test/fixtures/payloads/pull_request_reopened.json +454 -0
  296. data/test/fixtures/payloads/pull_request_unlabeled.json +454 -0
  297. data/test/fixtures/payloads/pull_request_with_no_repo.json +454 -0
  298. data/test/fixtures/shipit/commit_deployment_statuses.yml +4 -4
  299. data/test/fixtures/shipit/commit_deployments.yml +8 -8
  300. data/test/fixtures/shipit/commits.yml +52 -1
  301. data/test/fixtures/shipit/merge_requests.yml +141 -0
  302. data/test/fixtures/shipit/pull_request_assignments.yml +3 -0
  303. data/test/fixtures/shipit/pull_requests.yml +10 -131
  304. data/test/fixtures/shipit/repositories.yml +28 -0
  305. data/test/fixtures/shipit/stacks.yml +335 -30
  306. data/test/fixtures/shipit/statuses.yml +9 -0
  307. data/test/fixtures/shipit/tasks.yml +69 -3
  308. data/test/fixtures/shipit/users.yml +7 -0
  309. data/test/fixtures/timeout +2 -1
  310. data/test/helpers/api_helper.rb +1 -0
  311. data/test/helpers/fixture_aliases_helper.rb +1 -0
  312. data/test/helpers/hooks_helper.rb +2 -1
  313. data/test/helpers/json_helper.rb +15 -11
  314. data/test/helpers/links_helper.rb +4 -3
  315. data/test/helpers/payloads_helper.rb +5 -0
  316. data/test/helpers/queries_helper.rb +3 -2
  317. data/test/jobs/cache_deploy_spec_job_test.rb +2 -1
  318. data/test/jobs/chunk_rollup_job_test.rb +16 -1
  319. data/test/jobs/deliver_hook_job_test.rb +1 -0
  320. data/test/jobs/destroy_repository_job_test.rb +27 -0
  321. data/test/jobs/destroy_stack_job_test.rb +10 -0
  322. data/test/jobs/emit_event_job_test.rb +2 -1
  323. data/test/jobs/fetch_commit_stats_job_test.rb +1 -0
  324. data/test/jobs/fetch_deployed_revision_job_test.rb +1 -0
  325. data/test/jobs/github_sync_job_test.rb +1 -0
  326. data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
  327. data/test/jobs/perform_task_job_test.rb +12 -11
  328. data/test/jobs/{merge_pull_requests_job_test.rb → process_merge_requests_job_test.rb} +19 -18
  329. data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
  330. data/test/jobs/reap_dead_tasks_job_test.rb +68 -0
  331. data/test/jobs/refresh_github_user_job_test.rb +1 -0
  332. data/test/jobs/refresh_status_job_test.rb +1 -0
  333. data/test/jobs/unique_job_test.rb +1 -0
  334. data/test/jobs/update_github_last_deployed_ref_job_test.rb +1 -0
  335. data/test/lib/shipit/deploy_commands_test.rb +16 -0
  336. data/test/lib/shipit/task_commands_test.rb +17 -0
  337. data/test/middleware/same_site_cookie_middleware_test.rb +52 -0
  338. data/test/models/api_client_test.rb +1 -0
  339. data/test/models/commit_checks_test.rb +1 -0
  340. data/test/models/commit_deployment_status_test.rb +34 -4
  341. data/test/models/commit_deployment_test.rb +9 -11
  342. data/test/models/commits_test.rb +116 -21
  343. data/test/models/delivery_test.rb +2 -1
  344. data/test/models/deploy_spec_test.rb +103 -65
  345. data/test/models/deploy_stats_test.rb +113 -0
  346. data/test/models/deploys_test.rb +207 -26
  347. data/test/models/duration_test.rb +1 -0
  348. data/test/models/github_hook_test.rb +1 -0
  349. data/test/models/hook_test.rb +20 -16
  350. data/test/models/membership_test.rb +1 -0
  351. data/test/models/{pull_request_test.rb → merge_request_test.rb} +48 -41
  352. data/test/models/pull_request_assignment_test.rb +16 -0
  353. data/test/models/release_statuses_test.rb +1 -0
  354. data/test/models/rollbacks_test.rb +1 -0
  355. data/test/models/shipit/check_run_test.rb +1 -0
  356. data/test/models/shipit/provisioning_handler/base_test.rb +33 -0
  357. data/test/models/shipit/provisioning_handler/unregistered_provisioning_handler_test.rb +49 -0
  358. data/test/models/shipit/provisioning_handler_test.rb +64 -0
  359. data/test/models/shipit/pull_request_test.rb +52 -0
  360. data/test/models/shipit/repository_test.rb +81 -0
  361. data/test/models/shipit/review_stack_provision_status_test.rb +77 -0
  362. data/test/models/shipit/review_stack_provisioning_queue_test.rb +63 -0
  363. data/test/models/shipit/review_stack_test.rb +59 -0
  364. data/test/models/{stacks_test.rb → shipit/stacks_test.rb} +120 -60
  365. data/test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb +45 -0
  366. data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +192 -0
  367. data/test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb +47 -0
  368. data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +209 -0
  369. data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +332 -0
  370. data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +238 -0
  371. data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +282 -0
  372. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +83 -0
  373. data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +324 -0
  374. data/test/models/shipit/webhooks/handlers_test.rb +27 -0
  375. data/test/models/status/group_test.rb +1 -0
  376. data/test/models/status/missing_test.rb +1 -0
  377. data/test/models/status_test.rb +1 -0
  378. data/test/models/task_definitions_test.rb +9 -8
  379. data/test/models/tasks_test.rb +59 -1
  380. data/test/models/team_test.rb +4 -2
  381. data/test/models/undeployed_commits_test.rb +14 -0
  382. data/test/models/users_test.rb +13 -5
  383. data/test/serializers/shipit/pull_request_serializer_test.rb +29 -0
  384. data/test/test_command_integration.rb +3 -2
  385. data/test/test_helper.rb +37 -32
  386. data/test/unit/anonymous_user_serializer_test.rb +14 -0
  387. data/test/unit/command_test.rb +15 -10
  388. data/test/unit/commands_test.rb +1 -0
  389. data/test/unit/commit_serializer_test.rb +16 -0
  390. data/test/unit/csv_serializer_test.rb +3 -2
  391. data/test/unit/deploy_commands_test.rb +14 -4
  392. data/test/unit/deploy_serializer_test.rb +17 -0
  393. data/test/unit/environment_variables_test.rb +5 -4
  394. data/test/unit/github_app_test.rb +137 -0
  395. data/test/unit/github_url_helper_test.rb +6 -0
  396. data/test/unit/rollback_commands_test.rb +2 -1
  397. data/test/unit/shipit_helper_test.rb +17 -0
  398. data/test/unit/shipit_task_execution_strategy_test.rb +47 -0
  399. data/test/unit/shipit_test.rb +1 -0
  400. data/test/unit/user_serializer_test.rb +14 -0
  401. data/test/unit/variable_definition_test.rb +1 -0
  402. metadata +334 -169
  403. data/app/controllers/shipit/api/pull_requests_controller.rb +0 -36
  404. data/app/controllers/shipit/pull_requests_controller.rb +0 -30
  405. data/app/jobs/shipit/merge_pull_requests_job.rb +0 -31
  406. data/app/jobs/shipit/refresh_pull_request_job.rb +0 -10
  407. data/app/views/shipit/pull_requests/_pull_request.html.erb +0 -29
  408. data/test/controllers/pull_requests_controller_test.rb +0 -31
  409. data/test/fixtures/shipit/output_chunks.yml +0 -47
  410. data/test/models/output_chunk_test.rb +0 -20
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class FirstParentCommitsIterator < OctokitIterator
3
4
  def each
data/lib/shipit/flock.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'English'
2
3
  require 'timeout'
3
4
  require 'pathname'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class GitHubApp
3
4
  include Mutex_m
@@ -9,6 +10,8 @@ module Shipit
9
10
  end
10
11
  end
11
12
 
13
+ attr_reader :expires_at, :refresh_at
14
+
12
15
  def to_s
13
16
  @token
14
17
  end
@@ -16,16 +19,26 @@ module Shipit
16
19
  def initialize(token, expires_at)
17
20
  @token = token
18
21
  @expires_at = expires_at
22
+
23
+ # This needs to be lower than the token's lifetime, but higher than the cache expiry setting.
24
+ @refresh_at = expires_at - GITHUB_TOKEN_REFRESH_WINDOW
19
25
  end
20
26
 
21
27
  def blank?
22
- @expires_at.past?
28
+ # Old tokens missing @refresh_at may be used upon deploy, so we should auto-correct for now.
29
+ # TODO: Remove this assignment at a later date.
30
+ @refresh_at ||= @expires_at - GITHUB_TOKEN_REFRESH_WINDOW
31
+ @refresh_at.past?
23
32
  end
24
33
  end
25
34
 
26
- DOMAIN = 'github.com'.freeze
35
+ DOMAIN = 'github.com'
27
36
  AuthenticationFailed = Class.new(StandardError)
28
- API_STATUS_ID = 'brv1bkgrwx7q'.freeze
37
+ API_STATUS_ID = 'brv1bkgrwx7q'
38
+
39
+ GITHUB_EXPECTED_TOKEN_LIFETIME = 60.minutes
40
+ GITHUB_TOKEN_RAILS_CACHE_LIFETIME = 50.minutes
41
+ GITHUB_TOKEN_REFRESH_WINDOW = GITHUB_EXPECTED_TOKEN_LIFETIME - GITHUB_TOKEN_RAILS_CACHE_LIFETIME - 2.minutes
29
42
 
30
43
  attr_reader :oauth_teams, :domain, :bot_login
31
44
 
@@ -39,7 +52,7 @@ module Shipit
39
52
  oauth = (@config[:oauth] || {}).with_indifferent_access
40
53
  @oauth_id = oauth[:id]
41
54
  @oauth_secret = oauth[:secret]
42
- @oauth_teams = Array.wrap(oauth[:teams] || oauth[:teams])
55
+ @oauth_teams = Array.wrap(oauth[:teams])
43
56
  end
44
57
 
45
58
  def login
@@ -79,13 +92,21 @@ module Shipit
79
92
  end
80
93
 
81
94
  def fetch_new_token
82
- Rails.cache.fetch('github:integration:access-token', expires_in: 50.minutes, race_condition_ttl: 10.minutes) do
95
+ # Rails can add 5 minutes to the cache entry expiration time when any TTL is provided,
96
+ # so our TTL setting can be lower, and TTL + expires_in should be lower than the GitHub token expiration.
97
+ Rails.cache.fetch(
98
+ 'github:integration:access-token',
99
+ expires_in: GITHUB_TOKEN_RAILS_CACHE_LIFETIME,
100
+ race_condition_ttl: 4.minutes,
101
+ ) do
83
102
  response = new_client(bearer_token: authentication_payload).create_app_installation_access_token(
84
103
  installation_id,
85
104
  accept: 'application/vnd.github.machine-man-preview+json',
86
105
  )
87
106
  token = Token.from_github(response)
88
107
  raise AuthenticationFailed if token.blank?
108
+ Rails.logger.info("Created GitHub access token ending #{token.to_s[-5..-1]}, expires at #{token.expires_at}"\
109
+ " and will be refreshed at #{token&.refresh_at}")
89
110
  token
90
111
  end
91
112
  end
@@ -112,7 +133,7 @@ module Shipit
112
133
  end
113
134
 
114
135
  def url(*path)
115
- @url ||= "https://#{domain}".freeze
136
+ @url ||= "https://#{domain}"
116
137
  path.empty? ? @url : File.join(@url, *path.map(&:to_s))
117
138
  end
118
139
 
@@ -120,12 +141,22 @@ module Shipit
120
141
  url('/api/v3/') if enterprise?
121
142
  end
122
143
 
144
+ def web_endpoint
145
+ url if enterprise?
146
+ end
147
+
123
148
  def enterprise?
124
149
  domain != DOMAIN
125
150
  end
126
151
 
127
152
  def new_client(options = {})
128
- client = Octokit::Client.new(options.reverse_merge(api_endpoint: api_endpoint))
153
+ if enterprise?
154
+ options = options.reverse_merge(
155
+ api_endpoint: api_endpoint,
156
+ web_endpoint: web_endpoint,
157
+ )
158
+ end
159
+ client = Octokit::Client.new(options)
129
160
  client.middleware = faraday_stack
130
161
  client
131
162
  end
@@ -143,9 +174,9 @@ module Shipit
143
174
  logger: Rails.logger,
144
175
  serializer: NullSerializer,
145
176
  )
146
- builder.use GitHubHTTPCacheMiddleware
147
- builder.use Octokit::Response::RaiseError
148
- builder.adapter Faraday.default_adapter
177
+ builder.use(GitHubHTTPCacheMiddleware)
178
+ builder.use(Octokit::Response::RaiseError)
179
+ builder.adapter(Faraday.default_adapter)
149
180
  end
150
181
  end
151
182
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class GitHubHTTPCacheMiddleware < Faraday::Middleware
3
4
  def call(request_env)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  module NullSerializer
3
4
  extend self
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module OctokitCheckRuns
2
3
  def check_runs(repo, sha, options = {})
3
- paginate "#{Octokit::Repository.path repo}/commits/#{sha}/check-runs", options.reverse_merge(
4
+ paginate("#{Octokit::Repository.path(repo)}/commits/#{sha}/check-runs", options.reverse_merge(
4
5
  accept: 'application/vnd.github.antiope-preview+json',
5
- )
6
+ ))
6
7
  end
7
8
  end
8
9
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class OctokitIterator
3
4
  include Enumerable
@@ -6,8 +7,8 @@ module Shipit
6
7
  if relation
7
8
  @response = relation.get(per_page: 100)
8
9
  else
9
- yield Shipit.github.api
10
- @response = Shipit.github.api.last_response
10
+ data = yield Shipit.github.api
11
+ @response = Shipit.github.api.last_response if data.present?
11
12
  end
12
13
  end
13
14
 
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class Paginator
3
- def initialize(resources, controller, order: {id: :desc}, max_page_size: 100, default_page_size: 30)
4
+ def initialize(resources, controller, order: { id: :desc }, max_page_size: 100, default_page_size: 30)
4
5
  @order = order
5
6
  @controller = controller
6
7
  @since = controller.params[:since].presence
@@ -15,7 +16,7 @@ module Shipit
15
16
  end
16
17
 
17
18
  def links
18
- links = {first: link_to(since: nil, page_size: (page_size if page_size != @default_page_size))}
19
+ links = { first: link_to(since: nil, page_size: (page_size if page_size != @default_page_size)) }
19
20
  links[:next] = link_to(since: to_a.last.id) unless last_page?
20
21
  links
21
22
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shipit/stack_commands'
4
+
5
+ module Shipit
6
+ class ReviewStackCommands < Shipit::StackCommands
7
+ end
8
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class RollbackCommands < DeployCommands
3
4
  def steps
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ module Shipit
3
+ class SameSiteCookieMiddleware
4
+ COOKIE_SEPARATOR = "\n"
5
+
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ status, headers, body = @app.call(env)
12
+
13
+ if headers && headers['Set-Cookie'] &&
14
+ Rack::Request.new(env).ssl?
15
+
16
+ set_cookies = headers['Set-Cookie'].split(COOKIE_SEPARATOR).compact
17
+ set_cookies.map! do |cookie|
18
+ cookie << '; Secure' if cookie !~ /;\s*secure/i
19
+ cookie << '; SameSite=None' unless cookie.match?(/;\s*samesite=/i)
20
+ cookie
21
+ end
22
+
23
+ headers['Set-Cookie'] = set_cookies.join(COOKIE_SEPARATOR)
24
+ end
25
+
26
+ [status, headers, body]
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  class SimpleMessageVerifier < ActiveSupport::MessageVerifier
3
4
  def initialize(secret, options = {})
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Lint/MissingSuper
1
3
  require 'pathname'
2
4
  require 'fileutils'
3
5
 
@@ -7,6 +9,10 @@ module Shipit
7
9
  @stack = stack
8
10
  end
9
11
 
12
+ def env
13
+ super.merge(@stack.env)
14
+ end
15
+
10
16
  def fetch
11
17
  create_directories
12
18
  if Dir.exist?(@stack.git_path)
@@ -26,7 +32,7 @@ module Shipit
26
32
  end
27
33
 
28
34
  def fetch_deployed_revision
29
- with_temporary_working_directory(commit: @stack.commits.last) do |dir|
35
+ with_temporary_working_directory(commit: @stack.commits.reachable.last) do |dir|
30
36
  spec = DeploySpec::FileSystem.new(dir, @stack.environment)
31
37
  outputs = spec.fetch_deployed_revision_steps!.map do |command_line|
32
38
  Command.new(command_line, env: env, chdir: dir).run
@@ -42,18 +48,20 @@ module Shipit
42
48
  end
43
49
 
44
50
  def with_temporary_working_directory(commit: nil)
45
- commit ||= @stack.last_deployed_commit.presence || @stack.commits.last
51
+ commit ||= @stack.last_deployed_commit.presence || @stack.commits.reachable.last
46
52
 
47
53
  if !commit || !fetched?(commit).tap(&:run).success?
48
54
  @stack.acquire_git_cache_lock do
49
- fetch.run!
55
+ unless fetched?(commit).tap(&:run).success?
56
+ fetch.run!
57
+ end
50
58
  end
51
59
  end
52
60
 
53
61
  Dir.mktmpdir do |dir|
54
62
  git(
55
63
  'clone', @stack.git_path, @stack.repo_name,
56
- '--origin', 'cache',
64
+ '--recursive', '--origin', 'cache',
57
65
  chdir: dir
58
66
  ).run!
59
67
 
data/lib/shipit/stat.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
3
  module Stat
3
4
  extend self
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Lint/MissingSuper
1
3
  module Shipit
2
4
  class TaskCommands < Commands
3
5
  delegate :fetch, :fetched?, to: :stack_commands
@@ -28,20 +30,20 @@ module Shipit
28
30
  end
29
31
 
30
32
  def env
31
- normalized_name = ActiveSupport::Inflector.transliterate(@task.author.name)
32
- super.merge(
33
- 'ENVIRONMENT' => @stack.environment,
34
- 'BRANCH' => @stack.branch,
35
- 'SHIPIT_USER' => "#{@task.author.login} (#{normalized_name}) via Shipit",
36
- 'EMAIL' => @task.author.email,
37
- 'BUNDLE_PATH' => Rails.root.join('data', 'bundler').to_s,
38
- 'SHIPIT_LINK' => @task.permalink,
39
- 'LAST_DEPLOYED_SHA' => @stack.last_deployed_commit.sha,
40
- 'TASK_ID' => @task.id.to_s,
41
- 'IGNORED_SAFETIES' => @task.ignored_safeties? ? '1' : '0',
42
- 'GIT_COMMITTER_NAME' => @task.user&.name || Shipit.committer_name,
43
- 'GIT_COMMITTER_EMAIL' => @task.user&.email || Shipit.committer_email,
44
- ).merge(deploy_spec.machine_env).merge(@task.env)
33
+ super
34
+ .merge(@stack.env)
35
+ .merge(
36
+ 'SHIPIT_USER' => "#{@task.author.login} (#{normalized_author_name}) via Shipit",
37
+ 'EMAIL' => @task.author.email,
38
+ 'BUNDLE_PATH' => Rails.root.join('data', 'bundler').to_s,
39
+ 'SHIPIT_LINK' => @task.permalink,
40
+ 'TASK_ID' => @task.id.to_s,
41
+ 'IGNORED_SAFETIES' => @task.ignored_safeties? ? '1' : '0',
42
+ 'GIT_COMMITTER_NAME' => @task.user&.name || Shipit.committer_name,
43
+ 'GIT_COMMITTER_EMAIL' => @task.user&.email || Shipit.committer_email,
44
+ )
45
+ .merge(deploy_spec.machine_env)
46
+ .merge(@task.env)
45
47
  end
46
48
 
47
49
  def checkout(commit)
@@ -52,6 +54,7 @@ module Shipit
52
54
  [
53
55
  git(
54
56
  'clone',
57
+ '--quiet',
55
58
  '--local',
56
59
  '--origin', 'cache',
57
60
  @stack.git_path,
@@ -70,6 +73,12 @@ module Shipit
70
73
  FileUtils.rm_rf(@task.working_directory) if deploy_spec.clear_working_directory?
71
74
  end
72
75
 
76
+ private
77
+
78
+ def normalized_author_name
79
+ ActiveSupport::Inflector.transliterate(@task.author.name)
80
+ end
81
+
73
82
  protected
74
83
 
75
84
  def steps_directory
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Shipit
2
- VERSION = '0.28.1'.freeze
3
+ VERSION = '0.33.0'
3
4
  end
@@ -50,8 +50,12 @@ spec = Gem::Specification.load(spec_path)
50
50
  if RubygemsAPI.published?(spec.name, spec.version)
51
51
  puts "#{spec.name} version #{spec.version} is already published."
52
52
  exit 0
53
+ elsif !spec.metadata['allowed_push_host']
54
+ puts "Can't release the gem: spec.metadata['allowed_push_host'] must be defined."
55
+ exit 1
53
56
  else
54
- Git.tag_and_push(spec.version) do
57
+ is_successful = Git.tag_and_push(spec.version) do
55
58
  system(*release_command)
56
59
  end
60
+ is_successful ? exit(0) : exit(1)
57
61
  end
data/lib/tasks/cron.rake CHANGED
@@ -1,13 +1,16 @@
1
+ # frozen_string_literal: true
1
2
  namespace :cron do
2
3
  desc "Updates deployed revisions"
3
4
  task minutely: :environment do
4
5
  Shipit::Stack.refresh_deployed_revisions
5
6
  Shipit::Stack.schedule_continuous_delivery
6
7
  Shipit::GithubStatus.refresh_status
7
- Shipit::PullRequest.schedule_merges
8
+ Shipit::MergeRequest.schedule_merges
9
+ Shipit::ReapDeadTasksJob.perform_later
10
+ Shipit::ReviewStackProvisioningQueue.work
8
11
  end
9
12
 
10
- task hourly: %i(rollup refresh_users)
13
+ task hourly: %i(rollup refresh_users clear_stale_caches delete_old_deployment_directories)
11
14
 
12
15
  desc "Rolls-up output chunks for completed deploys older than an hour"
13
16
  task rollup: :environment do
@@ -17,4 +20,12 @@ namespace :cron do
17
20
  task refresh_users: :environment do
18
21
  Shipit::User.refresh_shard(Time.now.hour % 24, 24)
19
22
  end
23
+
24
+ task clear_stale_caches: :environment do
25
+ Shipit::ReviewStack.clear_stale_caches
26
+ end
27
+
28
+ task delete_old_deployment_directories: :environment do
29
+ Shipit::ReviewStack.delete_old_deployment_directories
30
+ end
20
31
  end
data/lib/tasks/dev.rake CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  namespace :dev do
2
3
  desc "Appends chunks to the last deploy, or specify with DEPLOY=id"
3
4
  task stream: :environment do
@@ -11,7 +12,7 @@ namespace :dev do
11
12
 
12
13
  deploy.update_attribute(:output, nil)
13
14
 
14
- logger.info "Starting to stream data to deploy ##{deploy.id}"
15
+ logger.info("Starting to stream data to deploy ##{deploy.id}")
15
16
 
16
17
  loop do
17
18
  sentence = Faker::Lorem.sentence.split.map do |word|
@@ -22,7 +23,7 @@ namespace :dev do
22
23
  end
23
24
  end.join(' ')
24
25
 
25
- logger.error sentence
26
+ logger.error(sentence)
26
27
 
27
28
  deploy.chunks.create(text: sentence + "\n")
28
29
  sleep 1
@@ -1,27 +1,26 @@
1
+ # frozen_string_literal: true
1
2
  namespace :shipit do
2
3
  desc "Deploy from a running instance. "
3
4
  task deploy: :environment do
4
- begin
5
- stack = ENV['stack']
6
- revision = ENV['revision']
5
+ stack = ENV['stack']
6
+ revision = ENV['revision']
7
7
 
8
- raise ArgumentError.new('The first argument has to be a stack, e.g. shopify/shipit/production') if stack.nil?
9
- raise ArgumentError.new('The second argument has to be a revision') if revision.nil?
8
+ raise ArgumentError, 'The first argument has to be a stack, e.g. shopify/shipit/production' if stack.nil?
9
+ raise ArgumentError, 'The second argument has to be a revision' if revision.nil?
10
10
 
11
- module Shipit
12
- class Task
13
- def write(text)
14
- p text
15
- chunks.create!(text: text)
16
- end
11
+ module Shipit
12
+ class Task
13
+ def write(text)
14
+ p(text)
15
+ chunks.create!(text: text)
17
16
  end
18
17
  end
19
-
20
- Shipit::Stack.run_deploy_in_foreground(stack: stack, revision: revision)
21
- rescue ArgumentError
22
- p "Use this command as follows:"
23
- p "bundle exec rake shipit:deploy stack='shopify/shipit/production' revision='$SHA'"
24
- raise
25
18
  end
19
+
20
+ Shipit::Stack.run_deploy_in_foreground(stack: stack, revision: revision)
21
+ rescue ArgumentError
22
+ p("Use this command as follows:")
23
+ p("bundle exec rake shipit:deploy stack='shopify/shipit/production' revision='$SHA'")
24
+ raise
26
25
  end
27
26
  end