shipit-engine 0.30.0 → 0.34.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 +19 -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 +0 -2
  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.rb +4 -0
  54. data/app/jobs/shipit/background_job/unique.rb +1 -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.rb +38 -7
  97. data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -0
  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 +13 -4
  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 +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.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 +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 +1 -0
  125. data/app/models/shipit/stack.rb +144 -44
  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 +2 -1
  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 +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.rb +11 -0
  141. data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +1 -0
  142. data/app/models/shipit/webhooks/handlers/handler.rb +1 -0
  143. data/app/models/shipit/webhooks/handlers/membership_handler.rb +1 -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 +5 -1
  154. data/app/models/shipit/webhooks/handlers/status_handler.rb +1 -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 +20 -7
  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 +4 -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/lib/shipit.rb +61 -17
  220. data/lib/shipit/cast_value.rb +1 -0
  221. data/lib/shipit/command.rb +20 -21
  222. data/lib/shipit/commands.rb +14 -6
  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 +11 -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 +37 -7
  240. data/lib/shipit/stat.rb +1 -0
  241. data/lib/shipit/task_commands.rb +23 -16
  242. data/lib/shipit/version.rb +2 -1
  243. data/lib/snippets/publish-lerna-independent-packages +35 -34
  244. data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
  245. data/lib/snippets/release-gem +5 -1
  246. data/lib/tasks/cron.rake +13 -2
  247. data/lib/tasks/dev.rake +3 -2
  248. data/lib/tasks/shipit.rake +15 -14
  249. data/lib/tasks/teams.rake +1 -0
  250. data/test/controllers/api/base_controller_test.rb +3 -2
  251. data/test/controllers/api/ccmenu_controller_test.rb +9 -8
  252. data/test/controllers/api/commits_controller_test.rb +3 -2
  253. data/test/controllers/api/deploys_controller_test.rb +32 -14
  254. data/test/controllers/api/hooks_controller_test.rb +8 -7
  255. data/test/controllers/api/locks_controller_test.rb +7 -6
  256. data/test/controllers/api/{pull_requests_controller_test.rb → merge_requests_controller_test.rb} +17 -16
  257. data/test/controllers/api/outputs_controller_test.rb +3 -1
  258. data/test/controllers/api/release_statuses_controller_test.rb +2 -1
  259. data/test/controllers/api/rollback_controller_test.rb +113 -0
  260. data/test/controllers/api/stacks_controller_test.rb +71 -16
  261. data/test/controllers/api/tasks_controller_test.rb +13 -12
  262. data/test/controllers/api_clients_controller_test.rb +5 -4
  263. data/test/controllers/ccmenu_controller_test.rb +4 -3
  264. data/test/controllers/commit_checks_controller_test.rb +4 -3
  265. data/test/controllers/commits_controller_test.rb +3 -2
  266. data/test/controllers/deploys_controller_test.rb +32 -21
  267. data/test/controllers/github_authentication_controller_test.rb +1 -0
  268. data/test/controllers/merge_requests_controller_test.rb +32 -0
  269. data/test/controllers/merge_status_controller_test.rb +7 -6
  270. data/test/controllers/release_statuses_controller_test.rb +3 -2
  271. data/test/controllers/repositories_controller_test.rb +71 -0
  272. data/test/controllers/rollbacks_controller_test.rb +9 -8
  273. data/test/controllers/stacks_controller_test.rb +41 -19
  274. data/test/controllers/status_controller_test.rb +1 -0
  275. data/test/controllers/tasks_controller_test.rb +32 -19
  276. data/test/controllers/webhooks_controller_test.rb +33 -17
  277. data/test/dummy/app/assets/config/manifest.js +3 -0
  278. data/test/dummy/config/application.rb +7 -2
  279. data/test/dummy/config/database.yml +9 -0
  280. data/test/dummy/config/environments/development.rb +3 -4
  281. data/test/dummy/config/environments/test.rb +2 -5
  282. data/test/dummy/config/secrets_double_github_app.yml +79 -0
  283. data/test/dummy/db/schema.rb +59 -17
  284. data/test/dummy/db/seeds.rb +2 -1
  285. data/test/fixtures/payloads/check_suite_master.json +4 -32
  286. data/test/fixtures/payloads/invalid_pull_request.json +117 -0
  287. data/test/fixtures/payloads/provision_disabled_pull_request.json +454 -0
  288. data/test/fixtures/payloads/pull_request_assigned.json +480 -0
  289. data/test/fixtures/payloads/pull_request_closed.json +454 -0
  290. data/test/fixtures/payloads/pull_request_labeled.json +461 -0
  291. data/test/fixtures/payloads/pull_request_opened.json +454 -0
  292. data/test/fixtures/payloads/pull_request_reopened.json +454 -0
  293. data/test/fixtures/payloads/pull_request_unlabeled.json +454 -0
  294. data/test/fixtures/payloads/pull_request_with_no_repo.json +454 -0
  295. data/test/fixtures/payloads/push_master.json +1 -1
  296. data/test/fixtures/payloads/push_not_master.json +1 -1
  297. data/test/fixtures/shipit/commits.yml +31 -3
  298. data/test/fixtures/shipit/hooks.yml +1 -0
  299. data/test/fixtures/shipit/merge_requests.yml +141 -0
  300. data/test/fixtures/shipit/pull_request_assignments.yml +3 -0
  301. data/test/fixtures/shipit/pull_requests.yml +10 -131
  302. data/test/fixtures/shipit/repositories.yml +5 -0
  303. data/test/fixtures/shipit/stacks.yml +235 -14
  304. data/test/fixtures/shipit/statuses.yml +9 -0
  305. data/test/fixtures/shipit/tasks.yml +4 -1
  306. data/test/fixtures/shipit/users.yml +7 -0
  307. data/test/fixtures/timeout +2 -1
  308. data/test/helpers/api_helper.rb +1 -0
  309. data/test/helpers/fixture_aliases_helper.rb +1 -0
  310. data/test/helpers/hooks_helper.rb +2 -1
  311. data/test/helpers/json_helper.rb +20 -12
  312. data/test/helpers/links_helper.rb +4 -3
  313. data/test/helpers/payloads_helper.rb +5 -0
  314. data/test/helpers/queries_helper.rb +3 -2
  315. data/test/jobs/cache_deploy_spec_job_test.rb +2 -1
  316. data/test/jobs/chunk_rollup_job_test.rb +16 -1
  317. data/test/jobs/deliver_hook_job_test.rb +1 -0
  318. data/test/jobs/destroy_repository_job_test.rb +27 -0
  319. data/test/jobs/destroy_stack_job_test.rb +1 -0
  320. data/test/jobs/emit_event_job_test.rb +2 -1
  321. data/test/jobs/fetch_commit_stats_job_test.rb +1 -0
  322. data/test/jobs/fetch_deployed_revision_job_test.rb +1 -0
  323. data/test/jobs/github_sync_job_test.rb +3 -1
  324. data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
  325. data/test/jobs/perform_task_job_test.rb +12 -11
  326. data/test/jobs/{merge_pull_requests_job_test.rb → process_merge_requests_job_test.rb} +19 -18
  327. data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
  328. data/test/jobs/reap_dead_tasks_job_test.rb +68 -0
  329. data/test/jobs/refresh_github_user_job_test.rb +1 -0
  330. data/test/jobs/refresh_status_job_test.rb +1 -0
  331. data/test/jobs/unique_job_test.rb +1 -0
  332. data/test/jobs/update_github_last_deployed_ref_job_test.rb +1 -0
  333. data/test/lib/shipit/deploy_commands_test.rb +16 -0
  334. data/test/lib/shipit/task_commands_test.rb +17 -0
  335. data/test/middleware/same_site_cookie_middleware_test.rb +52 -0
  336. data/test/models/api_client_test.rb +1 -0
  337. data/test/models/commit_checks_test.rb +1 -0
  338. data/test/models/commit_deployment_status_test.rb +4 -3
  339. data/test/models/commit_deployment_test.rb +2 -1
  340. data/test/models/commits_test.rb +96 -19
  341. data/test/models/delivery_test.rb +2 -1
  342. data/test/models/deploy_spec_test.rb +110 -65
  343. data/test/models/deploy_stats_test.rb +1 -0
  344. data/test/models/deploys_test.rb +197 -36
  345. data/test/models/duration_test.rb +1 -0
  346. data/test/models/github_hook_test.rb +1 -0
  347. data/test/models/hook_test.rb +47 -10
  348. data/test/models/membership_test.rb +1 -0
  349. data/test/models/{pull_request_test.rb → merge_request_test.rb} +53 -37
  350. data/test/models/pull_request_assignment_test.rb +16 -0
  351. data/test/models/release_statuses_test.rb +1 -0
  352. data/test/models/rollbacks_test.rb +1 -0
  353. data/test/models/shipit/check_run_test.rb +125 -5
  354. data/test/models/shipit/provisioning_handler/base_test.rb +33 -0
  355. data/test/models/shipit/provisioning_handler/unregistered_provisioning_handler_test.rb +49 -0
  356. data/test/models/shipit/provisioning_handler_test.rb +64 -0
  357. data/test/models/shipit/pull_request_test.rb +52 -0
  358. data/test/models/shipit/repository_test.rb +6 -1
  359. data/test/models/shipit/review_stack_provision_status_test.rb +77 -0
  360. data/test/models/shipit/review_stack_provisioning_queue_test.rb +63 -0
  361. data/test/models/shipit/review_stack_test.rb +91 -0
  362. data/test/models/{stacks_test.rb → shipit/stacks_test.rb} +121 -16
  363. data/test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb +45 -0
  364. data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +192 -0
  365. data/test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb +47 -0
  366. data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +209 -0
  367. data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +332 -0
  368. data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +238 -0
  369. data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +282 -0
  370. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +107 -0
  371. data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +324 -0
  372. data/test/models/shipit/{wehbooks → webhooks}/handlers_test.rb +1 -0
  373. data/test/models/status/group_test.rb +1 -0
  374. data/test/models/status/missing_test.rb +1 -0
  375. data/test/models/status_test.rb +1 -0
  376. data/test/models/task_definitions_test.rb +9 -8
  377. data/test/models/tasks_test.rb +81 -1
  378. data/test/models/team_test.rb +4 -2
  379. data/test/models/undeployed_commits_test.rb +1 -0
  380. data/test/models/users_test.rb +13 -5
  381. data/test/serializers/shipit/pull_request_serializer_test.rb +29 -0
  382. data/test/test_command_integration.rb +3 -2
  383. data/test/test_helper.rb +49 -31
  384. data/test/unit/anonymous_user_serializer_test.rb +14 -0
  385. data/test/unit/command_test.rb +16 -10
  386. data/test/unit/commands_test.rb +1 -0
  387. data/test/unit/commit_serializer_test.rb +16 -0
  388. data/test/unit/csv_serializer_test.rb +3 -2
  389. data/test/unit/deploy_commands_test.rb +75 -18
  390. data/test/unit/deploy_serializer_test.rb +17 -0
  391. data/test/unit/environment_variables_test.rb +5 -4
  392. data/test/unit/github_app_test.rb +3 -3
  393. data/test/unit/github_apps_test.rb +416 -0
  394. data/test/unit/github_url_helper_test.rb +6 -0
  395. data/test/unit/rollback_commands_test.rb +2 -1
  396. data/test/unit/shipit_deployment_checks_test.rb +77 -0
  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 +15 -0
  400. data/test/unit/user_serializer_test.rb +14 -0
  401. data/test/unit/variable_definition_test.rb +1 -0
  402. metadata +320 -178
  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
@@ -0,0 +1,282 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ module Webhooks
7
+ module Handlers
8
+ module PullRequest
9
+ class ReopenedHandlerTest < ActiveSupport::TestCase
10
+ test "validates payload" do
11
+ assert_raise(StandardError) { Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:invalid_pull_request)) }
12
+ end
13
+
14
+ test "ignores irrelevant PR actions" do
15
+ assert_no_difference -> { Shipit::Stack.count } do
16
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:pull_request_opened).merge(action: "assigned")).process
17
+ end
18
+ end
19
+
20
+ test "does not error for repos that are not tracked" do
21
+ assert_no_difference -> { Shipit::Stack.count } do
22
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:pull_request_with_no_repo)).process
23
+ end
24
+ end
25
+
26
+ test "de-archives stacks that were previously archived" do
27
+ create_archived_stack
28
+
29
+ assert_no_difference -> { Shipit::Stack.count } do
30
+ assert_difference -> { Shipit::Stack.not_archived.count } do
31
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:pull_request_reopened)).process
32
+ end
33
+ end
34
+ end
35
+
36
+ test "ignored duplicate deliveries" do
37
+ stack = create_archived_stack
38
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:pull_request_reopened)).process
39
+ complete_active_tasks(stack)
40
+
41
+ assert_no_difference -> { Shipit::Stack.not_archived.count } do
42
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:pull_request_reopened)).process
43
+ end
44
+ end
45
+
46
+ test "unarchives stacks for repos that allow_all" do
47
+ stack = create_archived_stack
48
+ repository = shipit_repositories(:shipit)
49
+ configure_provisioning_behavior(
50
+ repository: repository,
51
+ behavior: :allow_all
52
+ )
53
+
54
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload_parsed(:pull_request_reopened)).process
55
+
56
+ assert_not stack.reload.archived?, "Expected stack to NOT be archived"
57
+ assert_pending_provision(stack)
58
+ end
59
+
60
+ test "provisions missing stacks for repos that allow_all" do
61
+ repository = shipit_repositories(:shipit)
62
+ configure_provisioning_behavior(
63
+ repository: repository,
64
+ behavior: :allow_all
65
+ )
66
+ payload = payload_parsed(:pull_request_reopened)
67
+
68
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
69
+
70
+ stack = shipit_repositories(:shipit).stacks.last
71
+ assert_equal stack.environment, "pr#{payload['number']}"
72
+ assert_equal stack.continuous_deployment, false
73
+ assert_equal stack.ignore_ci, false
74
+ assert_equal stack.branch, payload["pull_request"]["head"]["ref"]
75
+ assert_not stack.archived?, "Expected stack to be NOT be archived"
76
+ assert_pending_provision(stack)
77
+ end
78
+
79
+ test "auto-created stack should have pull request assigned" do
80
+ repository = shipit_repositories(:shipit)
81
+ configure_provisioning_behavior(
82
+ repository: repository,
83
+ behavior: :allow_all
84
+ )
85
+ payload = payload_parsed(:pull_request_reopened)
86
+
87
+ assert_difference -> { Shipit::PullRequest.count } do
88
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
89
+ end
90
+ end
91
+
92
+ test "unarchives stacks for repos that allow_with_label when label is present" do
93
+ stack = create_archived_stack
94
+ repository = shipit_repositories(:shipit)
95
+ configure_provisioning_behavior(
96
+ repository: repository,
97
+ behavior: :allow_with_label,
98
+ label: "pull-requests-label"
99
+ )
100
+ payload = payload_parsed(:pull_request_reopened)
101
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
102
+
103
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
104
+
105
+ assert_not stack.reload.archived?, "Expected stack to be NOT be archived"
106
+ assert_pending_provision(stack)
107
+ end
108
+
109
+ test "provisions missing stacks for repos that allow_with_label when label is present" do
110
+ repository = shipit_repositories(:shipit)
111
+ configure_provisioning_behavior(
112
+ repository: repository,
113
+ behavior: :allow_with_label,
114
+ label: "pull-requests-label"
115
+ )
116
+ payload = payload_parsed(:pull_request_reopened)
117
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
118
+
119
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
120
+
121
+ stack = shipit_repositories(:shipit).stacks.last
122
+ assert_equal stack.environment, "pr#{payload['number']}"
123
+ assert_equal stack.continuous_deployment, false
124
+ assert_equal stack.ignore_ci, false
125
+ assert_equal stack.branch, payload["pull_request"]["head"]["ref"]
126
+ assert_not stack.archived?, "Expected stack to be NOT be archived"
127
+ assert_pending_provision(stack)
128
+ end
129
+
130
+ test "does not unarchive stacks for repos that allow_with_label when label is absent" do
131
+ stack = create_archived_stack
132
+ repository = shipit_repositories(:shipit)
133
+ configure_provisioning_behavior(
134
+ repository: repository,
135
+ behavior: :allow_with_label,
136
+ label: "pull-requests-label"
137
+ )
138
+ payload = payload_parsed(:pull_request_reopened)
139
+ payload["pull_request"]["labels"] = []
140
+
141
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
142
+
143
+ assert stack.reload.archived?, "Expected stack to be archived"
144
+ end
145
+
146
+ test "unarchives stacks for repos that prevent_with_label when label is absent" do
147
+ stack = create_archived_stack
148
+ repository = shipit_repositories(:shipit)
149
+ configure_provisioning_behavior(
150
+ repository: repository,
151
+ behavior: :prevent_with_label,
152
+ label: "pull-requests-label"
153
+ )
154
+ payload = payload_parsed(:pull_request_reopened)
155
+ payload["pull_request"]["labels"] = []
156
+
157
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
158
+
159
+ assert_not stack.reload.archived?, "Expected stack to be NOT be archived"
160
+ assert_pending_provision(stack)
161
+ end
162
+
163
+ test "provisions missing stacks for repos that prevent_with_label when label is absent" do
164
+ repository = shipit_repositories(:shipit)
165
+ configure_provisioning_behavior(
166
+ repository: repository,
167
+ behavior: :prevent_with_label,
168
+ label: "pull-requests-label"
169
+ )
170
+ payload = payload_parsed(:pull_request_reopened)
171
+ payload["pull_request"]["labels"] = []
172
+
173
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
174
+
175
+ stack = shipit_repositories(:shipit).stacks.last
176
+ assert_equal stack.environment, "pr#{payload['number']}"
177
+ assert_equal stack.continuous_deployment, false
178
+ assert_equal stack.ignore_ci, false
179
+ assert_equal stack.branch, payload["pull_request"]["head"]["ref"]
180
+ assert_not stack.archived?, "Expected stack to be NOT be archived"
181
+ assert_pending_provision(stack)
182
+ end
183
+
184
+ test "does not unarchive stacks for repos that prevent_with_label when label is present" do
185
+ stack = create_archived_stack
186
+ repository = shipit_repositories(:shipit)
187
+ configure_provisioning_behavior(
188
+ repository: repository,
189
+ behavior: :prevent_with_label,
190
+ label: "pull-requests-label"
191
+ )
192
+ payload = payload_parsed(:pull_request_reopened)
193
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
194
+
195
+ Shipit::Webhooks::Handlers::PullRequest::ReopenedHandler.new(payload).process
196
+
197
+ assert stack.reload.archived?, "Expected stack to be archived"
198
+ end
199
+
200
+ def configure_provisioning_behavior(repository:, provisioning_enabled: true, behavior: :allow_all, label: nil)
201
+ repository.review_stacks_enabled = provisioning_enabled
202
+ repository.provisioning_behavior = behavior
203
+ repository.provisioning_label_name = label
204
+ repository.save!
205
+
206
+ repository
207
+ end
208
+
209
+ def create_archived_stack
210
+ stack = create_stack
211
+ stack.archive!(shipit_users(:codertocat))
212
+
213
+ stack
214
+ end
215
+
216
+ def create_stack
217
+ repository = shipit_repositories(:shipit)
218
+ repository.provisioning_behavior = :allow_all
219
+ repository.save!
220
+
221
+ payload = payload_parsed(:pull_request_labeled)
222
+ payload["action"] = "opened"
223
+
224
+ OpenedHandler.new(payload).process
225
+
226
+ stack = repository.stacks.last
227
+ complete_active_tasks(stack)
228
+
229
+ stack
230
+ end
231
+
232
+ def complete_active_tasks(stack)
233
+ active_tasks = stack
234
+ .tasks
235
+ .active
236
+
237
+ active_tasks.map(&:run)
238
+ active_tasks.reload
239
+ active_tasks.map(&:complete)
240
+ end
241
+
242
+ def assert_pending_provision(stack)
243
+ stack.reload
244
+
245
+ assert(stack.awaiting_provision?, "Stack #{stack.environment} should be in the provisioning queue")
246
+ assert(stack.deprovisioned?, "Stack #{stack.environment} should be pending provision")
247
+ end
248
+
249
+ setup do
250
+ Shipit.github.api.stubs(:commit)
251
+ .with("shopify/shipit-engine", "ec26c3e57ca3a959ca5aad62de7213c562f8c821")
252
+ .returns(
253
+ resource(
254
+ {
255
+ sha: "ec26c3e57ca3a959ca5aad62de7213c562f8c821",
256
+ commit: {
257
+ author: {
258
+ name: "Codertocat",
259
+ email: "21031067+Codertocat@users.noreply.github.com",
260
+ date: "2019-05-15 15:20:30",
261
+ },
262
+ committer: {
263
+ name: "Codertocat",
264
+ email: "21031067+Codertocat@users.noreply.github.com",
265
+ date: "2019-05-15 15:20:30",
266
+ },
267
+ message: "Update README.md",
268
+ },
269
+ stats: {
270
+ total: 2,
271
+ additions: 1,
272
+ deletions: 1,
273
+ },
274
+ }
275
+ )
276
+ )
277
+ end
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ module Webhooks
7
+ module Handlers
8
+ module PullRequest
9
+ class ReviewStackAdapterTest < ActiveSupport::TestCase
10
+ test "unarchive! on an unarchived stack is a no-op" do
11
+ stack = create_stack
12
+ review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
13
+ params_for(stack),
14
+ scope: stack.repository.stacks
15
+ )
16
+ Shipit::ReviewStack.any_instance.expects(:unarchive!).never
17
+ Shipit::ReviewStackProvisioningQueue.expects(:add).never
18
+
19
+ review_stack.unarchive!
20
+ end
21
+
22
+ test "unarchive! syncs with GitHub" do
23
+ stack = create_archived_stack
24
+ review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
25
+ params_for(stack),
26
+ scope: stack.repository.stacks
27
+ )
28
+
29
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id]) do
30
+ review_stack.unarchive!
31
+ end
32
+ end
33
+
34
+ test "unarchive! schedules provisioning" do
35
+ stack = create_archived_stack
36
+ review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
37
+ params_for(stack),
38
+ scope: stack.repository.stacks
39
+ )
40
+
41
+ assert_changes -> { stack.reload.awaiting_provision }, from: false, to: true do
42
+ review_stack.unarchive!
43
+ end
44
+ end
45
+
46
+ test "archive! on an archived stack is a no-op" do
47
+ stack = create_archived_stack
48
+ review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
49
+ params_for(stack),
50
+ scope: stack.repository.stacks
51
+ )
52
+ Shipit::Stack.any_instance.expects(:archive!).never
53
+
54
+ review_stack.archive!
55
+ end
56
+
57
+ test "archive! removes stacks awaiting provisioning from the provisioning queue" do
58
+ stack = create_stack
59
+ stack.enqueue_for_provisioning
60
+ review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
61
+ params_for(stack),
62
+ scope: stack.repository.stacks
63
+ )
64
+
65
+ assert_changes -> { stack.reload.awaiting_provision }, from: true, to: false do
66
+ review_stack.archive!
67
+ end
68
+ end
69
+
70
+ def params_for(stack)
71
+ OpenStruct.new(
72
+ number: pr_number,
73
+ repository: {
74
+ "full_name" => stack.github_repo_name,
75
+ },
76
+ sender: { login: shipit_users(:walrus).login }
77
+ )
78
+ end
79
+
80
+ def create_stack
81
+ stack = shipit_stacks(:review_stack)
82
+ stack.environment = environment
83
+
84
+ stack.save!
85
+
86
+ stack
87
+ end
88
+
89
+ def create_archived_stack
90
+ stack = create_stack
91
+ stack.archive!(shipit_users(:walrus))
92
+
93
+ stack
94
+ end
95
+
96
+ def pr_number
97
+ 1
98
+ end
99
+
100
+ def environment
101
+ "pr#{pr_number}"
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,324 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module Shipit
6
+ module Webhooks
7
+ module Handlers
8
+ module PullRequest
9
+ class UnlabeledHandlerTest < ActiveSupport::TestCase
10
+ test "validates payload" do
11
+ assert_raise(StandardError) { UnlabeledHandler.new(payload_parsed(:invalid_pull_request)) }
12
+ end
13
+
14
+ test "ignores Github webhooks when the event is NOT 'unlabeled'" do
15
+ assert_no_difference -> { Shipit::Stack.not_archived.count } do
16
+ UnlabeledHandler.new(payload_parsed(:pull_request_opened).merge(action: "assigned")).process
17
+ end
18
+ end
19
+
20
+ test "ignores Github PullRequest webhooks by default" do
21
+ UnlabeledHandler.new(payload_parsed(:pull_request_with_no_repo).merge(action: "closed")).process
22
+ end
23
+
24
+ test "ignores Github PullRequest webhooks when the Repository has disabled the Review Stacks feature" do
25
+ repository = shipit_repositories(:shipit)
26
+ configure_provisioning_behavior(
27
+ repository: repository,
28
+ provisioning_enabled: false,
29
+ behavior: :allow_with_label,
30
+ label: "pull-requests-label"
31
+ )
32
+
33
+ assert_no_difference -> { Shipit::Stack.count } do
34
+ UnlabeledHandler.new(payload_parsed(:pull_request_unlabeled)).process
35
+ end
36
+ end
37
+
38
+ test "ignores Github PullRequest webhooks when the repository allows_all PullRequests to create ReviewStacks" do
39
+ assert_no_difference -> { Shipit::Stack.count } do
40
+ UnlabeledHandler.new(payload_parsed(:pull_request_unlabeled)).process
41
+ end
42
+ end
43
+
44
+ test "archives existing review stack when the repository creates ReviewStacks with allow_with_label and the label is absent" do
45
+ stack = create_stack
46
+ repository = shipit_repositories(:shipit)
47
+ configure_provisioning_behavior(
48
+ repository: repository,
49
+ behavior: :allow_with_label,
50
+ label: "pull-requests-label"
51
+ )
52
+
53
+ UnlabeledHandler.new(payload_parsed(:pull_request_unlabeled)).process
54
+
55
+ assert stack.reload.archived?, "Expected stack to be archived"
56
+ end
57
+
58
+ test "deprovisions existing review stack when the repository creates ReviewStacks with allow_with_label and the label is absent" do
59
+ stack = create_stack
60
+ repository = shipit_repositories(:shipit)
61
+ configure_provisioning_behavior(
62
+ repository: repository,
63
+ behavior: :allow_with_label,
64
+ label: "pull-requests-label"
65
+ )
66
+
67
+ UnlabeledHandler.new(payload_parsed(:pull_request_unlabeled)).process
68
+
69
+ assert_equal stack.reload.provision_status, "deprovisioning"
70
+ end
71
+
72
+ test "ignores Github PullRequest webhooks when the repository allow_with_label to create ReviewStacks and the label is absent" do
73
+ repository = shipit_repositories(:shipit)
74
+ configure_provisioning_behavior(
75
+ repository: repository,
76
+ behavior: :allow_with_label,
77
+ label: "pull-requests-label"
78
+ )
79
+
80
+ assert_no_difference -> { Shipit::Stack.count } do
81
+ UnlabeledHandler.new(payload_parsed(:pull_request_unlabeled)).process
82
+ end
83
+ end
84
+
85
+ test "unarchives existing review stack when the repository creates ReviewStacks with allow_with_label and the label is present" do
86
+ stack = create_archived_stack
87
+ repository = shipit_repositories(:shipit)
88
+ configure_provisioning_behavior(
89
+ repository: repository,
90
+ behavior: :allow_with_label,
91
+ label: "pull-requests-label"
92
+ )
93
+ payload = payload_parsed(:pull_request_unlabeled)
94
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
95
+
96
+ UnlabeledHandler.new(payload).process
97
+
98
+ assert_not stack.reload.archived?, "Expected stack to NOT be archived"
99
+ assert_pending_provision(stack)
100
+ end
101
+
102
+ test "creates and provisions a new review stack when the repository creates ReviewStacks with allow_with_label and the label is present" do
103
+ repository = shipit_repositories(:shipit)
104
+ configure_provisioning_behavior(
105
+ repository: repository,
106
+ behavior: :allow_with_label,
107
+ label: "pull-requests-label"
108
+ )
109
+ payload = payload_parsed(:pull_request_unlabeled)
110
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
111
+
112
+ UnlabeledHandler.new(payload).process
113
+
114
+ stack = shipit_repositories(:shipit).stacks.last
115
+ assert_equal stack.environment, "pr#{payload['number']}"
116
+ assert_equal stack.continuous_deployment, false
117
+ assert_equal stack.ignore_ci, false
118
+ assert_equal stack.branch, payload["pull_request"]["head"]["ref"]
119
+ assert_not stack.archived?, "Expected stack to be NOT be archived"
120
+ assert_pending_provision(stack)
121
+ end
122
+
123
+ test "archives an existing review stack when the repository creates ReviewStacks with prevent_with_label and the label is present" do
124
+ stack = create_stack
125
+ repository = shipit_repositories(:shipit)
126
+ configure_provisioning_behavior(
127
+ repository: repository,
128
+ behavior: :prevent_with_label,
129
+ label: "pull-requests-label"
130
+ )
131
+ payload = payload_parsed(:pull_request_unlabeled)
132
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
133
+
134
+ UnlabeledHandler.new(payload).process
135
+
136
+ assert stack.reload.archived?, "Expected stack to be archived"
137
+ end
138
+
139
+ test "deprovisions an existing review stack when the repository creates ReviewStacks with prevent_with_label and the label is present" do
140
+ stack = create_stack
141
+ repository = shipit_repositories(:shipit)
142
+ configure_provisioning_behavior(
143
+ repository: repository,
144
+ behavior: :prevent_with_label,
145
+ label: "pull-requests-label"
146
+ )
147
+ payload = payload_parsed(:pull_request_unlabeled)
148
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
149
+
150
+ UnlabeledHandler.new(payload).process
151
+
152
+ assert_equal stack.reload.provision_status, "deprovisioning"
153
+ end
154
+
155
+ test "ignores Github PullRequest webhooks when the repository prevent_with_label to create ReviewStacks and the label is present" do
156
+ repository = shipit_repositories(:shipit)
157
+ configure_provisioning_behavior(
158
+ repository: repository,
159
+ behavior: :prevent_with_label,
160
+ label: "pull-requests-label"
161
+ )
162
+ payload = payload_parsed(:pull_request_unlabeled)
163
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
164
+
165
+ assert_no_difference -> { Shipit::Stack.count } do
166
+ UnlabeledHandler.new(payload).process
167
+ end
168
+ end
169
+
170
+ test "unarchives an existing review stack when the repository creates ReviewStacks with prevent_with_label and the label is absent" do
171
+ stack = create_archived_stack
172
+ repository = shipit_repositories(:shipit)
173
+ configure_provisioning_behavior(
174
+ repository: repository,
175
+ behavior: :prevent_with_label,
176
+ label: "pull-requests-label"
177
+ )
178
+ payload = payload_parsed(:pull_request_unlabeled)
179
+ payload["pull_request"]["labels"] = []
180
+
181
+ UnlabeledHandler.new(payload).process
182
+
183
+ assert_not stack.reload.archived?, "Expected stack to NOT be archived"
184
+ assert_pending_provision(stack)
185
+ end
186
+
187
+ test "creates and provisions a new review stack when the repository creates ReviewStacks with prevent_with_label and the label is absent" do
188
+ repository = shipit_repositories(:shipit)
189
+ configure_provisioning_behavior(
190
+ repository: repository,
191
+ behavior: :prevent_with_label,
192
+ label: "pull-requests-label"
193
+ )
194
+ payload = payload_parsed(:pull_request_unlabeled)
195
+ payload["pull_request"]["labels"] = []
196
+
197
+ UnlabeledHandler.new(payload).process
198
+
199
+ stack = shipit_repositories(:shipit).stacks.last
200
+ assert_equal stack.environment, "pr#{payload['number']}"
201
+ assert_equal stack.continuous_deployment, false
202
+ assert_equal stack.ignore_ci, false
203
+ assert_equal stack.branch, payload["pull_request"]["head"]["ref"]
204
+ assert_not stack.archived?, "Expected stack to be NOT be archived"
205
+ assert_pending_provision(stack)
206
+ end
207
+
208
+ test "assigns the PullRequest to newly created stacks" do
209
+ repository = shipit_repositories(:shipit)
210
+ configure_provisioning_behavior(
211
+ repository: repository,
212
+ behavior: :prevent_with_label,
213
+ label: "pull-requests-label"
214
+ )
215
+ payload = payload_parsed(:pull_request_unlabeled)
216
+ payload["pull_request"]["labels"] = []
217
+
218
+ assert_difference -> { Shipit::PullRequest.count } do
219
+ UnlabeledHandler.new(payload).process
220
+ end
221
+ end
222
+
223
+ test "ignores Github Webhooks for closed PullRequests" do
224
+ create_archived_stack
225
+ repository = shipit_repositories(:shipit)
226
+ configure_provisioning_behavior(
227
+ repository: repository,
228
+ behavior: :allow_with_label,
229
+ label: "pull-requests-label"
230
+ )
231
+ payload = payload_parsed(:pull_request_unlabeled)
232
+ payload["pull_request"]["labels"] << { "name" => "pull-requests-label" }
233
+ payload["pull_request"]["state"] = "closed"
234
+
235
+ Shipit::ReviewStackProvisioningQueue.expects(:add).never
236
+
237
+ UnlabeledHandler.new(payload).process
238
+ end
239
+
240
+ def configure_provisioning_behavior(repository:, provisioning_enabled: true, behavior: :allow_all, label: nil)
241
+ repository.review_stacks_enabled = provisioning_enabled
242
+ repository.provisioning_behavior = behavior
243
+ repository.provisioning_label_name = label
244
+ repository.save!
245
+
246
+ repository
247
+ end
248
+
249
+ def create_archived_stack
250
+ stack = create_stack
251
+ stack.update(provision_status: :deprovisioned)
252
+ stack.archive!(shipit_users(:codertocat))
253
+
254
+ stack
255
+ end
256
+
257
+ def create_stack
258
+ repository = shipit_repositories(:shipit)
259
+ repository.provisioning_behavior = :allow_all
260
+ repository.save!
261
+
262
+ payload = payload_parsed(:pull_request_labeled)
263
+ payload["action"] = "opened"
264
+
265
+ OpenedHandler.new(payload).process
266
+
267
+ stack = repository.stacks.last
268
+ stack.update(provision_status: :provisioned)
269
+ complete_active_tasks(stack)
270
+
271
+ stack
272
+ end
273
+
274
+ def complete_active_tasks(stack)
275
+ active_tasks = stack
276
+ .tasks
277
+ .active
278
+
279
+ active_tasks.map(&:run)
280
+ active_tasks.reload
281
+ active_tasks.map(&:complete)
282
+ end
283
+
284
+ def assert_pending_provision(stack)
285
+ stack.reload
286
+
287
+ assert(stack.awaiting_provision?, "Stack #{stack.environment} should be in the provisioning queue")
288
+ assert(stack.deprovisioned?, "Stack #{stack.environment} should be pending provision")
289
+ end
290
+
291
+ setup do
292
+ Shipit.github.api.stubs(:commit)
293
+ .with("shopify/shipit-engine", "ec26c3e57ca3a959ca5aad62de7213c562f8c821")
294
+ .returns(
295
+ resource(
296
+ {
297
+ sha: "ec26c3e57ca3a959ca5aad62de7213c562f8c821",
298
+ commit: {
299
+ author: {
300
+ name: "Codertocat",
301
+ email: "21031067+Codertocat@users.noreply.github.com",
302
+ date: "2019-05-15 15:20:30",
303
+ },
304
+ committer: {
305
+ name: "Codertocat",
306
+ email: "21031067+Codertocat@users.noreply.github.com",
307
+ date: "2019-05-15 15:20:30",
308
+ },
309
+ message: "Update README.md",
310
+ },
311
+ stats: {
312
+ total: 2,
313
+ additions: 1,
314
+ deletions: 1,
315
+ },
316
+ }
317
+ )
318
+ )
319
+ end
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end