shipit-engine 0.31.0 → 0.35.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 (411) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -4
  3. data/Rakefile +4 -2
  4. data/app/assets/images/magic-solid.svg +1 -0
  5. data/app/assets/javascripts/shipit/repositories_search.js.coffee +60 -0
  6. data/app/assets/javascripts/shipit/{search.js.coffee → stack_search.js.coffee} +0 -0
  7. data/app/assets/stylesheets/_pages/_deploy.scss +2 -3
  8. data/app/assets/stylesheets/_pages/_repositories.scss +148 -0
  9. data/app/assets/stylesheets/_pages/_stacks.scss +19 -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 +1 -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 +6 -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 +34 -0
  28. data/app/controllers/shipit/api/stacks_controller.rb +32 -5
  29. data/app/controllers/shipit/api/tasks_controller.rb +6 -5
  30. data/app/controllers/shipit/api_clients_controller.rb +4 -3
  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 +4 -3
  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 +31 -30
  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 +24 -9
  43. data/app/controllers/shipit/status_controller.rb +2 -1
  44. data/app/controllers/shipit/tasks_controller.rb +7 -6
  45. data/app/controllers/shipit/webhooks_controller.rb +26 -6
  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 -1
  51. data/app/helpers/shipit/stacks_helper.rb +5 -0
  52. data/app/helpers/shipit/tasks_helper.rb +1 -0
  53. data/app/jobs/shipit/background_job/unique.rb +1 -0
  54. data/app/jobs/shipit/background_job.rb +4 -0
  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 +2 -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 +2 -1
  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 +3 -2
  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 +15 -10
  70. data/app/jobs/shipit/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 -92
  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 +5 -4
  83. data/app/models/concerns/shipit/deferred_touch.rb +4 -3
  84. data/app/models/shipit/anonymous_user.rb +15 -2
  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 +41 -4
  88. data/app/models/shipit/command_line_user.rb +5 -0
  89. data/app/models/shipit/commit.rb +42 -24
  90. data/app/models/shipit/commit_checks.rb +15 -13
  91. data/app/models/shipit/commit_deployment.rb +6 -5
  92. data/app/models/shipit/commit_deployment_status.rb +5 -4
  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 +23 -28
  96. data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -0
  97. data/app/models/shipit/deploy_spec/capistrano_discovery.rb +1 -0
  98. data/app/models/shipit/deploy_spec/file_system.rb +20 -7
  99. data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +1 -0
  100. data/app/models/shipit/deploy_spec/lerna_discovery.rb +13 -4
  101. data/app/models/shipit/deploy_spec/npm_discovery.rb +5 -4
  102. data/app/models/shipit/deploy_spec/pypi_discovery.rb +1 -0
  103. data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -0
  104. data/app/models/shipit/deploy_spec.rb +38 -7
  105. data/app/models/shipit/deploy_stats.rb +2 -1
  106. data/app/models/shipit/duration.rb +5 -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 +34 -7
  111. data/app/models/shipit/membership.rb +3 -2
  112. data/app/models/shipit/merge_request.rb +304 -0
  113. data/app/models/shipit/output_chunk.rb +7 -2
  114. data/app/models/shipit/provisioning_handler/base.rb +30 -0
  115. data/app/models/shipit/provisioning_handler/unregistered_provisioning_handler.rb +35 -0
  116. data/app/models/shipit/provisioning_handler.rb +32 -0
  117. data/app/models/shipit/pull_request.rb +28 -266
  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 +4 -3
  121. data/app/models/shipit/repository.rb +71 -6
  122. data/app/models/shipit/review_stack.rb +130 -0
  123. data/app/models/shipit/review_stack_provisioning_queue.rb +39 -0
  124. data/app/models/shipit/rollback.rb +6 -0
  125. data/app/models/shipit/stack.rb +127 -45
  126. data/app/models/shipit/status/common.rb +7 -6
  127. data/app/models/shipit/status/group.rb +2 -1
  128. data/app/models/shipit/status/missing.rb +2 -1
  129. data/app/models/shipit/status/unknown.rb +2 -1
  130. data/app/models/shipit/status.rb +3 -2
  131. data/app/models/shipit/task.rb +98 -12
  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 +109 -0
  135. data/app/models/shipit/team.rb +6 -3
  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 +19 -8
  139. data/app/models/shipit/variable_definition.rb +1 -0
  140. data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +1 -0
  141. data/app/models/shipit/webhooks/handlers/handler.rb +1 -0
  142. data/app/models/shipit/webhooks/handlers/membership_handler.rb +1 -0
  143. data/app/models/shipit/webhooks/handlers/pull_request/assigned_handler.rb +74 -0
  144. data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +68 -0
  145. data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +74 -0
  146. data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +127 -0
  147. data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +106 -0
  148. data/app/models/shipit/webhooks/handlers/pull_request/opened_handler.rb +83 -0
  149. data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +88 -0
  150. data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +103 -0
  151. data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +107 -0
  152. data/app/models/shipit/webhooks/handlers/push_handler.rb +5 -1
  153. data/app/models/shipit/webhooks/handlers/status_handler.rb +1 -0
  154. data/app/models/shipit/webhooks.rb +11 -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 +8 -6
  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 +1 -0
  171. data/app/validators/subset_validator.rb +2 -1
  172. data/app/views/layouts/merge_status.html.erb +1 -1
  173. data/app/views/layouts/shipit.html.erb +1 -1
  174. data/app/views/shipit/_variables.html.erb +1 -1
  175. data/app/views/shipit/ccmenu/project.xml.builder +2 -1
  176. data/app/views/shipit/deploys/show.html.erb +2 -2
  177. data/app/views/shipit/merge_requests/_merge_request.html.erb +29 -0
  178. data/app/views/shipit/{pull_requests → merge_requests}/index.html.erb +2 -2
  179. data/app/views/shipit/merge_requests/merge_requests/_pull_request.html.erb +29 -0
  180. data/app/views/shipit/merge_requests/merge_requests/index.html.erb +20 -0
  181. data/app/views/shipit/merge_status/_merge_queue_button.html.erb +3 -3
  182. data/app/views/shipit/merge_status/backlogged.html.erb +1 -1
  183. data/app/views/shipit/merge_status/failure.html.erb +1 -1
  184. data/app/views/shipit/merge_status/locked.html.erb +1 -1
  185. data/app/views/shipit/merge_status/success.html.erb +2 -2
  186. data/app/views/shipit/repositories/_header.html.erb +19 -0
  187. data/app/views/shipit/repositories/index.html.erb +31 -0
  188. data/app/views/shipit/repositories/new.html.erb +23 -0
  189. data/app/views/shipit/repositories/settings.html.erb +53 -0
  190. data/app/views/shipit/repositories/show.html.erb +30 -0
  191. data/app/views/shipit/stacks/_banners.html.erb +15 -1
  192. data/app/views/shipit/stacks/_header.html.erb +8 -2
  193. data/app/views/shipit/stacks/_stack.html.erb +8 -0
  194. data/app/views/shipit/stacks/all_tasks.html.erb +28 -0
  195. data/app/views/shipit/stacks/index.html.erb +3 -2
  196. data/app/views/shipit/stacks/new.html.erb +1 -1
  197. data/app/views/shipit/stacks/settings.html.erb +5 -5
  198. data/app/views/shipit/stacks/show.html.erb +1 -1
  199. data/app/views/shipit/tasks/_task_output.html.erb +1 -1
  200. data/app/views/shipit/tasks/show.html.erb +1 -1
  201. data/config/initializers/inflections.rb +2 -1
  202. data/config/locales/en.yml +3 -3
  203. data/config/routes.rb +25 -7
  204. data/config/secrets.development.example.yml +24 -0
  205. data/config/secrets.development.shopify.yml +20 -9
  206. data/db/migrate/20200226211925_add_index_to_tasks_status.rb +5 -0
  207. data/db/migrate/20200427135152_add_pull_request_head_sha_to_commit.rb +5 -0
  208. data/db/migrate/20200615181558_add_rollback_once_aborted_to.rb +5 -0
  209. data/db/migrate/20200706145406_add_review_stacks.rb +12 -0
  210. data/db/migrate/20200804144639_rename_pull_request_to_merge_request.rb +7 -0
  211. data/db/migrate/20200804161512_rename_commits_pull_request_id_to_merge_request_id.rb +5 -0
  212. data/db/migrate/20200813134712_recreate_shipit_pull_requests.rb +22 -0
  213. data/db/migrate/20200813194056_create_pull_request_assignments.rb +8 -0
  214. data/db/migrate/20201001125502_add_provision_pr_stacks_flag_to_repositories.rb +7 -0
  215. data/db/migrate/20201008145809_add_retry_attempt_to_tasks.rb +5 -0
  216. data/db/migrate/20201008152744_add_max_retries_to_tasks.rb +5 -0
  217. data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
  218. data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
  219. data/db/migrate/20210823075617_change_check_runs_github_updated_at_default.rb +5 -0
  220. data/lib/shipit/cast_value.rb +1 -0
  221. data/lib/shipit/command.rb +19 -17
  222. data/lib/shipit/commands.rb +23 -9
  223. data/lib/shipit/csv_serializer.rb +1 -0
  224. data/lib/shipit/deploy_commands.rb +1 -0
  225. data/lib/shipit/engine.rb +9 -2
  226. data/lib/shipit/environment_variables.rb +2 -1
  227. data/lib/shipit/first_parent_commits_iterator.rb +1 -0
  228. data/lib/shipit/flock.rb +9 -1
  229. data/lib/shipit/github_app.rb +15 -12
  230. data/lib/shipit/github_http_cache_middleware.rb +1 -0
  231. data/lib/shipit/null_serializer.rb +1 -0
  232. data/lib/shipit/octokit_check_runs.rb +3 -2
  233. data/lib/shipit/octokit_iterator.rb +4 -3
  234. data/lib/shipit/paginator.rb +3 -2
  235. data/lib/shipit/review_stack_commands.rb +8 -0
  236. data/lib/shipit/rollback_commands.rb +1 -0
  237. data/lib/shipit/same_site_cookie_middleware.rb +29 -0
  238. data/lib/shipit/simple_message_verifier.rb +3 -2
  239. data/lib/shipit/stack_commands.rb +39 -9
  240. data/lib/shipit/stat.rb +1 -0
  241. data/lib/shipit/task_commands.rb +9 -0
  242. data/lib/shipit/version.rb +2 -1
  243. data/lib/shipit.rb +61 -17
  244. data/lib/snippets/publish-lerna-independent-packages +35 -34
  245. data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
  246. data/lib/snippets/release-gem +5 -1
  247. data/lib/tasks/cron.rake +13 -2
  248. data/lib/tasks/dev.rake +3 -2
  249. data/lib/tasks/shipit.rake +15 -14
  250. data/lib/tasks/teams.rake +1 -0
  251. data/test/controllers/api/base_controller_test.rb +3 -2
  252. data/test/controllers/api/ccmenu_controller_test.rb +9 -8
  253. data/test/controllers/api/commits_controller_test.rb +3 -2
  254. data/test/controllers/api/deploys_controller_test.rb +32 -14
  255. data/test/controllers/api/hooks_controller_test.rb +8 -7
  256. data/test/controllers/api/locks_controller_test.rb +7 -6
  257. data/test/controllers/api/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +17 -16
  258. data/test/controllers/api/outputs_controller_test.rb +3 -1
  259. data/test/controllers/api/release_statuses_controller_test.rb +2 -1
  260. data/test/controllers/api/rollback_controller_test.rb +113 -0
  261. data/test/controllers/api/stacks_controller_test.rb +71 -16
  262. data/test/controllers/api/tasks_controller_test.rb +13 -12
  263. data/test/controllers/api_clients_controller_test.rb +5 -4
  264. data/test/controllers/ccmenu_controller_test.rb +4 -3
  265. data/test/controllers/commit_checks_controller_test.rb +4 -3
  266. data/test/controllers/commits_controller_test.rb +3 -2
  267. data/test/controllers/deploys_controller_test.rb +32 -21
  268. data/test/controllers/github_authentication_controller_test.rb +1 -0
  269. data/test/controllers/merge_requests_controller_test.rb +32 -0
  270. data/test/controllers/merge_status_controller_test.rb +7 -6
  271. data/test/controllers/release_statuses_controller_test.rb +3 -2
  272. data/test/controllers/repositories_controller_test.rb +71 -0
  273. data/test/controllers/rollbacks_controller_test.rb +9 -8
  274. data/test/controllers/stacks_controller_test.rb +41 -19
  275. data/test/controllers/status_controller_test.rb +1 -0
  276. data/test/controllers/tasks_controller_test.rb +32 -19
  277. data/test/controllers/webhooks_controller_test.rb +33 -17
  278. data/test/dummy/app/assets/config/manifest.js +3 -0
  279. data/test/dummy/config/application.rb +7 -2
  280. data/test/dummy/config/database.yml +9 -0
  281. data/test/dummy/config/environments/development.rb +3 -4
  282. data/test/dummy/config/environments/test.rb +2 -5
  283. data/test/dummy/config/secrets_double_github_app.yml +79 -0
  284. data/test/dummy/db/schema.rb +59 -17
  285. data/test/dummy/db/seeds.rb +2 -1
  286. data/test/fixtures/payloads/check_suite_master.json +4 -32
  287. data/test/fixtures/payloads/invalid_pull_request.json +117 -0
  288. data/test/fixtures/payloads/provision_disabled_pull_request.json +454 -0
  289. data/test/fixtures/payloads/pull_request_assigned.json +480 -0
  290. data/test/fixtures/payloads/pull_request_closed.json +454 -0
  291. data/test/fixtures/payloads/pull_request_labeled.json +461 -0
  292. data/test/fixtures/payloads/pull_request_opened.json +454 -0
  293. data/test/fixtures/payloads/pull_request_reopened.json +454 -0
  294. data/test/fixtures/payloads/pull_request_unlabeled.json +454 -0
  295. data/test/fixtures/payloads/pull_request_with_no_repo.json +454 -0
  296. data/test/fixtures/payloads/push_master.json +1 -1
  297. data/test/fixtures/payloads/push_not_master.json +1 -1
  298. data/test/fixtures/shipit/commits.yml +31 -3
  299. data/test/fixtures/shipit/hooks.yml +1 -0
  300. data/test/fixtures/shipit/merge_requests.yml +141 -0
  301. data/test/fixtures/shipit/pull_request_assignments.yml +3 -0
  302. data/test/fixtures/shipit/pull_requests.yml +10 -131
  303. data/test/fixtures/shipit/repositories.yml +5 -0
  304. data/test/fixtures/shipit/stacks.yml +235 -14
  305. data/test/fixtures/shipit/statuses.yml +9 -0
  306. data/test/fixtures/shipit/tasks.yml +4 -1
  307. data/test/fixtures/shipit/users.yml +7 -0
  308. data/test/fixtures/timeout +2 -1
  309. data/test/helpers/api_helper.rb +1 -0
  310. data/test/helpers/fixture_aliases_helper.rb +1 -0
  311. data/test/helpers/hooks_helper.rb +2 -1
  312. data/test/helpers/json_helper.rb +20 -12
  313. data/test/helpers/links_helper.rb +4 -3
  314. data/test/helpers/payloads_helper.rb +5 -0
  315. data/test/helpers/queries_helper.rb +3 -2
  316. data/test/jobs/cache_deploy_spec_job_test.rb +2 -1
  317. data/test/jobs/chunk_rollup_job_test.rb +16 -1
  318. data/test/jobs/deliver_hook_job_test.rb +1 -0
  319. data/test/jobs/destroy_repository_job_test.rb +27 -0
  320. data/test/jobs/destroy_stack_job_test.rb +1 -0
  321. data/test/jobs/emit_event_job_test.rb +2 -1
  322. data/test/jobs/fetch_commit_stats_job_test.rb +1 -0
  323. data/test/jobs/fetch_deployed_revision_job_test.rb +1 -0
  324. data/test/jobs/github_sync_job_test.rb +3 -1
  325. data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
  326. data/test/jobs/perform_task_job_test.rb +12 -11
  327. data/test/jobs/{merge_pull_requests_job_test.rb → process_merge_requests_job_test.rb} +19 -18
  328. data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
  329. data/test/jobs/reap_dead_tasks_job_test.rb +68 -0
  330. data/test/jobs/refresh_github_user_job_test.rb +1 -0
  331. data/test/jobs/refresh_status_job_test.rb +1 -0
  332. data/test/jobs/unique_job_test.rb +1 -0
  333. data/test/jobs/update_github_last_deployed_ref_job_test.rb +1 -0
  334. data/test/lib/shipit/deploy_commands_test.rb +16 -0
  335. data/test/lib/shipit/task_commands_test.rb +17 -0
  336. data/test/middleware/same_site_cookie_middleware_test.rb +52 -0
  337. data/test/models/api_client_test.rb +1 -0
  338. data/test/models/commit_checks_test.rb +1 -0
  339. data/test/models/commit_deployment_status_test.rb +4 -3
  340. data/test/models/commit_deployment_test.rb +2 -1
  341. data/test/models/commits_test.rb +96 -19
  342. data/test/models/delivery_test.rb +2 -1
  343. data/test/models/deploy_spec_test.rb +110 -65
  344. data/test/models/deploy_stats_test.rb +1 -0
  345. data/test/models/deploys_test.rb +219 -36
  346. data/test/models/duration_test.rb +1 -0
  347. data/test/models/github_hook_test.rb +1 -0
  348. data/test/models/hook_test.rb +47 -10
  349. data/test/models/membership_test.rb +1 -0
  350. data/test/models/{pull_request_test.rb → merge_request_test.rb} +53 -37
  351. data/test/models/pull_request_assignment_test.rb +16 -0
  352. data/test/models/release_statuses_test.rb +1 -0
  353. data/test/models/rollbacks_test.rb +1 -0
  354. data/test/models/shipit/check_run_test.rb +125 -5
  355. data/test/models/shipit/provisioning_handler/base_test.rb +33 -0
  356. data/test/models/shipit/provisioning_handler/unregistered_provisioning_handler_test.rb +49 -0
  357. data/test/models/shipit/provisioning_handler_test.rb +64 -0
  358. data/test/models/shipit/pull_request_test.rb +52 -0
  359. data/test/models/shipit/repository_test.rb +6 -1
  360. data/test/models/shipit/review_stack_provision_status_test.rb +77 -0
  361. data/test/models/shipit/review_stack_provisioning_queue_test.rb +63 -0
  362. data/test/models/shipit/review_stack_test.rb +91 -0
  363. data/test/models/{stacks_test.rb → shipit/stacks_test.rb} +82 -16
  364. data/test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb +45 -0
  365. data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +192 -0
  366. data/test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb +47 -0
  367. data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +209 -0
  368. data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +332 -0
  369. data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +238 -0
  370. data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +282 -0
  371. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +107 -0
  372. data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +324 -0
  373. data/test/models/shipit/{wehbooks → webhooks}/handlers_test.rb +1 -0
  374. data/test/models/status/group_test.rb +1 -0
  375. data/test/models/status/missing_test.rb +1 -0
  376. data/test/models/status_test.rb +1 -0
  377. data/test/models/task_definitions_test.rb +9 -8
  378. data/test/models/tasks_test.rb +81 -1
  379. data/test/models/team_test.rb +4 -2
  380. data/test/models/undeployed_commits_test.rb +1 -0
  381. data/test/models/users_test.rb +13 -5
  382. data/test/serializers/shipit/pull_request_serializer_test.rb +29 -0
  383. data/test/test_command_integration.rb +3 -2
  384. data/test/test_helper.rb +49 -31
  385. data/test/unit/anonymous_user_serializer_test.rb +14 -0
  386. data/test/unit/command_test.rb +16 -10
  387. data/test/unit/commands_test.rb +1 -0
  388. data/test/unit/commit_serializer_test.rb +16 -0
  389. data/test/unit/csv_serializer_test.rb +3 -2
  390. data/test/unit/deploy_commands_test.rb +77 -20
  391. data/test/unit/deploy_serializer_test.rb +17 -0
  392. data/test/unit/environment_variables_test.rb +5 -4
  393. data/test/unit/github_app_test.rb +3 -3
  394. data/test/unit/github_apps_test.rb +416 -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_deployment_checks_test.rb +77 -0
  398. data/test/unit/shipit_helper_test.rb +17 -0
  399. data/test/unit/shipit_task_execution_strategy_test.rb +47 -0
  400. data/test/unit/shipit_test.rb +15 -0
  401. data/test/unit/user_serializer_test.rb +14 -0
  402. data/test/unit/variable_definition_test.rb +1 -0
  403. metadata +325 -182
  404. data/app/controllers/shipit/api/pull_requests_controller.rb +0 -36
  405. data/app/controllers/shipit/pull_requests_controller.rb +0 -30
  406. data/app/jobs/shipit/merge_pull_requests_job.rb +0 -31
  407. data/app/jobs/shipit/refresh_pull_request_job.rb +0 -10
  408. data/app/views/shipit/pull_requests/_pull_request.html.erb +0 -29
  409. data/test/controllers/pull_requests_controller_test.rb +0 -31
  410. data/test/fixtures/shipit/output_chunks.yml +0 -47
  411. data/test/models/output_chunk_test.rb +0 -20
@@ -1,39 +1,40 @@
1
1
  #!/usr/bin/env node
2
- const {resolve} = require('path');
3
- const {execSync} = require('child_process')
4
- const Repository = require(resolve('.', 'node_modules', 'lerna', 'lib', 'Repository'));
5
- const PackageUtilities = require(resolve('.', 'node_modules', 'lerna', 'lib', 'PackageUtilities'));
6
-
7
- function npmTag(version) {
8
- const isNext = ['-beta', '-alpha', '-rc', '-next'].some(distributionType =>
9
- version.includes(distributionType),
10
- );
11
- return isNext ? 'next' : 'latest';
12
- }
2
+ const { execSync } = require("child_process");
13
3
 
14
- const taggedPackages = execSync('git tag --points-at HEAD')
4
+ const taggedPackages = execSync("git tag --points-at HEAD")
15
5
  .toString()
16
6
  .trim()
17
- .split('\n')
18
- .map(tag => {
19
- if (tag.startsWith('@')) {
20
- return `@${tag.split('@')[1]}`;
21
- }
22
- return tag.split('@')[0];
23
- });
24
-
25
- const repository = new Repository('.');
26
- const unsortedPackages = PackageUtilities.getPackages({rootPath: '.', packageConfigs: repository.packageConfigs});
27
- const packages = PackageUtilities.topologicallyBatchPackages(unsortedPackages, true)
28
- .reduce((acc, packageGroup) => [...acc, ...packageGroup], [])
29
- .filter(({name}) => taggedPackages.includes(name));
30
-
31
- packages.forEach(({name, version}) => {
32
- const command = `node_modules/.bin/lerna publish --yes --npm-client=npm --skip-npm=false --skip-git --force-publish=${name} --repo-version=${version} --scope=${name} --npm-tag=${npmTag(
33
- version,
34
- )}`;
35
-
36
- // eslint-disable-next-line no-console
37
- console.log(command);
38
- require('child_process').execSync(command);
7
+ .split("\n");
8
+
9
+ // anything that matches `-` after MAJOR.MINOR.PATCH
10
+ const validPattern = new RegExp(/\d+\.\d+\.\d+-(\w+)/);
11
+
12
+ // Ensure that all releases use the same prerelease suffix.
13
+ // We want to only release all final versions, or all betas etc
14
+ const allPrereleaseSuffixes = taggedPackages.map((version) => {
15
+ const result = validPattern.exec(version);
16
+ return result ? result[1] : '';
39
17
  });
18
+ if ((new Set(allPrereleaseSuffixes)).size > 1) {
19
+ throw Error("All packages must be of the same type of release. Versions cannot be mixed.");
20
+ }
21
+
22
+ // set this using machine.environment.SHIPIT_LERNA_PUBLISH_MECHANISM in your shipit.yml
23
+ const publishMechanism = process.env.SHIPIT_LERNA_PUBLISH_MECHANISM || 'from-git';
24
+
25
+ if (!['from-package', 'from-git'].includes(publishMechanism)) {
26
+ throw Error("SHIPIT_LERNA_PUBLISH_MECHANISM must be 'from-package' or 'from-git'.");
27
+ }
28
+
29
+ const command = [
30
+ "node_modules/.bin/lerna publish",
31
+ publishMechanism,
32
+ "--yes",
33
+ "--dist-tag latest",
34
+ "--pre-dist-tag next",
35
+ ];
36
+
37
+ const commandString = command.join(" ");
38
+
39
+ console.log(`${commandString}`);
40
+ execSync(commandString);
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ const {resolve} = require('path');
3
+ const {execSync} = require('child_process')
4
+ const Repository = require(resolve('.', 'node_modules', 'lerna', 'lib', 'Repository'));
5
+ const PackageUtilities = require(resolve('.', 'node_modules', 'lerna', 'lib', 'PackageUtilities'));
6
+
7
+ function npmTag(version) {
8
+ const isNext = ['-beta', '-alpha', '-rc', '-next'].some(distributionType =>
9
+ version.includes(distributionType),
10
+ );
11
+ return isNext ? 'next' : 'latest';
12
+ }
13
+
14
+ const taggedPackages = execSync('git tag --points-at HEAD')
15
+ .toString()
16
+ .trim()
17
+ .split('\n')
18
+ .map(tag => {
19
+ if (tag.startsWith('@')) {
20
+ return `@${tag.split('@')[1]}`;
21
+ }
22
+ return tag.split('@')[0];
23
+ });
24
+
25
+ const repository = new Repository('.');
26
+ const unsortedPackages = PackageUtilities.getPackages({rootPath: '.', packageConfigs: repository.packageConfigs});
27
+ const packages = PackageUtilities.topologicallyBatchPackages(unsortedPackages, true)
28
+ .reduce((acc, packageGroup) => [...acc, ...packageGroup], [])
29
+ .filter(({name}) => taggedPackages.includes(name));
30
+
31
+ packages.forEach(({name, version}) => {
32
+ const command = `node_modules/.bin/lerna publish --yes --npm-client=npm --skip-npm=false --skip-git --force-publish=${name} --repo-version=${version} --scope=${name} --npm-tag=${npmTag(
33
+ version,
34
+ )}`;
35
+
36
+ // eslint-disable-next-line no-console
37
+ console.log(command);
38
+ require('child_process').execSync(command);
39
+ });
@@ -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,25 +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
- stack = ENV['stack']
5
- revision = ENV['revision']
5
+ stack = ENV['stack']
6
+ revision = ENV['revision']
6
7
 
7
- raise ArgumentError.new('The first argument has to be a stack, e.g. shopify/shipit/production') if stack.nil?
8
- 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?
9
10
 
10
- module Shipit
11
- class Task
12
- def write(text)
13
- p text
14
- chunks.create!(text: text)
15
- end
11
+ module Shipit
12
+ class Task
13
+ def write(text)
14
+ p(text)
15
+ chunks.create!(text: text)
16
16
  end
17
17
  end
18
+ end
18
19
 
19
- Shipit::Stack.run_deploy_in_foreground(stack: stack, revision: revision)
20
+ Shipit::Stack.run_deploy_in_foreground(stack: stack, revision: revision)
20
21
  rescue ArgumentError
21
- p "Use this command as follows:"
22
- p "bundle exec rake shipit:deploy stack='shopify/shipit/production' revision='$SHA'"
23
- raise
22
+ p("Use this command as follows:")
23
+ p("bundle exec rake shipit:deploy stack='shopify/shipit/production' revision='$SHA'")
24
+ raise
24
25
  end
25
26
  end
data/lib/tasks/teams.rake CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  namespace :teams do
2
3
  desc "Import the members of each team configured through the github.oauth.teams config"
3
4
  task fetch: :environment do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -6,7 +7,7 @@ module Shipit
6
7
  test "authentication is required" do
7
8
  get :index
8
9
  assert_response :unauthorized
9
- assert_equal({message: 'Bad credentials'}.to_json, response.body)
10
+ assert_equal({ message: 'Bad credentials' }.to_json, response.body)
10
11
  end
11
12
 
12
13
  test "with proper credentials the request is processed" do
@@ -17,7 +18,7 @@ module Shipit
17
18
  test "#index respond with a list of endpoints" do
18
19
  authenticate!
19
20
  get :index, format: :json
20
- assert_equal({stacks_url: api_stacks_url}.to_json, response.body)
21
+ assert_equal({ stacks_url: api_stacks_url }.to_json, response.body)
21
22
  end
22
23
  end
23
24
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -10,26 +11,26 @@ module Shipit
10
11
 
11
12
  test "a request with insufficient permissions will render a 403" do
12
13
  @client.update!(permissions: [])
13
- get :show, params: {stack_id: @stack.to_param}
14
+ get :show, params: { stack_id: @stack.to_param }
14
15
  assert_response :forbidden
15
16
  assert_json 'message', 'This operation requires the `read:stack` permission'
16
17
  end
17
18
 
18
19
  test "#show renders the xml" do
19
- get :show, params: {stack_id: @stack.to_param}
20
+ get :show, params: { stack_id: @stack.to_param }
20
21
  assert_response :ok
21
22
  assert_payload 'name', @stack.to_param
22
23
  end
23
24
 
24
25
  test "can authenticate with query string token" do
25
26
  request.headers['Authorization'] = 'bleh'
26
- get :show, params: {stack_id: @stack.to_param, token: @client.authentication_token}
27
+ get :show, params: { stack_id: @stack.to_param, token: @client.authentication_token }
27
28
  assert_response :ok
28
29
  assert_payload 'name', @stack.to_param
29
30
  end
30
31
 
31
32
  test "xml contains required attributes" do
32
- get :show, params: {stack_id: @stack.to_param}
33
+ get :show, params: { stack_id: @stack.to_param }
33
34
  project = get_project_from_xml(response.body)
34
35
  %w(name activity lastBuildStatus lastBuildLabel lastBuildTime webUrl).each do |attribute|
35
36
  assert_includes project, attribute, "Response missing required attribute: #{attribute}"
@@ -38,13 +39,13 @@ module Shipit
38
39
 
39
40
  test "locked stacks show as failed" do
40
41
  @stack.lock('test', @user)
41
- get :show, params: {stack_id: @stack.to_param}
42
+ get :show, params: { stack_id: @stack.to_param }
42
43
  assert_payload 'lastBuildStatus', 'Failure'
43
44
  end
44
45
 
45
46
  test "stacks with no deploys render correctly" do
46
- stack = Stack.create!(repository: Repository.new(owner: "foo", name: "bar"))
47
- get :show, params: {stack_id: stack.to_param}
47
+ stack = Stack.create!(repository: Repository.new(owner: "foo", name: "bar"), branch: 'main')
48
+ get :show, params: { stack_id: stack.to_param }
48
49
  assert_payload 'lastBuildStatus', 'Success'
49
50
  end
50
51
 
@@ -56,7 +57,7 @@ module Shipit
56
57
 
57
58
  def assert_payload(k, v)
58
59
  @project ||= get_project_from_xml(response.body)
59
- assert_equal v, @project[k]
60
+ assert_equal(v, @project[k])
60
61
  end
61
62
  end
62
63
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -11,7 +12,7 @@ module Shipit
11
12
  test "#index returns a list of commits" do
12
13
  commit = @stack.commits.reachable.last
13
14
 
14
- get :index, params: {stack_id: @stack.to_param}
15
+ get :index, params: { stack_id: @stack.to_param }
15
16
  assert_response :ok
16
17
  assert_json '0.sha', commit.sha
17
18
  end
@@ -19,7 +20,7 @@ module Shipit
19
20
  test "#index with undeployed=1 returns a list of undeployed commits" do
20
21
  commits = @stack.undeployed_commits.pluck(:sha)
21
22
 
22
- get :index, params: {stack_id: @stack.to_param, undeployed: 1}
23
+ get :index, params: { stack_id: @stack.to_param, undeployed: 1 }
23
24
  assert_response :ok
24
25
  JSON.parse(response.body).each do |commit|
25
26
  assert commits.include?(commit.fetch("sha"))
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -13,7 +14,7 @@ module Shipit
13
14
  test "#deploys returns the deploys and revisions for a given stack" do
14
15
  tasks = @stack.deploys_and_rollbacks.order(id: :desc)
15
16
 
16
- get :index, params: {stack_id: @stack.to_param}
17
+ get :index, params: { stack_id: @stack.to_param }
17
18
  assert_response :ok
18
19
 
19
20
  (0...tasks.length).each do |i|
@@ -23,70 +24,87 @@ module Shipit
23
24
 
24
25
  test "#create triggers a new deploy for the stack" do
25
26
  assert_difference -> { @stack.deploys.count }, 1 do
26
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
27
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
27
28
  end
28
29
  assert_response :accepted
29
30
  assert_json 'status', 'pending'
30
31
  end
31
32
 
32
33
  test "#create triggers a new deploy for whitelisted variables" do
33
- correct_env = {'SAFETY_DISABLED' => 1}
34
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha, env: correct_env}
34
+ correct_env = { 'SAFETY_DISABLED' => 1 }
35
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, env: correct_env }
35
36
  assert_response :accepted
36
37
  assert_json 'type', 'deploy'
37
38
  assert_json 'status', 'pending'
38
39
  end
39
40
 
40
41
  test "#create refuses to trigger a new deploy with incorrect variables" do
41
- incorrect_env = {'DANGEROUS_VARIABLE' => 1}
42
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha, env: incorrect_env}
42
+ incorrect_env = { 'DANGEROUS_VARIABLE' => 1 }
43
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, env: incorrect_env }
43
44
  assert_response :unprocessable_entity
44
45
  assert_json 'message', 'Variables DANGEROUS_VARIABLE have not been whitelisted'
45
46
  end
46
47
 
47
48
  test "#create use the claimed user as author" do
48
49
  request.headers['X-Shipit-User'] = @user.login
49
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
50
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
50
51
  deploy = Deploy.last
51
52
  deploy.user == @user
52
53
  end
53
54
 
54
55
  test "#create normalises the claimed user" do
55
56
  request.headers['X-Shipit-User'] = @user.login.swapcase
56
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
57
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
57
58
  deploy = Deploy.last
58
59
  assert_equal deploy.user, @user
59
60
  end
60
61
 
61
62
  test "#create renders a 422 if the sha isn't found" do
62
- post :create, params: {stack_id: @stack.to_param, sha: '123443543545'}
63
+ post :create, params: { stack_id: @stack.to_param, sha: '123443543545' }
63
64
  assert_response :unprocessable_entity
64
65
  assert_json 'errors', 'sha' => ['Unknown revision']
65
66
  end
66
67
 
67
68
  test "#create renders a 422 if the sha format is invalid" do
68
- post :create, params: {stack_id: @stack.to_param, sha: '1'}
69
+ post :create, params: { stack_id: @stack.to_param, sha: '1' }
69
70
  assert_response :unprocessable_entity
70
71
  assert_json 'errors', 'sha' => ['is too short (minimum is 6 characters)']
71
72
  end
72
73
 
73
74
  test "#create renders a 409 if a concurrent task is already running" do
74
75
  assert_difference -> { @stack.deploys.count }, 1 do
75
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
76
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
76
77
  end
77
78
 
78
79
  assert_no_difference -> { @stack.deploys.count } do
79
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
80
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
80
81
  end
81
82
 
82
83
  assert_response :conflict
83
84
  end
84
85
 
86
+ test "#create refuses to deploy unsuccessful commits if the require_ci flag is passed" do
87
+ Commit.any_instance.expects(:deployable?).returns(false)
88
+
89
+ assert_no_difference -> { @stack.deploys.count } do
90
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, require_ci: true }
91
+ end
92
+ assert_response :unprocessable_entity
93
+ assert_json 'errors.require_ci', ["Commit is not deployable"]
94
+ end
95
+
96
+ test "#create deploys failing commits if the require_ci flag is not passed" do
97
+ Commit.any_instance.expects(:deployable?).returns(false)
98
+
99
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
100
+ assert_response :accepted
101
+ end
102
+
85
103
  test "#create refuses to deploy locked stacks" do
86
104
  @stack.update!(lock_reason: 'Something broken')
87
105
 
88
106
  assert_no_difference -> { @stack.deploys.count } do
89
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
107
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
90
108
  end
91
109
  assert_response :unprocessable_entity
92
110
  assert_json 'errors.force', ["Can't deploy a locked stack"]
@@ -96,7 +114,7 @@ module Shipit
96
114
  @stack.update!(lock_reason: 'Something broken')
97
115
 
98
116
  assert_difference -> { @stack.deploys.count }, 1 do
99
- post :create, params: {stack_id: @stack.to_param, sha: @commit.sha, force: 'true'}
117
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, force: 'true' }
100
118
  end
101
119
  assert_response :accepted
102
120
  assert_json 'status', 'pending'