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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
4
5
  class DeploysTest < ActiveSupport::TestCase
5
6
  def setup
6
7
  @deploy = shipit_deploys(:shipit)
8
+ @deploy.write("dummy output")
7
9
  @deploy.pid = 42
8
10
  @stack = shipit_stacks(:shipit)
9
11
  @user = shipit_users(:walrus)
@@ -59,6 +61,146 @@ module Shipit
59
61
  assert_equal [], @deploy.commits
60
62
  end
61
63
 
64
+ test "deploys retry up to limit upon timeout when configured" do
65
+ runnable_deploy = shipit_deploys(:shipit_pending)
66
+ deploy_stack = runnable_deploy.stack
67
+
68
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock).twice
69
+ .raises(Shipit::Command::TimedOut, 'Deploy timed out')
70
+ .then.raises(Shipit::Command::Error, "Second command error failure")
71
+
72
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
73
+ runnable_deploy.enqueue
74
+ end
75
+ assert_performed_jobs 2
76
+
77
+ runnable_deploy.reload
78
+ assert_equal 'timedout', runnable_deploy.status
79
+
80
+ retried_deploy = deploy_stack.deploys.last
81
+ assert_not_equal runnable_deploy.id, retried_deploy.id
82
+ assert_equal runnable_deploy.since_commit, retried_deploy.since_commit
83
+ assert_equal runnable_deploy.until_commit, retried_deploy.until_commit
84
+ assert_equal 'failed', retried_deploy.status
85
+ assert_equal 1, retried_deploy.retry_attempt
86
+ end
87
+
88
+ test "deploys retry up to limit upon failure when configured" do
89
+ runnable_deploy = shipit_deploys(:shipit_pending)
90
+ deploy_stack = runnable_deploy.stack
91
+
92
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock).twice
93
+ .raises(Shipit::Command::Error, 'Deploy failed')
94
+ .then.raises(Shipit::Command::Error, "Second deploy failed")
95
+
96
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
97
+ runnable_deploy.enqueue
98
+ end
99
+ assert_performed_jobs 2
100
+
101
+ runnable_deploy.reload
102
+ assert_equal 'failed', runnable_deploy.status
103
+
104
+ retried_deploy = deploy_stack.deploys.last
105
+ assert_not_equal runnable_deploy.id, retried_deploy.id
106
+ assert_equal runnable_deploy.since_commit, retried_deploy.since_commit
107
+ assert_equal runnable_deploy.until_commit, retried_deploy.until_commit
108
+ assert_equal 'failed', retried_deploy.status
109
+ assert_equal 1, retried_deploy.retry_attempt
110
+ end
111
+
112
+ test "deploys retry up to limit upon error when configured" do
113
+ runnable_deploy = shipit_deploys(:shipit_pending)
114
+ deploy_stack = runnable_deploy.stack
115
+
116
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock).twice
117
+ .raises(StandardError, 'Deploy failed')
118
+ .then.raises(StandardError, "Second deploy failed")
119
+
120
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
121
+ runnable_deploy.enqueue
122
+ end
123
+ assert_performed_jobs 2
124
+
125
+ runnable_deploy.reload
126
+ assert_equal 'error', runnable_deploy.status
127
+
128
+ retried_deploy = deploy_stack.deploys.last
129
+ assert_not_equal runnable_deploy.id, retried_deploy.id
130
+ assert_equal runnable_deploy.since_commit, retried_deploy.since_commit
131
+ assert_equal runnable_deploy.until_commit, retried_deploy.until_commit
132
+ assert_equal 'error', retried_deploy.status
133
+ assert_equal 1, retried_deploy.retry_attempt
134
+ end
135
+
136
+ test "deploys do not retry upon timeout when not configured" do
137
+ runnable_deploy = shipit_deploys(:shipit_pending)
138
+ runnable_deploy.update!(retry_attempt: 0, max_retries: 0)
139
+
140
+ Shipit::Deploy.any_instance.expects(:acquire_git_cache_lock)
141
+ .raises(Shipit::Command::TimedOut, 'Deploy timed out')
142
+
143
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
144
+ runnable_deploy.enqueue
145
+ end
146
+ assert_performed_jobs 1
147
+
148
+ runnable_deploy.reload
149
+
150
+ assert_equal 'timedout', runnable_deploy.status
151
+ end
152
+
153
+ test "rollbacks retry on timeouts if configured" do
154
+ deploy = shipit_deploys(:shipit)
155
+ deploy_stack = deploy.stack
156
+
157
+ DeploySpec.any_instance.expects(:retries_on_rollback).returns(1)
158
+
159
+ Shipit::Command.any_instance.expects(:run).twice
160
+ .raises(Shipit::Command::TimedOut, 'Rollback timed out')
161
+ .then.raises(Shipit::Command::Error, "Second command error failure")
162
+
163
+ first_rollback = nil
164
+
165
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
166
+ first_rollback = deploy.trigger_rollback(@user, force: true)
167
+ end
168
+ assert_performed_jobs 2
169
+
170
+ first_rollback.reload
171
+
172
+ assert_equal 'timedout', first_rollback.status
173
+ retried_rollback = deploy_stack.deploys_and_rollbacks.last
174
+
175
+ assert_not_equal first_rollback.id, retried_rollback.id
176
+ assert_equal first_rollback.since_commit, retried_rollback.since_commit
177
+ assert_equal first_rollback.until_commit, retried_rollback.until_commit
178
+ assert_equal 'failed', retried_rollback.status
179
+ assert_equal 1, retried_rollback.max_retries
180
+ end
181
+
182
+ test "rollbacks do not retry if not configured" do
183
+ deploy_stack = @deploy.stack
184
+
185
+ DeploySpec.any_instance.expects(:retries_on_rollback).returns(0)
186
+
187
+ Shipit::Command.any_instance.expects(:run).once
188
+ .raises(Shipit::Command::TimedOut, 'Rollback timed out')
189
+ .then.raises(Shipit::Command::Error, "Second command error failure")
190
+
191
+ first_rollback = nil
192
+
193
+ perform_enqueued_jobs(only: Shipit::PerformTaskJob) do
194
+ first_rollback = @deploy.trigger_rollback(@user, force: true)
195
+ end
196
+ assert_performed_jobs 1
197
+
198
+ first_rollback.reload
199
+
200
+ assert_equal 'timedout', first_rollback.status
201
+ assert_equal first_rollback, deploy_stack.deploys_and_rollbacks.last
202
+ end
203
+
62
204
  test "additions and deletions are denormalized on before create" do
63
205
  stack = shipit_stacks(:shipit)
64
206
  first = shipit_commits(:first)
@@ -199,7 +341,7 @@ module Shipit
199
341
  since_commit: shipit.commits.first,
200
342
  until_commit: shipit.commits.last,
201
343
  )
202
- deploy.stubs(:pull_request_head_for_commit).returns(nil)
344
+ deploy.stubs(:merge_request_head_for_commit).returns(nil)
203
345
 
204
346
  expect_event(deploy)
205
347
  deploy.save!
@@ -247,6 +389,8 @@ module Shipit
247
389
  end
248
390
 
249
391
  test "transitioning to success enqueues a last-deployed git reference update" do
392
+ Shipit.stubs(:update_latest_deployed_ref).returns(true)
393
+
250
394
  @deploy = shipit_deploys(:shipit_running)
251
395
  assert_enqueued_with(job: UpdateGithubLastDeployedRefJob, args: [@deploy.stack]) do
252
396
  @deploy.complete!
@@ -260,9 +404,9 @@ module Shipit
260
404
  assert_in_delta @deploy.ended_at, @stack.last_deployed_at, 2
261
405
  end
262
406
 
263
- test "transitioning to success schedule a MergePullRequests job" do
407
+ test "transitioning to success schedule a MergeMergeRequests job" do
264
408
  @deploy = shipit_deploys(:shipit_running)
265
- assert_enqueued_with(job: MergePullRequestsJob, args: [@deploy.stack]) do
409
+ assert_enqueued_with(job: ProcessMergeRequestsJob, args: [@deploy.stack]) do
266
410
  @deploy.complete!
267
411
  end
268
412
  end
@@ -301,6 +445,20 @@ module Shipit
301
445
  end
302
446
  end
303
447
 
448
+ test "transitioning to aborted schedule a rollback to the designated deploy if set" do
449
+ @rollback_to = shipit_deploys(:shipit_pending)
450
+ @deploy = shipit_deploys(:shipit_running)
451
+ @deploy.ping
452
+ @deploy.pid = 42
453
+ @deploy.abort!(rollback_once_aborted: true, rollback_once_aborted_to: @rollback_to, aborted_by: @user)
454
+
455
+ assert_difference -> { @stack.rollbacks.count }, 1 do
456
+ assert_enqueued_with(job: PerformTaskJob) do
457
+ @deploy.aborted!
458
+ end
459
+ end
460
+ end
461
+
304
462
  test "#build_rollback returns an unsaved record" do
305
463
  assert @deploy.build_rollback.new_record?
306
464
  end
@@ -376,7 +534,7 @@ module Shipit
376
534
  # Check that the next item in the series is 1 greater than the last.
377
535
  def assert_generated_record_ids_are_sequential(record_id_series)
378
536
  record_id_series[0..-2].each_with_index do |id_element, index|
379
- assert_equal id_element + 1, record_id_series[index + 1]
537
+ assert_equal(id_element + 1, record_id_series[index + 1])
380
538
  end
381
539
  end
382
540
 
@@ -429,6 +587,20 @@ module Shipit
429
587
  assert_equal "Shipit::Rollback", last_deploy.type
430
588
  end
431
589
 
590
+ test "#trigger_revert uses rollback_to if set" do
591
+ test_stack = create_test_stack
592
+ test_stack.save
593
+ test_stack.reload
594
+
595
+ running_deploy = shipit_deploys(:shipit_running)
596
+ rollback_to = shipit_deploys(:shipit_pending)
597
+
598
+ final_rollback = running_deploy.trigger_revert(rollback_to: rollback_to)
599
+
600
+ assert_equal "Shipit::Rollback", final_rollback.type
601
+ assert_equal 4, final_rollback.until_commit_id
602
+ end
603
+
432
604
  test "#trigger_revert skips unsuccessful deploys when reverting" do
433
605
  user_id = @user.id
434
606
  test_stack = create_test_stack
@@ -630,6 +802,12 @@ module Shipit
630
802
  assert_equal @user, @stack.lock_author
631
803
  end
632
804
 
805
+ test "#trigger_rollback does not lock the stack if not requested" do
806
+ refute @stack.locked?
807
+ @deploy.trigger_rollback(@user, lock: false)
808
+ refute @stack.reload.locked?
809
+ end
810
+
633
811
  test "#trigger_rollback marks the rollback as `ignored_safeties` if the force option was used" do
634
812
  rollback = @deploy.trigger_rollback(@user, force: true)
635
813
  assert_predicate rollback, :ignored_safeties?
@@ -668,20 +846,13 @@ module Shipit
668
846
  assert_predicate @deploy, :error?
669
847
  end
670
848
 
671
- test "destroy deletes the related output chunks" do
672
- assert_difference -> { @deploy.chunks.count }, -@deploy.chunks.count do
673
- @deploy.destroy
674
- end
675
- end
676
-
677
- test "#chunk_output joins all chunk test if logs not rolled up" do
678
- assert_equal @deploy.chunks.count, @deploy.chunks.count
679
- assert_equal @deploy.chunks.pluck(:text).join, @deploy.chunk_output
849
+ test "#chunk_output fetches from Redis if logs not rolled up" do
850
+ assert_equal Shipit.redis.get(@deploy.send(:output_key)), @deploy.chunk_output
680
851
  refute @deploy.rolled_up
681
852
  end
682
853
 
683
854
  test "#chunk_output returns logs from records if rolled up" do
684
- expected_output = @deploy.chunks.pluck(:text).join
855
+ expected_output = Shipit.redis.get(@deploy.send(:output_key))
685
856
  @deploy.rollup_chunks
686
857
 
687
858
  assert_no_queries do
@@ -802,6 +973,18 @@ module Shipit
802
973
  end
803
974
  end
804
975
 
976
+ test "succeeding a deploy sets the release status as pending and does not schedule job if the status delay is negative (-1)" do
977
+ @deploy = shipit_deploys(:canaries_running)
978
+ @deploy.stack.expects(:release_status_delay).at_least_once.returns(Duration.parse(-1))
979
+
980
+ assert_difference -> { ReleaseStatus.count }, +1 do
981
+ assert_not_equal 'success', @deploy.last_release_status.state
982
+ @deploy.report_complete!
983
+ assert_equal 'validating', @deploy.status
984
+ assert_equal 'pending', @deploy.last_release_status.state
985
+ end
986
+ end
987
+
805
988
  test "triggering a rollback via abort! sets the release status as failure" do
806
989
  @deploy = shipit_deploys(:canaries_running)
807
990
  @deploy.ping
@@ -865,9 +1048,6 @@ module Shipit
865
1048
  until_commit: template_task.until_commit,
866
1049
  )
867
1050
 
868
- pull_request_response = stub(head: stub(sha: '6dcb09b5b57875f334f61aebed695e2e4193db5e'))
869
- Shipit.github.api.expects(:pull_request).with('shopify/shipit-engine', 7).returns(pull_request_response)
870
-
871
1051
  expected_delta = deploy.commits.select(&:pull_request?).size + 1
872
1052
  assert_difference -> { CommitDeployment.count }, expected_delta do
873
1053
  assert_difference -> { CommitDeploymentStatus.count }, expected_delta do
@@ -879,25 +1059,6 @@ module Shipit
879
1059
  refute_nil CommitDeployment.find_by(sha: deploy.until_commit.sha)
880
1060
  end
881
1061
 
882
- test "#create_commit_deployments handles API errors when loading pull request details" do
883
- template_task = shipit_tasks(:shipit_pending)
884
- deploy = template_task.stack.deploys.build(
885
- since_commit: template_task.since_commit,
886
- until_commit: template_task.until_commit,
887
- )
888
-
889
- Shipit.github.api.expects(:pull_request).with('shopify/shipit-engine', 7).raises(Octokit::NotFound)
890
-
891
- expected_delta = 1 # Only the batch head
892
- assert_difference -> { CommitDeployment.count }, expected_delta do
893
- assert_difference -> { CommitDeploymentStatus.count }, expected_delta do
894
- deploy.save!
895
- end
896
- end
897
-
898
- refute_nil CommitDeployment.find_by(sha: deploy.until_commit.sha)
899
- end
900
-
901
1062
  private
902
1063
 
903
1064
  def expect_event(deploy)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -35,6 +36,35 @@ module Shipit
35
36
  end
36
37
  end
37
38
 
39
+ test ".deliver! sends request with correct method, headers, and body" do
40
+ stub_request(:post, @hook.delivery_url).to_return(body: 'OK')
41
+ body = { 'foo' => 42 }
42
+ expected_body = JSON.pretty_generate(body)
43
+ expected_signature = Hook::DeliverySigner.new(@hook.secret).sign(expected_body)
44
+
45
+ perform_enqueued_jobs(only: DeliverHookJob) do
46
+ @hook.deliver!(:deploy, body)
47
+ end
48
+ assert_performed_jobs 1
49
+ assert_requested :post, @hook.delivery_url do |req|
50
+ req.headers['X-Shipit-Signature'] == expected_signature
51
+ end
52
+ end
53
+
54
+ test ".deliver! sends without signature if no secret is configured" do
55
+ stub_request(:post, @hook.delivery_url).to_return(body: 'OK')
56
+ @hook.update!(secret: '')
57
+ body = { 'foo' => 42 }
58
+
59
+ perform_enqueued_jobs(only: DeliverHookJob) do
60
+ @hook.deliver!(:deploy, body)
61
+ end
62
+ assert_performed_jobs 1
63
+ assert_requested :post, @hook.delivery_url do |req|
64
+ !req.headers.key?('X-Shipit-Signature')
65
+ end
66
+ end
67
+
38
68
  test ".scoped? returns true if the hook has a stack_id" do
39
69
  @hook.stack_id = nil
40
70
  refute @hook.scoped?
@@ -50,22 +80,29 @@ module Shipit
50
80
  end
51
81
 
52
82
  test ".emit calls #deliver on internal hooks" do
53
- original_receivers = Shipit.internal_hook_receivers
54
- FakeReceiver = Module.new
55
- FakeReceiver.expects(:deliver).with(:deploy, @stack, 'foo' => 42)
83
+ original_receivers = Shipit.internal_hook_receivers
84
+ FakeReceiver = Module.new
85
+ FakeReceiver.expects(:deliver).with(:deploy, @stack, 'foo' => 42)
56
86
 
57
- Shipit.internal_hook_receivers << FakeReceiver
58
- Hook.emit(:deploy, @stack, 'foo' => 42)
87
+ Shipit.internal_hook_receivers << FakeReceiver
88
+ Hook.emit(:deploy, @stack, 'foo' => 42)
59
89
  ensure
60
- Shipit.internal_hook_receivers = original_receivers
90
+ Shipit.internal_hook_receivers = original_receivers
61
91
  end
62
92
 
63
93
  test ".emit calls no internal hooks if there are no internal_hook_receivers" do
64
- original_receivers = Shipit.internal_hook_receivers
65
- Shipit.internal_hook_receivers = nil
66
- Hook.emit(:deploy, @stack, 'foo' => 42)
94
+ original_receivers = Shipit.internal_hook_receivers
95
+ Shipit.internal_hook_receivers = nil
96
+ Hook.emit(:deploy, @stack, 'foo' => 42)
67
97
  ensure
68
- Shipit.internal_hook_receivers = original_receivers
98
+ Shipit.internal_hook_receivers = original_receivers
99
+ end
100
+
101
+ test ".coerce_payload coerces anonymous user correctly" do
102
+ locked_stack = Stack.first
103
+ locked_stack.lock("Some Reason", nil)
104
+ serialized = Hook.coerce_payload(stack: locked_stack)
105
+ assert_json_document(serialized, "stack.lock_author.anonymous", true)
69
106
  end
70
107
  end
71
108
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -1,24 +1,25 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
4
- class PullRequestTest < ActiveSupport::TestCase
5
+ class MergeRequestTest < ActiveSupport::TestCase
5
6
  setup do
6
7
  @stack = shipit_stacks(:shipit)
7
- @pr = shipit_pull_requests(:shipit_pending)
8
+ @pr = shipit_merge_requests(:shipit_pending)
8
9
  @user = shipit_users(:walrus)
9
10
  end
10
11
 
11
12
  test ".request_merge! creates a record and schedule a refresh" do
12
- pull_request = nil
13
- assert_enqueued_with(job: RefreshPullRequestJob) do
14
- pull_request = PullRequest.request_merge!(@stack, 64, @user)
13
+ merge_request = nil
14
+ assert_enqueued_with(job: RefreshMergeRequestJob) do
15
+ merge_request = MergeRequest.request_merge!(@stack, 64, @user)
15
16
  end
16
- assert_predicate pull_request, :persisted?
17
+ assert_predicate merge_request, :persisted?
17
18
  end
18
19
 
19
20
  test ".request_merge! only track pull requests once" do
20
- assert_difference -> { PullRequest.count }, +1 do
21
- 5.times { PullRequest.request_merge!(@stack, 999, @user) }
21
+ assert_difference -> { MergeRequest.count }, +1 do
22
+ 5.times { MergeRequest.request_merge!(@stack, 999, @user) }
22
23
  end
23
24
  end
24
25
 
@@ -26,7 +27,7 @@ module Shipit
26
27
  original_merge_requested_at = @pr.merge_requested_at
27
28
  @pr.cancel!
28
29
  assert_predicate @pr, :canceled?
29
- PullRequest.request_merge!(@stack, @pr.number, @user)
30
+ MergeRequest.request_merge!(@stack, @pr.number, @user)
30
31
  assert_predicate @pr.reload, :pending?
31
32
  assert_not_equal original_merge_requested_at, @pr.merge_requested_at
32
33
  assert_in_delta Time.now.utc, @pr.merge_requested_at, 2
@@ -36,7 +37,7 @@ module Shipit
36
37
  original_merge_requested_at = @pr.merge_requested_at
37
38
  @pr.reject!('merge_conflict')
38
39
  assert_predicate @pr, :rejected?
39
- PullRequest.request_merge!(@stack, @pr.number, @user)
40
+ MergeRequest.request_merge!(@stack, @pr.number, @user)
40
41
  assert_predicate @pr.reload, :pending?
41
42
  assert_not_equal original_merge_requested_at, @pr.merge_requested_at
42
43
  assert_in_delta Time.now.utc, @pr.merge_requested_at, 2
@@ -47,29 +48,29 @@ module Shipit
47
48
  original_merge_requested_at = @pr.merge_requested_at
48
49
  @pr.revalidate!
49
50
  assert_predicate @pr, :revalidating?
50
- PullRequest.request_merge!(@stack, @pr.number, @user)
51
+ MergeRequest.request_merge!(@stack, @pr.number, @user)
51
52
  assert_predicate @pr.reload, :pending?
52
53
  assert_equal original_merge_requested_at, @pr.merge_requested_at
53
54
  end
54
55
 
55
56
  test ".extract_number can get a pull request number from different formats" do
56
- assert_equal 42, PullRequest.extract_number(@stack, '42')
57
- assert_equal 42, PullRequest.extract_number(@stack, '#42')
58
- assert_equal 42, PullRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
57
+ assert_equal 42, MergeRequest.extract_number(@stack, '42')
58
+ assert_equal 42, MergeRequest.extract_number(@stack, '#42')
59
+ assert_equal 42, MergeRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
59
60
 
60
- assert_nil PullRequest.extract_number(@stack, 'https://github.com/ACME/shipit-engine/pull/42')
61
+ assert_nil MergeRequest.extract_number(@stack, 'https://github.com/ACME/shipit-engine/pull/42')
61
62
 
62
- Shipit.github.expects(:domain).returns('github.acme.com').at_least_once
63
- assert_equal 42, PullRequest.extract_number(@stack, 'https://github.acme.com/Shopify/shipit-engine/pull/42')
64
- assert_nil PullRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
63
+ Shipit.github.class.any_instance.expects(:domain).returns('github.acme.com').at_least_once
64
+ assert_equal 42, MergeRequest.extract_number(@stack, 'https://github.acme.com/Shopify/shipit-engine/pull/42')
65
+ assert_nil MergeRequest.extract_number(@stack, 'https://github.com/Shopify/shipit-engine/pull/42')
65
66
  end
66
67
 
67
68
  test "refresh! pulls state from GitHub" do
68
- pull_request = shipit_pull_requests(:shipit_fetching)
69
+ merge_request = shipit_merge_requests(:shipit_fetching)
69
70
 
70
71
  head_sha = '64b3833d39def7ec65b57b42f496eb27ab4980b6'
71
72
  base_sha = 'ba7ab50e02286f7d6c60c1ef75258133dd9ea763'
72
- Shipit.github.api.expects(:pull_request).with(@stack.github_repo_name, pull_request.number).returns(
73
+ Shipit.github.api.expects(:pull_request).with(@stack.github_repo_name, merge_request.number).returns(
73
74
  stub(
74
75
  id: 4_857_578,
75
76
  url: 'https://api.github.com/repos/Shopify/shipit-engine/pulls/64',
@@ -124,15 +125,30 @@ module Shipit
124
125
  created_at: 1.day.ago,
125
126
  )])
126
127
 
127
- pull_request.refresh!
128
-
129
- assert_predicate pull_request, :mergeable?
130
- assert_predicate pull_request, :pending?
131
- assert_equal 'super-branch', pull_request.branch
132
-
133
- assert_not_nil pull_request.head
134
- assert_predicate pull_request.head, :detached?
135
- assert_predicate pull_request.head, :success?
128
+ Shipit.github.api.expects(:check_runs).with(@stack.github_repo_name, head_sha).returns(stub(
129
+ check_runs: [stub(
130
+ id: 123456,
131
+ name: 'check run',
132
+ conclusion: 'success',
133
+ output: stub(
134
+ title: 'a test checkrun',
135
+ ),
136
+ details_url: 'http://example.com',
137
+ html_url: 'http://example.com',
138
+ completed_at: Time.now,
139
+ started_at: 1.minute.ago,
140
+ )]
141
+ ))
142
+
143
+ merge_request.refresh!
144
+
145
+ assert_predicate merge_request, :mergeable?
146
+ assert_predicate merge_request, :pending?
147
+ assert_equal 'super-branch', merge_request.branch
148
+
149
+ assert_not_nil merge_request.head
150
+ assert_predicate merge_request.head, :detached?
151
+ assert_predicate merge_request.head, :success?
136
152
  end
137
153
 
138
154
  test "#reject! records the reason" do
@@ -215,11 +231,11 @@ module Shipit
215
231
  assert_equal 'requires_rebase', @pr.rejection_reason
216
232
  end
217
233
 
218
- test "#merge! raises a PullRequest::NotReady if the PR isn't mergeable yet" do
234
+ test "#merge! raises a MergeRequest::NotReady if the PR isn't mergeable yet" do
219
235
  @pr.update!(mergeable: nil)
220
236
 
221
237
  assert_predicate @pr, :not_mergeable_yet?
222
- assert_raises PullRequest::NotReady do
238
+ assert_raises MergeRequest::NotReady do
223
239
  @pr.merge!
224
240
  end
225
241
  @pr.reload
@@ -232,9 +248,9 @@ module Shipit
232
248
  end
233
249
  params = job.arguments.first
234
250
  assert_equal 'merge', params[:event]
235
- assert_json 'status', 'rejected', document: params[:payload]
236
- assert_json 'pull_request.rejection_reason', 'merge_conflict', document: params[:payload]
237
- assert_json 'pull_request.number', @pr.number, document: params[:payload]
251
+ assert_json_document params[:payload], 'status', 'rejected'
252
+ assert_json_document params[:payload], 'merge_request.rejection_reason', 'merge_conflict'
253
+ assert_json_document params[:payload], 'merge_request.number', @pr.number
238
254
  end
239
255
 
240
256
  test "#merge! doesnt delete the branch if there are open PRs against it" do
@@ -271,7 +287,7 @@ module Shipit
271
287
  behind_by: 10,
272
288
  ),
273
289
  )
274
- spec = {'merge' => {'max_divergence' => {'commits' => 1}}}
290
+ spec = { 'merge' => { 'max_divergence' => { 'commits' => 1 } } }
275
291
  @pr.stack.cached_deploy_spec = DeploySpec.new(spec)
276
292
  assert_predicate @pr, :stale?
277
293
  end
@@ -279,14 +295,14 @@ module Shipit
279
295
  test "#stale? returns true when the branch falls behind the maximum age" do
280
296
  @pr.base_commit = shipit_commits(:second)
281
297
  @pr.head.committed_at = 2.hours.ago
282
- spec = {'merge' => {'max_divergence' => {'age' => '1h'}}}
298
+ spec = { 'merge' => { 'max_divergence' => { 'age' => '1h' } } }
283
299
  @pr.stack.cached_deploy_spec = DeploySpec.new(spec)
284
300
  assert_predicate @pr, :stale?
285
301
  end
286
302
 
287
303
  test "#stale? is false when base_commit information is missing" do
288
304
  @pr.base_commit = nil
289
- spec = {'merge' => {'max_divergence' => {'age' => '1h', 'commits' => 10}}}
305
+ spec = { 'merge' => { 'max_divergence' => { 'age' => '1h', 'commits' => 10 } } }
290
306
  @pr.stack.cached_deploy_spec = DeploySpec.new(spec)
291
307
  refute_predicate @pr, :stale?
292
308
  end