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
@@ -21,16 +21,16 @@ module Shipit
21
21
  perform_task
22
22
  @task.write("\nCompleted successfully\n")
23
23
  @task.report_complete!
24
- rescue Command::TimedOut => error
25
- @task.write("\n#{error.message}\n")
26
- @task.report_timeout!(error)
27
- rescue Command::Error => error
28
- @task.write("\n#{error.message}\n")
29
- @task.report_failure!(error)
30
- rescue StandardError => error
31
- @task.report_error!(error)
32
- rescue Exception => error
33
- @task.report_error!(error)
24
+ rescue Command::TimedOut => e
25
+ @task.write("\n#{e.message}\n")
26
+ @task.report_timeout!(e)
27
+ rescue Command::Error => e
28
+ @task.write("\n#{e.message}\n")
29
+ @task.report_failure!(e)
30
+ rescue StandardError => e
31
+ @task.report_error!(e)
32
+ rescue Exception => e
33
+ @task.report_error!(e)
34
34
  raise
35
35
  end
36
36
 
@@ -42,8 +42,8 @@ module Shipit
42
42
  else
43
43
  @task.write("Can't abort, no recorded pid, WTF?\n")
44
44
  end
45
- rescue SystemCallError => error
46
- @task.write("kill: (#{pid}) - #{error.message}\n")
45
+ rescue SystemCallError => e
46
+ @task.write("kill: (#{pid}) - #{e.message}\n")
47
47
  end
48
48
 
49
49
  def check_for_abort
@@ -94,7 +94,7 @@ module Shipit
94
94
  @task.write(line)
95
95
  end
96
96
  finished_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
97
- @task.write("pid: #{command.pid} finished in: #{finished_at - started_at} seconds\n")
97
+ @task.write("pid: #{command.pid} finished in: #{(finished_at - started_at).round(3)} seconds\n")
98
98
  command.success?
99
99
  end
100
100
 
@@ -1,32 +1,33 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class Team < Record
4
- REQUIRED_HOOKS = %i(membership).freeze
5
+ REQUIRED_HOOKS = %i[membership].freeze
5
6
 
6
7
  has_many :memberships
7
8
  has_many :members, class_name: :User, through: :memberships, source: :user
8
9
 
9
10
  has_many :github_hooks,
10
- -> { where(event: REQUIRED_HOOKS) },
11
- foreign_key: :organization,
12
- primary_key: :organization,
13
- class_name: 'GithubHook::Organization',
14
- inverse_of: false
11
+ -> { where(event: REQUIRED_HOOKS) },
12
+ foreign_key: :organization,
13
+ primary_key: :organization,
14
+ class_name: 'GithubHook::Organization',
15
+ inverse_of: false
15
16
 
16
17
  class << self
17
18
  def find_or_create_by_handle(handle)
18
19
  organization, slug = handle.split('/').map(&:downcase)
19
- find_by(organization: organization, slug: slug) || fetch_and_create_from_github(organization, slug)
20
+ find_by(organization:, slug:) || fetch_and_create_from_github(organization, slug)
20
21
  end
21
22
 
22
23
  def fetch_and_create_from_github(organization, slug)
23
- if github_team = find_team_on_github(organization, slug)
24
- create!(github_team: github_team, organization: organization)
25
- end
24
+ return unless github_team = find_team_on_github(organization, slug)
25
+
26
+ create!(github_team:, organization:)
26
27
  end
27
28
 
28
29
  def find_team_on_github(organization, slug)
29
- gh_api = Shipit.github(organization: organization).api
30
+ gh_api = Shipit.github(organization:).api
30
31
  teams = Shipit::OctokitIterator.new(github_api: gh_api) { gh_api.org_teams(organization, per_page: 100) }
31
32
  teams.find { |t| t.slug == slug }
32
33
  rescue Octokit::NotFound
@@ -42,7 +43,7 @@ module Shipit
42
43
  end
43
44
 
44
45
  def refresh_members!
45
- github_api = Shipit.github(organization: organization).api
46
+ github_api = Shipit.github(organization:).api
46
47
  github_members = Shipit::OctokitIterator.new(github_api.get(api_url).rels[:members])
47
48
  members = github_members.map { |u| User.find_or_create_from_github(u) }
48
49
  self.members = members
@@ -1,4 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
3
+ # rubocop:disable Lint/MissingCopEnableDirective, Style/OptionalBooleanParameter
4
+ # Disabling for now because we need to support the `bypass_safeties` parameter
5
+ # in the `deploy_state` and `redeploy_state` methods. We can revisit this later.
6
+
7
+ require 'delegate'
2
8
  module Shipit
3
9
  class UndeployedCommit < DelegateClass(Commit)
4
10
  attr_reader :index
@@ -26,9 +32,7 @@ module Shipit
26
32
 
27
33
  def redeploy_state(bypass_safeties = false)
28
34
  state = 'allowed'
29
- unless bypass_safeties
30
- state = 'deploying' if stack.active_task?
31
- end
35
+ state = 'deploying' if !bypass_safeties && stack.active_task?
32
36
  state
33
37
  end
34
38
 
@@ -50,6 +54,7 @@ module Shipit
50
54
 
51
55
  def blocked?
52
56
  return @blocked if defined?(@blocked)
57
+
53
58
  @blocked = super
54
59
  end
55
60
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class UnlimitedApiClient
4
5
  def stack_id?
5
6
  false
6
7
  end
7
8
 
8
- def check_permissions!(*)
9
- end
9
+ def check_permissions!(*); end
10
10
  end
11
11
  end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class User < Record
4
5
  DEFAULT_AVATAR = URI.parse('https://avatars.githubusercontent.com/u/583231?')
5
6
 
6
- self.ignored_columns = %w(encrypted_github_access_token_iv)
7
+ self.ignored_columns = %w[encrypted_github_access_token_iv]
7
8
 
8
9
  has_many :memberships
9
10
  has_many :teams, through: :memberships
@@ -19,7 +20,7 @@ module Shipit
19
20
  after_find :discard_outdated_credentials!
20
21
 
21
22
  def self.find_or_create_by_login!(login)
22
- find_or_create_by!(login: login) do |user|
23
+ find_or_create_by!(login:) do |user|
23
24
  # Users are global, any app can be used
24
25
  # This will not work for users that only exist in an Enterprise install
25
26
  user.github_user = Shipit.github.api.user(login)
@@ -31,7 +32,7 @@ module Shipit
31
32
  end
32
33
 
33
34
  def self.find_or_create_author_from_github_commit(github_commit)
34
- if (match_info = github_commit.commit.message.match(/^#{MergeRequest::MERGE_REQUEST_FIELD}: ([\w\-\.]+)$/))
35
+ if (match_info = github_commit.commit.message.match(/^#{MergeRequest::MERGE_REQUEST_FIELD}: ([\w\-.]+)$/))
35
36
  begin
36
37
  return find_or_create_by_login!(match_info[1])
37
38
  rescue Octokit::NotFound
@@ -48,11 +49,12 @@ module Shipit
48
49
 
49
50
  def self.find_from_github(github_user)
50
51
  return unless github_user.id
52
+
51
53
  find_by(github_id: github_user.id)
52
54
  end
53
55
 
54
56
  def self.create_from_github(github_user)
55
- create(github_user: github_user)
57
+ create(github_user:)
56
58
  end
57
59
 
58
60
  def self.refresh_shard(shard_index, shards_count)
@@ -68,7 +70,7 @@ module Shipit
68
70
  end
69
71
 
70
72
  def identifiers_for_ping
71
- { github_id: github_id, name: name, email: email, github_login: login }
73
+ { github_id:, name:, email:, github_login: login }
72
74
  end
73
75
 
74
76
  def logged_in?
@@ -81,12 +83,14 @@ module Shipit
81
83
 
82
84
  def repositories_contributed_to
83
85
  return [] unless id
86
+
84
87
  Stack.where(id: stacks_contributed_to).distinct.pluck(:repository_id)
85
88
  end
86
89
 
87
90
  def stacks_contributed_to
88
91
  return [] unless id
89
- Commit.where('author_id = :id or committer_id = :id', id: id).distinct.pluck(:stack_id)
92
+
93
+ Commit.where('author_id = :id or committer_id = :id', id:).distinct.pluck(:stack_id)
90
94
  end
91
95
 
92
96
  def refresh_from_github!
@@ -95,6 +99,8 @@ module Shipit
95
99
  update!(github_user: Shipit.github.api.user(github_id))
96
100
  rescue Octokit::NotFound
97
101
  identify_renamed_user!
102
+ rescue Octokit::Forbidden
103
+ Rails.logger.info("User #{name}, github_id #{github_id} has forbidden access to their GitHub, likely deleted.")
98
104
  end
99
105
 
100
106
  def github_user=(github_user)
@@ -110,7 +116,7 @@ module Shipit
110
116
  email: appropriate_email_for(github_user),
111
117
  login: github_user.login,
112
118
  avatar_url: github_user.avatar_url,
113
- api_url: github_user.url,
119
+ api_url: github_user.url
114
120
  )
115
121
  end
116
122
 
@@ -130,18 +136,19 @@ module Shipit
130
136
  private
131
137
 
132
138
  def discard_outdated_credentials!
133
- if encrypted_github_access_token_before_type_cast.present?
134
- begin
135
- encrypted_github_access_token
136
- rescue ActiveRecord::Encryption::Errors::Decryption
137
- update_column(:encrypted_github_access_token, nil)
138
- end
139
+ return unless encrypted_github_access_token_before_type_cast.present?
140
+
141
+ begin
142
+ encrypted_github_access_token
143
+ rescue ActiveRecord::Encryption::Errors::Decryption
144
+ update_column(:encrypted_github_access_token, nil)
139
145
  end
140
146
  end
141
147
 
142
148
  def identify_renamed_user!
143
149
  last_commit = commits.last
144
150
  return unless last_commit
151
+
145
152
  github_author = last_commit.github_commit.author
146
153
  update!(github_user: github_author)
147
154
  rescue Octokit::NotFound
@@ -161,9 +168,9 @@ module Shipit
161
168
 
162
169
  begin
163
170
  github_api.emails
164
- .sort_by { |e| e.primary ? 0 : 1 }
165
- .map(&:email)
166
- .find { |e| email_valid_and_preferred?(e) }
171
+ .sort_by { |e| e.primary ? 0 : 1 }
172
+ .map(&:email)
173
+ .find { |e| email_valid_and_preferred?(e) }
167
174
  rescue Octokit::NotFound, Octokit::Forbidden, Octokit::Unauthorized
168
175
  # If the user hasn't agreed to the necessary permission, we can't access their private emails.
169
176
  Rails.logger.warn("Failed to retrieve emails for user '#{github_user.name || github_user.login}'")
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class VariableDefinition
4
5
  attr_reader :name, :title, :default, :select
@@ -20,7 +21,7 @@ module Shipit
20
21
  'name' => @name,
21
22
  'title' => @title,
22
23
  'default' => @default,
23
- 'select' => @select,
24
+ 'select' => @select
24
25
  }
25
26
  end
26
27
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Webhooks
4
5
  module Handlers
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Webhooks
4
5
  module Handlers
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Webhooks
4
5
  module Handlers
@@ -52,16 +52,16 @@ module Shipit
52
52
 
53
53
  def pull_request
54
54
  @pull_request ||= Shipit::PullRequest
55
- .joins(:stack, stack: :repository)
56
- .find_by(
57
- number: params.number,
58
- stacks: {
59
- repositories:
60
- {
61
- id: repository.id,
62
- },
63
- }
64
- )
55
+ .joins(:stack, stack: :repository)
56
+ .find_by(
57
+ number: params.number,
58
+ stacks: {
59
+ repositories:
60
+ {
61
+ id: repository.id
62
+ }
63
+ }
64
+ )
65
65
  end
66
66
 
67
67
  def repository
@@ -55,7 +55,7 @@ module Shipit
55
55
  def review_stack
56
56
  @review_stack ||=
57
57
  Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter
58
- .new(params, scope: repository.review_stacks)
58
+ .new(params, scope: repository.review_stacks)
59
59
  end
60
60
 
61
61
  def respond_to_pull_request_closed?
@@ -48,16 +48,16 @@ module Shipit
48
48
 
49
49
  def pull_request
50
50
  @pull_request ||= Shipit::PullRequest
51
- .joins(:stack, stack: :repository)
52
- .find_by(
53
- number: params.number,
54
- stacks: {
55
- repositories:
56
- {
57
- id: repository.id,
58
- },
59
- }
60
- )
51
+ .joins(:stack, stack: :repository)
52
+ .find_by(
53
+ number: params.number,
54
+ stacks: {
55
+ repositories:
56
+ {
57
+ id: repository.id
58
+ }
59
+ }
60
+ )
61
61
  end
62
62
 
63
63
  def repository
@@ -104,13 +104,13 @@ module Shipit
104
104
  def review_stack
105
105
  @review_stack ||=
106
106
  Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter
107
- .new(params, scope: repository.review_stacks)
107
+ .new(params, scope: repository.review_stacks)
108
108
  end
109
109
 
110
110
  def repository
111
111
  @repository ||=
112
112
  Shipit::Repository
113
- .from_github_repo_name(params.repository.full_name) || NullRepository.new
113
+ .from_github_repo_name(params.repository.full_name) || NullRepository.new
114
114
  end
115
115
 
116
116
  def stack
@@ -59,12 +59,12 @@ module Shipit
59
59
  def stack
60
60
  @stack ||=
61
61
  Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter
62
- .new(params, scope: repository.review_stacks)
62
+ .new(params, scope: repository.review_stacks)
63
63
  end
64
64
 
65
65
  def repository
66
66
  @repository ||= Shipit::Repository.from_github_repo_name(params.repository.full_name) ||
67
- Shipit::NullRepository.new
67
+ Shipit::NullRepository.new
68
68
  end
69
69
 
70
70
  def pull_request
@@ -55,7 +55,7 @@ module Shipit
55
55
  def stack
56
56
  @stack ||=
57
57
  Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter
58
- .new(params, scope: repository.review_stacks)
58
+ .new(params, scope: repository.review_stacks)
59
59
  end
60
60
 
61
61
  def pull_request
@@ -13,7 +13,7 @@ module Shipit
13
13
  end
14
14
 
15
15
  def stack
16
- @stack ||= scope.find_by(environment: environment)
16
+ @stack ||= scope.find_by(environment:)
17
17
  end
18
18
 
19
19
  def find_or_create!
@@ -87,9 +87,9 @@ module Shipit
87
87
  def stack_attributes
88
88
  {
89
89
  branch: params.pull_request.head.ref,
90
- environment: environment,
90
+ environment:,
91
91
  ignore_ci: false,
92
- continuous_deployment: false,
92
+ continuous_deployment: false
93
93
  }
94
94
  end
95
95
 
@@ -65,7 +65,7 @@ module Shipit
65
65
  def stack
66
66
  @stack ||=
67
67
  Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter
68
- .new(params, scope: repository.review_stacks)
68
+ .new(params, scope: repository.review_stacks)
69
69
  end
70
70
 
71
71
  def pull_request
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Webhooks
4
5
  module Handlers
@@ -9,7 +10,7 @@ module Shipit
9
10
  def process
10
11
  stacks
11
12
  .not_archived
12
- .where(branch: branch)
13
+ .where(branch:)
13
14
  .find_each(&:sync_github)
14
15
  end
15
16
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Webhooks
4
5
  module Handlers
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module Webhooks
4
5
  class << self
@@ -13,11 +14,11 @@ module Shipit
13
14
  Handlers::PullRequest::AssignedHandler,
14
15
  Handlers::PullRequest::LabeledHandler,
15
16
  Handlers::PullRequest::UnlabeledHandler,
16
- Handlers::PullRequest::LabelCapturingHandler,
17
+ Handlers::PullRequest::LabelCapturingHandler
17
18
  ],
18
19
  'status' => [Handlers::StatusHandler],
19
20
  'membership' => [Handlers::MembershipHandler],
20
- 'check_suite' => [Handlers::CheckSuiteHandler],
21
+ 'check_suite' => [Handlers::CheckSuiteHandler]
21
22
  }
22
23
  end
23
24
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  module ConditionalAttributes
4
5
  extend ActiveSupport::Concern
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class AnonymousUserSerializer < UserSerializer
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class CommandLineUserSerializer < UserSerializer
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class CommitSerializer < ShortCommitSerializer
4
5
  include GithubUrlHelper
@@ -24,7 +25,7 @@ module Shipit
24
25
  def pull_request
25
26
  {
26
27
  number: object.pull_request_number,
27
- html_url: github_pull_request_url(object),
28
+ html_url: github_pull_request_url(object)
28
29
  }
29
30
  end
30
31
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class DeploySerializer < TaskSerializer
4
5
  include GithubUrlHelper
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class HookSerializer < ActiveModel::Serializer
4
5
  include ConditionalAttributes
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class MergeRequestSerializer < ActiveModel::Serializer
4
5
  include GithubUrlHelper
@@ -8,7 +9,7 @@ module Shipit
8
9
  has_one :head, serializer: ShortCommitSerializer
9
10
 
10
11
  attributes :id, :number, :title, :github_id, :additions, :deletions, :state, :merge_status, :mergeable,
11
- :merge_requested_at, :rejection_reason, :html_url, :branch, :base_ref
12
+ :merge_requested_at, :rejection_reason, :html_url, :branch, :base_ref
12
13
 
13
14
  def html_url
14
15
  github_pull_request_url(object)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class RollbackSerializer < DeploySerializer
4
5
  def type
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class ShortCommitSerializer < ActiveModel::Serializer
4
5
  attributes :sha, :message
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class StackSerializer < ActiveModel::Serializer
4
5
  include ConditionalAttributes
@@ -6,9 +7,9 @@ module Shipit
6
7
  has_one :lock_author
7
8
 
8
9
  attributes :id, :repo_owner, :repo_name, :environment, :html_url, :url, :tasks_url, :deploy_url,
9
- :merge_requests_url, :deploy_spec, :undeployed_commits_count, :is_locked, :lock_reason, :continuous_deployment,
10
- :created_at, :updated_at, :locked_since, :last_deployed_at, :branch, :merge_queue_enabled, :is_archived,
11
- :archived_since, :ignore_ci
10
+ :merge_requests_url, :deploy_spec, :undeployed_commits_count, :is_locked, :lock_reason,
11
+ :continuous_deployment, :created_at, :updated_at, :locked_since, :last_deployed_at, :branch,
12
+ :merge_queue_enabled, :is_archived, :archived_since, :ignore_ci
12
13
 
13
14
  def url
14
15
  api_stack_url(object)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class TailTaskSerializer < ActiveModel::Serializer
4
5
  include ChunksHelper
@@ -8,6 +9,7 @@ module Shipit
8
9
 
9
10
  def url
10
11
  return @url if defined? @url
12
+
11
13
  @url = next_chunks_url(task, last_byte: next_offset)
12
14
  end
13
15
 
@@ -29,7 +31,7 @@ module Shipit
29
31
 
30
32
  private
31
33
 
32
- alias_method :task, :object
34
+ alias task object
33
35
  delegate :stack, to: :object
34
36
 
35
37
  def next_offset
@@ -42,6 +44,7 @@ module Shipit
42
44
 
43
45
  def rollback
44
46
  return @rollback if defined? @rollback
47
+
45
48
  @rollback = stack.rollbacks.where(parent_id: task.id).last
46
49
  end
47
50
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class TaskSerializer < ActiveModel::Serializer
4
5
  include ConditionalAttributes
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Shipit
3
4
  class UserSerializer < ActiveModel::Serializer
4
5
  attributes :id, :name, :email, :login, :avatar_url, :created_at, :updated_at, :github_id, :anonymous
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class AsciiOnlyValidator < ActiveModel::EachValidator
3
4
  def validate_each(record, attribute, value)
4
- if value && !value.ascii_only?
5
- record.errors.add(attribute, :ascii)
6
- end
5
+ return unless value && !value.ascii_only?
6
+
7
+ record.errors.add(attribute, :ascii)
7
8
  end
8
9
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class SubsetValidator < ActiveModel::EachValidator
3
4
  def validate_each(record, attribute, value)
4
5
  superset = options[:of]