shipit-engine 0.38.0 → 0.40.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 (323) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -4
  3. data/Rakefile +2 -1
  4. data/app/assets/javascripts/shipit/continuous_delivery_schedule.js.coffee +15 -0
  5. data/app/controllers/concerns/shipit/active_model_serializers_patch.rb +1 -0
  6. data/app/controllers/concerns/shipit/api/cacheable.rb +1 -0
  7. data/app/controllers/concerns/shipit/api/paginable.rb +3 -2
  8. data/app/controllers/concerns/shipit/api/rendering.rb +1 -0
  9. data/app/controllers/concerns/shipit/authentication.rb +1 -0
  10. data/app/controllers/concerns/shipit/pagination.rb +3 -2
  11. data/app/controllers/shipit/api/base_controller.rb +12 -10
  12. data/app/controllers/shipit/api/ccmenu_controller.rb +2 -1
  13. data/app/controllers/shipit/api/commits_controller.rb +2 -3
  14. data/app/controllers/shipit/api/deploys_controller.rb +6 -1
  15. data/app/controllers/shipit/api/hooks_controller.rb +4 -3
  16. data/app/controllers/shipit/api/locks_controller.rb +1 -0
  17. data/app/controllers/shipit/api/merge_requests_controller.rb +6 -5
  18. data/app/controllers/shipit/api/outputs_controller.rb +1 -0
  19. data/app/controllers/shipit/api/release_statuses_controller.rb +2 -1
  20. data/app/controllers/shipit/api/rollbacks_controller.rb +1 -0
  21. data/app/controllers/shipit/api/stacks_controller.rb +15 -14
  22. data/app/controllers/shipit/api/tasks_controller.rb +6 -5
  23. data/app/controllers/shipit/api_clients_controller.rb +6 -7
  24. data/app/controllers/shipit/ccmenu_url_controller.rb +3 -2
  25. data/app/controllers/shipit/commit_checks_controller.rb +2 -1
  26. data/app/controllers/shipit/commits_controller.rb +1 -0
  27. data/app/controllers/shipit/continuous_delivery_schedules_controller.rb +42 -0
  28. data/app/controllers/shipit/deploys_controller.rb +6 -5
  29. data/app/controllers/shipit/github_authentication_controller.rb +6 -0
  30. data/app/controllers/shipit/merge_requests_controller.rb +1 -0
  31. data/app/controllers/shipit/merge_status_controller.rb +30 -26
  32. data/app/controllers/shipit/release_statuses_controller.rb +1 -0
  33. data/app/controllers/shipit/repositories_controller.rb +4 -7
  34. data/app/controllers/shipit/rollbacks_controller.rb +2 -1
  35. data/app/controllers/shipit/shipit_controller.rb +1 -0
  36. data/app/controllers/shipit/stacks_controller.rb +27 -31
  37. data/app/controllers/shipit/status_controller.rb +1 -0
  38. data/app/controllers/shipit/tasks_controller.rb +3 -1
  39. data/app/controllers/shipit/webhooks_controller.rb +2 -1
  40. data/app/helpers/shipit/api_clients_helper.rb +1 -0
  41. data/app/helpers/shipit/chunks_helper.rb +3 -1
  42. data/app/helpers/shipit/deploys_helper.rb +7 -3
  43. data/app/helpers/shipit/github_url_helper.rb +5 -4
  44. data/app/helpers/shipit/merge_status_helper.rb +1 -0
  45. data/app/helpers/shipit/shipit_helper.rb +11 -10
  46. data/app/helpers/shipit/stacks_helper.rb +10 -11
  47. data/app/helpers/shipit/tasks_helper.rb +2 -1
  48. data/app/jobs/shipit/background_job/unique.rb +3 -2
  49. data/app/jobs/shipit/background_job.rb +9 -1
  50. data/app/jobs/shipit/cache_deploy_spec_job.rb +2 -1
  51. data/app/jobs/shipit/chunk_rollup_job.rb +1 -0
  52. data/app/jobs/shipit/clear_git_cache_job.rb +1 -0
  53. data/app/jobs/shipit/continuous_delivery_job.rb +5 -0
  54. data/app/jobs/shipit/create_on_github_job.rb +1 -0
  55. data/app/jobs/shipit/create_release_statuses_job.rb +2 -0
  56. data/app/jobs/shipit/deferred_touch_job.rb +1 -0
  57. data/app/jobs/shipit/deliver_hook_job.rb +1 -0
  58. data/app/jobs/shipit/destroy_job.rb +1 -0
  59. data/app/jobs/shipit/destroy_repository_job.rb +1 -0
  60. data/app/jobs/shipit/destroy_stack_job.rb +36 -15
  61. data/app/jobs/shipit/emit_event_job.rb +1 -0
  62. data/app/jobs/shipit/fetch_commit_stats_job.rb +1 -0
  63. data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -0
  64. data/app/jobs/shipit/github_sync_job.rb +4 -2
  65. data/app/jobs/shipit/mark_deploy_healthy_job.rb +1 -0
  66. data/app/jobs/shipit/perform_commit_checks_job.rb +1 -0
  67. data/app/jobs/shipit/perform_task_job.rb +1 -0
  68. data/app/jobs/shipit/process_merge_requests_job.rb +2 -0
  69. data/app/jobs/shipit/purge_old_deliveries_job.rb +1 -0
  70. data/app/jobs/shipit/reap_dead_tasks_job.rb +1 -0
  71. data/app/jobs/shipit/refresh_check_runs_job.rb +1 -0
  72. data/app/jobs/shipit/refresh_github_user_job.rb +1 -0
  73. data/app/jobs/shipit/refresh_merge_request_job.rb +1 -0
  74. data/app/jobs/shipit/refresh_statuses_job.rb +1 -0
  75. data/app/jobs/shipit/setup_github_hook_job.rb +1 -0
  76. data/app/jobs/shipit/update_estimated_deploy_duration_job.rb +1 -0
  77. data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +6 -7
  78. data/app/models/concerns/shipit/deferred_touch.rb +5 -2
  79. data/app/models/shipit/anonymous_user.rb +4 -5
  80. data/app/models/shipit/api_client.rb +5 -3
  81. data/app/models/shipit/application_record.rb +1 -0
  82. data/app/models/shipit/check_run.rb +7 -6
  83. data/app/models/shipit/command_line_user.rb +4 -5
  84. data/app/models/shipit/commit.rb +46 -32
  85. data/app/models/shipit/commit_checks.rb +4 -2
  86. data/app/models/shipit/commit_deployment.rb +7 -5
  87. data/app/models/shipit/commit_deployment_status.rb +5 -3
  88. data/app/models/shipit/commit_message.rb +2 -0
  89. data/app/models/shipit/continuous_delivery_schedule.rb +84 -0
  90. data/app/models/shipit/delivery.rb +5 -4
  91. data/app/models/shipit/deploy.rb +46 -26
  92. data/app/models/shipit/deploy_spec/bundler_discovery.rb +3 -1
  93. data/app/models/shipit/deploy_spec/capistrano_discovery.rb +1 -0
  94. data/app/models/shipit/deploy_spec/file_system.rb +48 -17
  95. data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +4 -3
  96. data/app/models/shipit/deploy_spec/lerna_discovery.rb +32 -31
  97. data/app/models/shipit/deploy_spec/npm_discovery.rb +18 -13
  98. data/app/models/shipit/deploy_spec/pypi_discovery.rb +5 -4
  99. data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -0
  100. data/app/models/shipit/deploy_spec.rb +25 -30
  101. data/app/models/shipit/deploy_stats.rb +6 -1
  102. data/app/models/shipit/duration.rb +5 -3
  103. data/app/models/shipit/ephemeral_commit_checks.rb +8 -7
  104. data/app/models/shipit/github_hook.rb +1 -0
  105. data/app/models/shipit/github_status.rb +1 -0
  106. data/app/models/shipit/hook.rb +9 -7
  107. data/app/models/shipit/membership.rb +1 -0
  108. data/app/models/shipit/merge_request.rb +26 -16
  109. data/app/models/shipit/output_chunk.rb +1 -0
  110. data/app/models/shipit/provisioning_handler.rb +1 -0
  111. data/app/models/shipit/pull_request.rb +2 -2
  112. data/app/models/shipit/record.rb +1 -0
  113. data/app/models/shipit/release_status.rb +4 -3
  114. data/app/models/shipit/repository.rb +12 -11
  115. data/app/models/shipit/review_stack.rb +3 -1
  116. data/app/models/shipit/review_stack_provisioning_queue.rb +2 -2
  117. data/app/models/shipit/rollback.rb +2 -0
  118. data/app/models/shipit/stack.rb +71 -60
  119. data/app/models/shipit/status/common.rb +1 -0
  120. data/app/models/shipit/status/group.rb +5 -3
  121. data/app/models/shipit/status/missing.rb +2 -1
  122. data/app/models/shipit/status/unknown.rb +1 -0
  123. data/app/models/shipit/status.rb +5 -4
  124. data/app/models/shipit/task.rb +40 -31
  125. data/app/models/shipit/task_definition.rb +10 -7
  126. data/app/models/shipit/task_execution_strategy/default.rb +13 -13
  127. data/app/models/shipit/team.rb +13 -12
  128. data/app/models/shipit/undeployed_commit.rb +8 -3
  129. data/app/models/shipit/unlimited_api_client.rb +2 -2
  130. data/app/models/shipit/user.rb +23 -16
  131. data/app/models/shipit/variable_definition.rb +2 -1
  132. data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +1 -0
  133. data/app/models/shipit/webhooks/handlers/handler.rb +1 -0
  134. data/app/models/shipit/webhooks/handlers/membership_handler.rb +1 -0
  135. data/app/models/shipit/webhooks/handlers/pull_request/assigned_handler.rb +10 -10
  136. data/app/models/shipit/webhooks/handlers/pull_request/closed_handler.rb +1 -1
  137. data/app/models/shipit/webhooks/handlers/pull_request/edited_handler.rb +10 -10
  138. data/app/models/shipit/webhooks/handlers/pull_request/label_capturing_handler.rb +2 -2
  139. data/app/models/shipit/webhooks/handlers/pull_request/labeled_handler.rb +2 -2
  140. data/app/models/shipit/webhooks/handlers/pull_request/reopened_handler.rb +1 -1
  141. data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +3 -3
  142. data/app/models/shipit/webhooks/handlers/pull_request/unlabeled_handler.rb +1 -1
  143. data/app/models/shipit/webhooks/handlers/push_handler.rb +2 -1
  144. data/app/models/shipit/webhooks/handlers/status_handler.rb +1 -0
  145. data/app/models/shipit/webhooks.rb +3 -2
  146. data/app/serializers/concerns/shipit/conditional_attributes.rb +1 -0
  147. data/app/serializers/shipit/anonymous_user_serializer.rb +1 -0
  148. data/app/serializers/shipit/command_line_user_serializer.rb +1 -0
  149. data/app/serializers/shipit/commit_serializer.rb +2 -1
  150. data/app/serializers/shipit/deploy_serializer.rb +1 -0
  151. data/app/serializers/shipit/hook_serializer.rb +1 -0
  152. data/app/serializers/shipit/merge_request_serializer.rb +2 -1
  153. data/app/serializers/shipit/rollback_serializer.rb +1 -0
  154. data/app/serializers/shipit/short_commit_serializer.rb +1 -0
  155. data/app/serializers/shipit/stack_serializer.rb +4 -3
  156. data/app/serializers/shipit/tail_task_serializer.rb +4 -1
  157. data/app/serializers/shipit/task_serializer.rb +1 -0
  158. data/app/serializers/shipit/user_serializer.rb +1 -0
  159. data/app/validators/ascii_only_validator.rb +4 -3
  160. data/app/validators/subset_validator.rb +1 -0
  161. data/app/views/shipit/_variables.html.erb +1 -1
  162. data/app/views/shipit/ccmenu/project.xml.builder +2 -1
  163. data/app/views/shipit/continuous_delivery_schedules/show.html.erb +59 -0
  164. data/app/views/shipit/merge_status/failure.html.erb +1 -1
  165. data/app/views/shipit/missing_settings.html.erb +1 -1
  166. data/app/views/shipit/stacks/_settings_form.erb +1 -0
  167. data/config/initializers/inflections.rb +1 -0
  168. data/config/locales/en.yml +1 -0
  169. data/config/routes.rb +21 -18
  170. data/config/secrets.development.example.yml +1 -1
  171. data/config/secrets.development.shopify.yml +1 -1
  172. data/db/migrate/20240821003007_add_continuous_delivery_schedules.rb +13 -0
  173. data/db/migrate/20250207203053_embiggen_github_ids.rb +8 -0
  174. data/lib/shipit/cast_value.rb +1 -0
  175. data/lib/shipit/command.rb +29 -9
  176. data/lib/shipit/commands.rb +4 -2
  177. data/lib/shipit/csv_serializer.rb +3 -0
  178. data/lib/shipit/deploy_commands.rb +2 -1
  179. data/lib/shipit/engine.rb +6 -5
  180. data/lib/shipit/environment_variables.rb +2 -0
  181. data/lib/shipit/first_parent_commits_iterator.rb +2 -3
  182. data/lib/shipit/flock.rb +11 -9
  183. data/lib/shipit/github_app.rb +14 -16
  184. data/lib/shipit/github_http_cache_middleware.rb +1 -0
  185. data/lib/shipit/null_serializer.rb +1 -0
  186. data/lib/shipit/octokit_check_runs.rb +2 -3
  187. data/lib/shipit/octokit_iterator.rb +2 -0
  188. data/lib/shipit/paginator.rb +1 -0
  189. data/lib/shipit/rollback_commands.rb +2 -1
  190. data/lib/shipit/same_site_cookie_middleware.rb +1 -0
  191. data/lib/shipit/simple_message_verifier.rb +1 -0
  192. data/lib/shipit/stack_commands.rb +35 -27
  193. data/lib/shipit/stat.rb +1 -0
  194. data/lib/shipit/task_commands.rb +7 -6
  195. data/lib/shipit/version.rb +2 -1
  196. data/lib/shipit.rb +30 -17
  197. data/lib/tasks/cron.rake +2 -1
  198. data/lib/tasks/dev.rake +3 -2
  199. data/lib/tasks/shipit.rake +3 -2
  200. data/lib/tasks/teams.rake +3 -2
  201. data/test/controllers/api/base_controller_test.rb +1 -0
  202. data/test/controllers/api/ccmenu_controller_test.rb +4 -3
  203. data/test/controllers/api/commits_controller_test.rb +1 -0
  204. data/test/controllers/api/deploys_controller_test.rb +26 -1
  205. data/test/controllers/api/hooks_controller_test.rb +6 -5
  206. data/test/controllers/api/locks_controller_test.rb +1 -0
  207. data/test/controllers/api/merge_requests_controller_test.rb +1 -0
  208. data/test/controllers/api/outputs_controller_test.rb +1 -0
  209. data/test/controllers/api/release_statuses_controller_test.rb +4 -3
  210. data/test/controllers/api/rollback_controller_test.rb +3 -2
  211. data/test/controllers/api/stacks_controller_test.rb +13 -12
  212. data/test/controllers/api/tasks_controller_test.rb +7 -6
  213. data/test/controllers/api_clients_controller_test.rb +10 -10
  214. data/test/controllers/ccmenu_controller_test.rb +1 -0
  215. data/test/controllers/commit_checks_controller_test.rb +1 -0
  216. data/test/controllers/commits_controller_test.rb +9 -8
  217. data/test/controllers/continuous_delivery_schedules_controller_test.rb +66 -0
  218. data/test/controllers/deploys_controller_test.rb +4 -2
  219. data/test/controllers/github_authentication_controller_test.rb +6 -4
  220. data/test/controllers/merge_requests_controller_test.rb +1 -0
  221. data/test/controllers/merge_status_controller_test.rb +5 -4
  222. data/test/controllers/release_statuses_controller_test.rb +1 -0
  223. data/test/controllers/repositories_controller_test.rb +6 -5
  224. data/test/controllers/rollbacks_controller_test.rb +3 -2
  225. data/test/controllers/stacks_controller_test.rb +8 -6
  226. data/test/controllers/status_controller_test.rb +1 -0
  227. data/test/controllers/tasks_controller_test.rb +13 -5
  228. data/test/controllers/webhooks_controller_test.rb +10 -9
  229. data/test/dummy/config/application.rb +2 -1
  230. data/test/dummy/config/initializers/0_load_development_secrets.rb +2 -2
  231. data/test/dummy/config/secrets.development.json +3 -0
  232. data/test/dummy/config/secrets.test.json +21 -0
  233. data/test/dummy/db/schema.rb +33 -6
  234. data/test/fixtures/shipit/commits.yml +7 -7
  235. data/test/fixtures/shipit/stacks.yml +4 -10
  236. data/test/fixtures/shipit/tasks.yml +3 -3
  237. data/test/helpers/api_helper.rb +2 -3
  238. data/test/helpers/fixture_aliases_helper.rb +1 -0
  239. data/test/helpers/hooks_helper.rb +1 -0
  240. data/test/helpers/json_helper.rb +4 -3
  241. data/test/helpers/links_helper.rb +2 -1
  242. data/test/helpers/payloads_helper.rb +1 -0
  243. data/test/helpers/queries_helper.rb +4 -3
  244. data/test/jobs/cache_deploy_spec_job_test.rb +3 -2
  245. data/test/jobs/chunk_rollup_job_test.rb +3 -2
  246. data/test/jobs/deliver_hook_job_test.rb +1 -0
  247. data/test/jobs/destroy_repository_job_test.rb +1 -0
  248. data/test/jobs/destroy_stack_job_test.rb +12 -0
  249. data/test/jobs/emit_event_job_test.rb +1 -0
  250. data/test/jobs/fetch_commit_stats_job_test.rb +1 -0
  251. data/test/jobs/fetch_deployed_revision_job_test.rb +1 -0
  252. data/test/jobs/github_sync_job_test.rb +22 -21
  253. data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
  254. data/test/jobs/perform_task_job_test.rb +3 -3
  255. data/test/jobs/process_merge_requests_job_test.rb +7 -6
  256. data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
  257. data/test/jobs/reap_dead_tasks_job_test.rb +1 -0
  258. data/test/jobs/refresh_github_user_job_test.rb +1 -0
  259. data/test/jobs/refresh_status_job_test.rb +1 -0
  260. data/test/jobs/shipit/background_job_test.rb +35 -0
  261. data/test/jobs/shipit/continuous_delivery_job_test.rb +31 -0
  262. data/test/jobs/unique_job_test.rb +3 -1
  263. data/test/jobs/update_github_last_deployed_ref_job_test.rb +1 -0
  264. data/test/middleware/same_site_cookie_middleware_test.rb +2 -2
  265. data/test/models/api_client_test.rb +1 -0
  266. data/test/models/commit_checks_test.rb +2 -1
  267. data/test/models/commit_deployment_status_test.rb +2 -2
  268. data/test/models/commit_deployment_test.rb +4 -3
  269. data/test/models/commits_test.rb +72 -70
  270. data/test/models/delivery_test.rb +3 -2
  271. data/test/models/deploy_spec_test.rb +113 -109
  272. data/test/models/deploy_stats_test.rb +1 -0
  273. data/test/models/deploys_test.rb +65 -56
  274. data/test/models/duration_test.rb +1 -1
  275. data/test/models/github_hook_test.rb +1 -0
  276. data/test/models/hook_test.rb +7 -4
  277. data/test/models/membership_test.rb +1 -0
  278. data/test/models/merge_request_test.rb +26 -20
  279. data/test/models/release_statuses_test.rb +2 -1
  280. data/test/models/rollbacks_test.rb +4 -3
  281. data/test/models/shipit/check_run_test.rb +16 -15
  282. data/test/models/shipit/continuous_delivery_schedule_test.rb +109 -0
  283. data/test/models/shipit/deploy_spec/file_system_test.rb +54 -10
  284. data/test/models/shipit/pull_request_test.rb +9 -9
  285. data/test/models/shipit/repository_test.rb +3 -2
  286. data/test/models/shipit/review_stack_provisioning_queue_test.rb +2 -2
  287. data/test/models/shipit/{stacks_test.rb → stack_test.rb} +48 -34
  288. data/test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb +36 -34
  289. data/test/models/shipit/webhooks/handlers/pull_request/label_capturing_handler_test.rb +28 -28
  290. data/test/models/shipit/webhooks/handlers/pull_request/labeled_handler_test.rb +42 -42
  291. data/test/models/shipit/webhooks/handlers/pull_request/opened_handler_test.rb +33 -33
  292. data/test/models/shipit/webhooks/handlers/pull_request/reopened_handler_test.rb +37 -37
  293. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +1 -1
  294. data/test/models/shipit/webhooks/handlers/pull_request/unlabeled_handler_test.rb +44 -42
  295. data/test/models/shipit/webhooks/handlers_test.rb +1 -0
  296. data/test/models/status/group_test.rb +3 -2
  297. data/test/models/status/missing_test.rb +1 -0
  298. data/test/models/status_test.rb +2 -1
  299. data/test/models/task_definitions_test.rb +7 -6
  300. data/test/models/tasks_test.rb +5 -4
  301. data/test/models/team_test.rb +5 -4
  302. data/test/models/undeployed_commits_test.rb +10 -9
  303. data/test/models/users_test.rb +29 -20
  304. data/test/test_command_integration.rb +1 -1
  305. data/test/test_helper.rb +12 -10
  306. data/test/unit/anonymous_user_serializer_test.rb +1 -0
  307. data/test/unit/command_test.rb +10 -1
  308. data/test/unit/commands_test.rb +1 -0
  309. data/test/unit/commit_serializer_test.rb +1 -0
  310. data/test/unit/csv_serializer_test.rb +3 -2
  311. data/test/unit/deploy_commands_test.rb +33 -23
  312. data/test/unit/deploy_serializer_test.rb +1 -0
  313. data/test/unit/environment_variables_test.rb +2 -1
  314. data/test/unit/github_app_test.rb +11 -10
  315. data/test/unit/github_apps_test.rb +19 -18
  316. data/test/unit/github_url_helper_test.rb +1 -0
  317. data/test/unit/line_buffer_test.rb +1 -1
  318. data/test/unit/rollback_commands_test.rb +2 -1
  319. data/test/unit/shipit_helper_test.rb +1 -0
  320. data/test/unit/shipit_test.rb +47 -1
  321. data/test/unit/user_serializer_test.rb +1 -0
  322. data/test/unit/variable_definition_test.rb +4 -3
  323. metadata +61 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f671228679f81a64a70284699951ea5cc8fce83e82a56263cf6a4f52055f5976
4
- data.tar.gz: 0d795762874714a9d592edb0dd3fd1b599f1819edc06d1085252a9e26ef0073b
3
+ metadata.gz: 6b42049322671e225e86884f3990cf0233fcd0b4ac7eaec63643a3c57dbe8f9b
4
+ data.tar.gz: 132aee7cfff7bc2801a0a28224be08e625880bfc59fcc98a6adabd1459a2b812
5
5
  SHA512:
6
- metadata.gz: 6c55d8a3f3ab16affd874abd8c15e51c19a29e81ddb3131a4695d9ca2ba409e312e40892ddbd66ec6bca32ce403254f02de632dbab06a97306c6a0da5e684c2e
7
- data.tar.gz: fd7b4ad69bd0b03a486a38a4ce2dcf0802581aee836e44f1390f362aeace5b1fbb30f24bd3a5579da89e0bfca8f588ed16d121e9be7a4afd7f7f1efda208a97f
6
+ metadata.gz: 2d75e469feb17bab9a1792cefd41da3ae8daf38d1b32ef0c1ab39df1bfd931b033f27d83cadefb92e77ff3063f2b8ebdcea4844ef64b88d61a9a87d1183eca19
7
+ data.tar.gz: 667e3e0cbaac19bc64c11defa7e502d504aea73c09010e81bf1368a52d5794fc8953e29b34d7cb65865f5229d3c3ab38bbe2bc62db822bdb59fb119d59b728c9
data/README.md CHANGED
@@ -25,8 +25,8 @@ This guide aims to help you [set up](#installation-and-setup), [use](#using-ship
25
25
  **II. USING SHIPIT**
26
26
 
27
27
  * [Adding stacks](#adding-stacks)
28
- * [Working on stacks](#working-on-stacks),
29
- * [Configuring stacks](#configuring-stacks).
28
+ * [Working on stacks](#working-on-stacks)
29
+ * [Configuring stacks](#configuring-stacks)
30
30
 
31
31
  **III. REFERENCE**
32
32
 
@@ -123,6 +123,7 @@ The settings in the `shipit.yml` file relate to the different things you can do
123
123
  * [Custom Tasks](#custom-tasks) (`tasks`)
124
124
  * [Custom links](#custom-links) (`links`)
125
125
  * [Review Process](#review-process) (`review.checklist`, `review.monitoring`, `review.checks`)
126
+ * [Inherit From](#inherit-from)(`inherit_from`)
126
127
 
127
128
  All the settings in `shipit.yml` are optional. Most applications can be deployed from Shipit without any configuration.
128
129
 
@@ -130,6 +131,8 @@ Also, if your repository is deployed different ways depending on the environment
130
131
 
131
132
  For example for a stack like: `my-org/my-repo/staging`, `shipit.staging.yml` will have priority over `shipit.yml`.
132
133
 
134
+ In order to reduce duplication across different environment specific files, you can specify an `inherit_from` key in your relevant `shipit.yml` file. This key expects a string of the file name to inherit from. If this key is specified, a deep-merge will be performed on the file therein, overwriting any duplicated values from the parent. See [Inherit From](#inherit-from)(`inherit_From`) for example.
135
+
133
136
  Lastly, if you override the `app_name` configuration in your Shipit deployment, `yourapp.yml` and `yourapp.staging.yml` will work.
134
137
 
135
138
  * * *
@@ -357,6 +360,11 @@ For example:
357
360
  fetch:
358
361
  curl --silent https://app.example.com/services/ping/version
359
362
  ```
363
+
364
+ **Note:** Currently, deployments in emergency mode are configured to occur concurrently via [the `build_deploy` method](https://github.com/Shopify/shipit-engine/blob/main/app/models/shipit/stack.rb),
365
+ whose `allow_concurrency` keyword argument defaults to `force`, where `force` is true when emergency mode is enabled.
366
+ If you'd like to separate these two from one another, override this method as desired in your service.
367
+
360
368
  <h3 id="kubernetes">Kubernetes</h3>
361
369
 
362
370
  **<code>kubernetes</code>** allows to specify a Kubernetes namespace and context to deploy to.
@@ -608,9 +616,45 @@ review:
608
616
  - bundle exec rake db:migrate:status
609
617
  ```
610
618
 
619
+ <h3 id="inherit-from">Inherit From</h3>
620
+
621
+ If the `inherit_from` key is specified, a deep-merge will be performed on the file therein, overwriting any duplicated values from the parent. Keys may be chained across files. Example:
622
+
623
+ ``` yaml
624
+ # shipit.production.yml
625
+ inherit_from: shipit.staging.yml
626
+
627
+ machine:
628
+ environment:
629
+ PUBLIC: true
630
+ ```
631
+
632
+ ``` yaml
633
+ # shipit.staging.yml
634
+ inherit_from: shipit.yml
635
+
636
+ deploy:
637
+ override:
638
+ - ./some_deployment_process.sh ${PUBLIC}
639
+ ```
640
+
641
+ ``` yaml
642
+ # shipit.yml
643
+
644
+ machine:
645
+ environment:
646
+ TEST: true
647
+ PUBLIC: false
648
+ ```
649
+
650
+ Loading 'shipit.production.yml' would result in:
651
+ ```rb
652
+ {"machine"=>{"environment"=>{"TEST"=>true, "PUBLIC"=>true}}, "deploy"=>{"override"=>["./some_deployment_process.sh ${PUBLIC}"]}}
653
+ ```
654
+
611
655
  <h3 id="shell-commands-timeout">Shell commands timeout</h3>
612
656
 
613
- All the shell commands can take an optional `timeout` parameter to limit their duration:
657
+ All the shell commands can take an optional `timeout` parameter. This is the value in seconds that a command can be inactive before Shipit will terminate the task.
614
658
 
615
659
  ```yml
616
660
  deploy:
@@ -641,7 +685,7 @@ Your deploy scripts have access to the following environment variables:
641
685
  * `GITHUB_REPO_OWNER`: The GitHub username of the repository owner for the current deploy/task.
642
686
  * `EMAIL`: Email of the user that triggered the deploy/task (if available)
643
687
  * `ENVIRONMENT`: The stack environment (e.g `production` / `staging`)
644
- * `BRANCH`: The stack branch (e.g `master`)
688
+ * `BRANCH`: The stack branch (e.g `main`)
645
689
  * `LAST_DEPLOYED_SHA`: The git SHA of the last deployed commit
646
690
  * `DIFF_LINK`: URL to the diff on GitHub.
647
691
  * `TASK_ID`: ID of the task that is running
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Add your own tasks in files placed in lib/tasks ending in .rake,
3
4
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
5
 
@@ -8,7 +9,7 @@ begin
8
9
  rescue LoadError
9
10
  end
10
11
 
11
- APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
12
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
12
13
  load('rails/tasks/engine.rake')
13
14
 
14
15
  Bundler::GemHelper.install_tasks
@@ -0,0 +1,15 @@
1
+ $(document)
2
+ .on "click", ".continuous-delivery-schedule [data-action='copy-to-all']", (event) ->
3
+ form = event.target.closest("form");
4
+
5
+ mondayStart = form.elements.namedItem("continuous_delivery_schedule[monday_start]").value
6
+ mondayEnd = form.elements.namedItem("continuous_delivery_schedule[monday_end]").value
7
+
8
+ Array.from(form.elements).forEach (formElement) ->
9
+ return unless formElement.type == "time"
10
+
11
+ if formElement.name.endsWith("_start]")
12
+ formElement.value = mondayStart
13
+
14
+ if formElement.name.endsWith("_end]")
15
+ formElement.value = mondayEnd
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module ActiveModelSerializersPatch
4
5
  private
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  module Cacheable
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  module Paginable
@@ -23,8 +24,8 @@ module Shipit
23
24
  resource,
24
25
  self,
25
26
  order: default_order,
26
- max_page_size: max_page_size,
27
- default_page_size: default_page_size,
27
+ max_page_size:,
28
+ default_page_size:
28
29
  )
29
30
  headers[LINK] = render_links(paginator.links)
30
31
  super(paginator.to_a)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  module Rendering
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Authentication
4
5
  extend ActiveSupport::Concern
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Pagination
4
5
  extend ActiveSupport::Concern
@@ -20,8 +21,8 @@ module Shipit
20
21
  relation,
21
22
  self,
22
23
  order: default_order,
23
- max_page_size: max_page_size,
24
- default_page_size: default_page_size,
24
+ max_page_size:,
25
+ default_page_size:
25
26
  )
26
27
  end
27
28
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class BaseController < ActionController::Base
@@ -35,7 +36,7 @@ module Shipit
35
36
 
36
37
  private
37
38
 
38
- def has_basic_credentials?(request)
39
+ def basic_credentials?(request)
39
40
  request.authorization.present? && (auth_scheme(request).downcase == "basic")
40
41
  end
41
42
  end
@@ -46,14 +47,15 @@ module Shipit
46
47
 
47
48
  def authenticate_api_client
48
49
  @current_api_client = if Shipit.disable_api_authentication
49
- UnlimitedApiClient.new
50
- else
51
- BasicAuth.authenticate(request) do |*parts|
52
- token = parts.select(&:present?).join('--')
53
- ApiClient.authenticate(token)
54
- end
55
- end
50
+ UnlimitedApiClient.new
51
+ else
52
+ BasicAuth.authenticate(request) do |*parts|
53
+ token = parts.select(&:present?).join('--')
54
+ ApiClient.authenticate(token)
55
+ end
56
+ end
56
57
  return if @current_api_client
58
+
57
59
  headers['WWW-Authenticate'] = 'Basic realm="Authentication token"'
58
60
  render(status: :unauthorized, json: { message: 'Bad credentials' })
59
61
  end
@@ -93,8 +95,8 @@ module Shipit
93
95
  render(status: :not_found, json: { status: '404', error: 'Not Found' })
94
96
  end
95
97
 
96
- def conflict(_error)
97
- render(status: :conflict, json: { status: '409', error: 'Conflict' })
98
+ def conflict(error)
99
+ render(status: :conflict, json: { status: '409', error: error.message })
98
100
  end
99
101
  end
100
102
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class CCMenuController < BaseController
@@ -20,7 +21,7 @@ module Shipit
20
21
 
21
22
  def show
22
23
  latest_deploy = stack.deploys_and_rollbacks.last || NoDeploy.new
23
- render('shipit/ccmenu/project', formats: [:xml], locals: { stack: stack, deploy: latest_deploy })
24
+ render('shipit/ccmenu/project', formats: [:xml], locals: { stack:, deploy: latest_deploy })
24
25
  end
25
26
 
26
27
  private
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class CommitsController < BaseController
@@ -6,9 +7,7 @@ module Shipit
6
7
 
7
8
  def index
8
9
  commits = stack.commits.reachable.includes(:statuses)
9
- if params[:undeployed]
10
- commits = commits.newer_than(stack.last_deployed_commit)
11
- end
10
+ commits = commits.newer_than(stack.last_deployed_commit) if params[:undeployed]
12
11
 
13
12
  render_resources(commits)
14
13
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class DeploysController < BaseController
@@ -11,6 +12,7 @@ module Shipit
11
12
  params do
12
13
  requires :sha, String, length: { in: 6..40 }
13
14
  accepts :force, Boolean, default: false
15
+ accepts :allow_concurrency, Boolean
14
16
  accepts :require_ci, Boolean, default: false
15
17
  accepts :env, Hash, default: {}
16
18
  end
@@ -18,7 +20,10 @@ module Shipit
18
20
  commit = stack.commits.by_sha(params.sha) || param_error!(:sha, 'Unknown revision')
19
21
  param_error!(:force, "Can't deploy a locked stack") if !params.force && stack.locked?
20
22
  param_error!(:require_ci, "Commit is not deployable") if params.require_ci && !commit.deployable?
21
- deploy = stack.trigger_deploy(commit, current_user, env: params.env, force: params.force)
23
+
24
+ allow_concurrency = params.allow_concurrency.nil? ? params.force : params.allow_concurrency
25
+ deploy = stack.trigger_deploy(commit, current_user, env: params.env, force: params.force,
26
+ allow_concurrency:)
22
27
  render_resource(deploy, status: :accepted)
23
28
  end
24
29
  end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class HooksController < BaseController
5
- require_permission :read, :hook, only: %i(index show)
6
- require_permission :write, :hook, only: %i(create update destroy)
6
+ require_permission :read, :hook, only: %i[index show]
7
+ require_permission :write, :hook, only: %i[create update destroy]
7
8
 
8
9
  def index
9
10
  render_resources(hooks)
@@ -43,7 +44,7 @@ module Shipit
43
44
  end
44
45
 
45
46
  def hooks
46
- Hook.where(stack_id: stack_id)
47
+ Hook.where(stack_id:)
47
48
  end
48
49
 
49
50
  def stack_id
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class LocksController < BaseController
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class MergeRequestsController < BaseController
5
6
  require_permission :read, :stack
6
- require_permission :deploy, :stack, only: %i(update destroy)
7
+ require_permission :deploy, :stack, only: %i[update destroy]
7
8
 
8
9
  def index
9
10
  render_resources(stack.merge_requests.includes(:head).order(id: :desc))
@@ -19,16 +20,16 @@ module Shipit
19
20
  head(:accepted)
20
21
  elsif merge_request.merged?
21
22
  render(status: :method_not_allowed, json: {
22
- message: "This pull request was already merged.",
23
- })
23
+ message: "This pull request was already merged."
24
+ })
24
25
  else
25
26
  raise "Pull Request is neither waiting nor merged, this should be impossible"
26
27
  end
27
28
  end
28
29
 
29
30
  def destroy
30
- if merge_request = stack.merge_requests.where(number: params[:id]).first
31
- merge_request.cancel! if merge_request.waiting?
31
+ if (merge_request = stack.merge_requests.where(number: params[:id]).first) && merge_request.waiting?
32
+ merge_request.cancel!
32
33
  end
33
34
  head(:no_content)
34
35
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class OutputsController < BaseController
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class ReleaseStatusesController < BaseController
@@ -6,7 +7,7 @@ module Shipit
6
7
 
7
8
  params do
8
9
  requires :status, String
9
- validates :status, inclusion: { in: %w(success failure) }
10
+ validates :status, inclusion: { in: %w[success failure] }
10
11
  end
11
12
  def create
12
13
  deploy = stack.deploys_and_rollbacks.find(params[:deploy_id])
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class RollbacksController < BaseController
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class StacksController < BaseController
5
- require_permission :read, :stack, only: %i(index show)
6
- require_permission :write, :stack, only: %i(create update destroy)
6
+ require_permission :read, :stack, only: %i[index show]
7
+ require_permission :write, :stack, only: %i[create update destroy]
7
8
 
8
9
  params do
9
10
  accepts :repo_owner, String
@@ -14,10 +15,10 @@ module Shipit
14
15
  if params[:repo_owner] && params[:repo_name]
15
16
  full_repo_name = [repo_owner, repo_name].join('/')
16
17
  @stacks = if (repository = Repository.from_github_repo_name(full_repo_name))
17
- stacks.where(repository: repository)
18
- else
19
- Stack.none
20
- end
18
+ stacks.where(repository:)
19
+ else
20
+ Stack.none
21
+ end
21
22
  end
22
23
  render_resources(@stacks)
23
24
  end
@@ -75,7 +76,7 @@ module Shipit
75
76
  private
76
77
 
77
78
  def create_params
78
- params.reject { |key, _| %i(repo_owner repo_name).include?(key) }
79
+ params.reject { |key, _| %i[repo_owner repo_name].include?(key) }
79
80
  end
80
81
 
81
82
  def stack
@@ -83,12 +84,12 @@ module Shipit
83
84
  end
84
85
 
85
86
  def update_archived
86
- if key?(:archived)
87
- if params[:archived]
88
- stack.archive!(nil)
89
- elsif stack.archived?
90
- stack.unarchive!
91
- end
87
+ return unless key?(:archived)
88
+
89
+ if params[:archived]
90
+ stack.archive!(nil)
91
+ elsif stack.archived?
92
+ stack.unarchive!
92
93
  end
93
94
  end
94
95
 
@@ -98,7 +99,7 @@ module Shipit
98
99
 
99
100
  def update_params
100
101
  params.select do |key, _|
101
- %i(environment branch deploy_url ignore_ci merge_queue_enabled continuous_deployment).include?(key)
102
+ %i[environment branch deploy_url ignore_ci merge_queue_enabled continuous_deployment].include?(key)
102
103
  end
103
104
  end
104
105
 
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Api
4
5
  class TasksController < BaseController
5
6
  require_permission :read, :stack
6
- require_permission :deploy, :stack, only: %i(trigger abort)
7
+ require_permission :deploy, :stack, only: %i[trigger abort]
7
8
 
8
9
  def index
9
10
  render_resources(stack.tasks)
@@ -20,8 +21,8 @@ module Shipit
20
21
  render_resource(stack.trigger_task(params[:task_name], current_user, env: params.env), status: :accepted)
21
22
  rescue Shipit::Task::ConcurrentTaskRunning
22
23
  render(status: :conflict, json: {
23
- message: 'A task is already running.',
24
- })
24
+ message: 'A task is already running.'
25
+ })
25
26
  end
26
27
 
27
28
  def abort
@@ -30,8 +31,8 @@ module Shipit
30
31
  head(:accepted)
31
32
  else
32
33
  render(status: :method_not_allowed, json: {
33
- message: "This task is not currently running.",
34
- })
34
+ message: "This task is not currently running."
35
+ })
35
36
  end
36
37
  end
37
38
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class ApiClientsController < ShipitController
4
5
  include Pagination
@@ -15,9 +16,7 @@ module Shipit
15
16
 
16
17
  def create
17
18
  @api_client = ApiClient.new(create_params.merge(creator_id: current_user.id))
18
- unless @api_client.save
19
- flash[:warning] = @api_client.errors.full_messages.to_sentence
20
- end
19
+ flash[:warning] = @api_client.errors.full_messages.to_sentence unless @api_client.save
21
20
 
22
21
  respond_with(@api_client)
23
22
  end
@@ -29,10 +28,10 @@ module Shipit
29
28
  def update
30
29
  @api_client = ApiClient.find(params[:id])
31
30
  options = if @api_client.update(update_params)
32
- { flash: { success: 'Successfully updated' } }
33
- else
34
- { flash: { warning: @stack.errors.full_messages.to_sentence } }
35
- end
31
+ { flash: { success: 'Successfully updated' } }
32
+ else
33
+ { flash: { warning: @stack.errors.full_messages.to_sentence } }
34
+ end
36
35
 
37
36
  redirect_to(params[:return_to].presence || api_client_path(@api_client), options)
38
37
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'uri'
3
4
 
4
5
  module Shipit
@@ -12,8 +13,8 @@ module Shipit
12
13
  private
13
14
 
14
15
  def client
15
- @client ||= ApiClient.create_with(permissions: %w(read:stack))
16
- .find_or_create_by!(creator: current_user, name: 'CCMenu Client')
16
+ @client ||= ApiClient.create_with(permissions: %w[read:stack])
17
+ .find_or_create_by!(creator: current_user, name: 'CCMenu Client')
17
18
  end
18
19
 
19
20
  def stack
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class CommitChecksController < ShipitController
4
5
  def show
@@ -16,7 +17,7 @@ module Shipit
16
17
  url = stack_tail_commit_checks_path(stack, sha: commit.sha, since: next_offset)
17
18
  end
18
19
 
19
- render(json: { url: url, output: output, status: checks.status })
20
+ render(json: { url:, output:, status: checks.status })
20
21
  end
21
22
 
22
23
  private
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class CommitsController < ShipitController
4
5
  def update
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shipit
4
+ class ContinuousDeliverySchedulesController < ShipitController
5
+ before_action :load_stack
6
+
7
+ def show
8
+ @continuous_delivery_schedule = @stack.continuous_delivery_schedule || @stack.build_continuous_delivery_schedule
9
+ end
10
+
11
+ def update
12
+ @continuous_delivery_schedule = @stack.continuous_delivery_schedule || @stack.build_continuous_delivery_schedule
13
+ @continuous_delivery_schedule.assign_attributes(continuous_delivery_schedule_params)
14
+
15
+ if @continuous_delivery_schedule.save
16
+ flash[:success] = "Successfully updated"
17
+ redirect_to(stack_continuous_delivery_schedule_path)
18
+ else
19
+ flash.now[:warning] = "Check form for errors"
20
+ render(:show, status: :unprocessable_entity)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def load_stack
27
+ @stack = Stack.from_param!(params[:id])
28
+ end
29
+
30
+ def continuous_delivery_schedule_params
31
+ params.require(:continuous_delivery_schedule).permit(
32
+ *Shipit::ContinuousDeliverySchedule::DAYS.flat_map do |day|
33
+ [
34
+ "#{day}_start",
35
+ "#{day}_end",
36
+ "#{day}_enabled"
37
+ ]
38
+ end
39
+ )
40
+ end
41
+ end
42
+ end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class DeploysController < ShipitController
4
5
  include ChunksHelper
5
6
 
6
7
  before_action :load_stack
7
- before_action :load_deploy, only: %i(show rollback revert)
8
+ before_action :load_deploy, only: %i[show rollback revert]
8
9
  before_action :load_until_commit, only: :create
9
10
  helper_method :short_commit_sha
10
11
 
@@ -26,7 +27,7 @@ module Shipit
26
27
  @until_commit,
27
28
  current_user,
28
29
  env: deploy_params[:env],
29
- force: params[:force].present?,
30
+ force: params[:force].present?
30
31
  )
31
32
  respond_with(@deploy.stack, @deploy)
32
33
  rescue Task::ConcurrentTaskRunning
@@ -43,9 +44,9 @@ module Shipit
43
44
  end
44
45
 
45
46
  def short_commit_sha(task)
46
- if previous_successful_deploy_commit(task)
47
- @short_commit_sha ||= @previous_successful_deploy_commit&.short_sha
48
- end
47
+ return unless previous_successful_deploy_commit(task)
48
+
49
+ @short_commit_sha ||= @previous_successful_deploy_commit&.short_sha
49
50
  end
50
51
 
51
52
  private