shipit-engine 0.28.0 → 0.32.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 (314) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -2
  3. data/Rakefile +4 -2
  4. data/app/assets/images/archive-solid.svg +1 -0
  5. data/app/assets/stylesheets/_pages/_stacks.scss +76 -3
  6. data/app/assets/stylesheets/_structure/_main.scss +2 -1
  7. data/app/assets/stylesheets/merge_status.scss +0 -3
  8. data/app/controllers/concerns/shipit/active_model_serializers_patch.rb +13 -0
  9. data/app/controllers/concerns/shipit/api/cacheable.rb +1 -0
  10. data/app/controllers/concerns/shipit/api/paginable.rb +3 -2
  11. data/app/controllers/concerns/shipit/api/rendering.rb +5 -4
  12. data/app/controllers/concerns/shipit/authentication.rb +3 -2
  13. data/app/controllers/concerns/shipit/pagination.rb +2 -1
  14. data/app/controllers/shipit/api/base_controller.rb +11 -6
  15. data/app/controllers/shipit/api/ccmenu_controller.rb +2 -1
  16. data/app/controllers/shipit/api/commits_controller.rb +2 -1
  17. data/app/controllers/shipit/api/deploys_controller.rb +4 -3
  18. data/app/controllers/shipit/api/hooks_controller.rb +6 -5
  19. data/app/controllers/shipit/api/locks_controller.rb +5 -4
  20. data/app/controllers/shipit/api/outputs_controller.rb +2 -1
  21. data/app/controllers/shipit/api/pull_requests_controller.rb +7 -6
  22. data/app/controllers/shipit/api/release_statuses_controller.rb +3 -2
  23. data/app/controllers/shipit/api/rollbacks_controller.rb +33 -0
  24. data/app/controllers/shipit/api/stacks_controller.rb +37 -5
  25. data/app/controllers/shipit/api/tasks_controller.rb +6 -5
  26. data/app/controllers/shipit/api_clients_controller.rb +50 -0
  27. data/app/controllers/shipit/ccmenu_url_controller.rb +4 -3
  28. data/app/controllers/shipit/commit_checks_controller.rb +2 -1
  29. data/app/controllers/shipit/commits_controller.rb +2 -1
  30. data/app/controllers/shipit/deploys_controller.rb +3 -2
  31. data/app/controllers/shipit/github_authentication_controller.rb +4 -3
  32. data/app/controllers/shipit/merge_status_controller.rb +19 -14
  33. data/app/controllers/shipit/pull_requests_controller.rb +3 -2
  34. data/app/controllers/shipit/release_statuses_controller.rb +3 -2
  35. data/app/controllers/shipit/rollbacks_controller.rb +3 -2
  36. data/app/controllers/shipit/shipit_controller.rb +2 -1
  37. data/app/controllers/shipit/stacks_controller.rb +78 -14
  38. data/app/controllers/shipit/status_controller.rb +2 -1
  39. data/app/controllers/shipit/tasks_controller.rb +6 -5
  40. data/app/controllers/shipit/webhooks_controller.rb +5 -132
  41. data/app/helpers/shipit/chunks_helper.rb +1 -0
  42. data/app/helpers/shipit/deploys_helper.rb +4 -3
  43. data/app/helpers/shipit/github_url_helper.rb +1 -0
  44. data/app/helpers/shipit/merge_status_helper.rb +1 -0
  45. data/app/helpers/shipit/shipit_helper.rb +1 -0
  46. data/app/helpers/shipit/stacks_helper.rb +5 -0
  47. data/app/helpers/shipit/tasks_helper.rb +1 -0
  48. data/app/jobs/shipit/background_job.rb +4 -0
  49. data/app/jobs/shipit/background_job/unique.rb +4 -1
  50. data/app/jobs/shipit/cache_deploy_spec_job.rb +1 -0
  51. data/app/jobs/shipit/chunk_rollup_job.rb +4 -0
  52. data/app/jobs/shipit/clear_git_cache_job.rb +1 -0
  53. data/app/jobs/shipit/continuous_delivery_job.rb +3 -1
  54. data/app/jobs/shipit/create_on_github_job.rb +6 -1
  55. data/app/jobs/shipit/create_release_statuses_job.rb +1 -0
  56. data/app/jobs/shipit/deferred_touch_job.rb +4 -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_stack_job.rb +3 -2
  60. data/app/jobs/shipit/emit_event_job.rb +2 -1
  61. data/app/jobs/shipit/fetch_commit_stats_job.rb +1 -0
  62. data/app/jobs/shipit/fetch_deployed_revision_job.rb +2 -1
  63. data/app/jobs/shipit/github_sync_job.rb +3 -2
  64. data/app/jobs/shipit/{mark_deploy_healty_job.rb → mark_deploy_healthy_job.rb} +1 -0
  65. data/app/jobs/shipit/merge_pull_requests_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 +14 -5
  68. data/app/jobs/shipit/purge_old_deliveries_job.rb +1 -0
  69. data/app/jobs/shipit/reap_dead_tasks_job.rb +21 -0
  70. data/app/jobs/shipit/refresh_check_runs_job.rb +1 -0
  71. data/app/jobs/shipit/refresh_github_user_job.rb +1 -0
  72. data/app/jobs/shipit/refresh_pull_request_job.rb +1 -0
  73. data/app/jobs/shipit/refresh_statuses_job.rb +1 -0
  74. data/app/jobs/shipit/setup_github_hook_job.rb +1 -0
  75. data/app/jobs/shipit/update_estimated_deploy_duration_job.rb +1 -0
  76. data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +6 -3
  77. data/app/models/concerns/shipit/deferred_touch.rb +4 -3
  78. data/app/models/shipit/anonymous_user.rb +5 -0
  79. data/app/models/shipit/api_client.rb +3 -2
  80. data/app/models/shipit/application_record.rb +2 -1
  81. data/app/models/shipit/check_run.rb +4 -3
  82. data/app/models/shipit/command_line_user.rb +1 -0
  83. data/app/models/shipit/commit.rb +31 -12
  84. data/app/models/shipit/commit_checks.rb +1 -0
  85. data/app/models/shipit/commit_deployment.rb +17 -12
  86. data/app/models/shipit/commit_deployment_status.rb +8 -3
  87. data/app/models/shipit/commit_message.rb +1 -0
  88. data/app/models/shipit/delivery.rb +4 -3
  89. data/app/models/shipit/deploy.rb +40 -10
  90. data/app/models/shipit/deploy_spec.rb +22 -3
  91. data/app/models/shipit/deploy_spec/bundler_discovery.rb +2 -1
  92. data/app/models/shipit/deploy_spec/capistrano_discovery.rb +1 -0
  93. data/app/models/shipit/deploy_spec/file_system.rb +10 -3
  94. data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +1 -0
  95. data/app/models/shipit/deploy_spec/lerna_discovery.rb +1 -0
  96. data/app/models/shipit/deploy_spec/npm_discovery.rb +5 -4
  97. data/app/models/shipit/deploy_spec/pypi_discovery.rb +1 -0
  98. data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -0
  99. data/app/models/shipit/deploy_stats.rb +58 -0
  100. data/app/models/shipit/duration.rb +3 -2
  101. data/app/models/shipit/ephemeral_commit_checks.rb +1 -0
  102. data/app/models/shipit/github_hook.rb +2 -1
  103. data/app/models/shipit/github_status.rb +3 -2
  104. data/app/models/shipit/hook.rb +6 -5
  105. data/app/models/shipit/membership.rb +3 -2
  106. data/app/models/shipit/output_chunk.rb +7 -2
  107. data/app/models/shipit/pull_request.rb +13 -7
  108. data/app/models/shipit/record.rb +18 -0
  109. data/app/models/shipit/release_status.rb +3 -2
  110. data/app/models/shipit/repository.rb +43 -0
  111. data/app/models/shipit/rollback.rb +1 -0
  112. data/app/models/shipit/stack.rb +109 -50
  113. data/app/models/shipit/status.rb +3 -2
  114. data/app/models/shipit/status/common.rb +7 -6
  115. data/app/models/shipit/status/group.rb +1 -0
  116. data/app/models/shipit/status/missing.rb +2 -1
  117. data/app/models/shipit/status/unknown.rb +2 -1
  118. data/app/models/shipit/task.rb +64 -9
  119. data/app/models/shipit/task_definition.rb +1 -0
  120. data/app/models/shipit/team.rb +2 -1
  121. data/app/models/shipit/undeployed_commit.rb +1 -0
  122. data/app/models/shipit/unlimited_api_client.rb +1 -0
  123. data/app/models/shipit/user.rb +29 -5
  124. data/app/models/shipit/variable_definition.rb +1 -0
  125. data/app/models/shipit/webhooks.rb +33 -0
  126. data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +20 -0
  127. data/app/models/shipit/webhooks/handlers/handler.rb +41 -0
  128. data/app/models/shipit/webhooks/handlers/membership_handler.rb +46 -0
  129. data/app/models/shipit/webhooks/handlers/push_handler.rb +21 -0
  130. data/app/models/shipit/webhooks/handlers/status_handler.rb +27 -0
  131. data/app/serializers/concerns/shipit/conditional_attributes.rb +1 -0
  132. data/app/serializers/shipit/anonymous_user_serializer.rb +1 -0
  133. data/app/serializers/shipit/command_line_user_serializer.rb +1 -0
  134. data/app/serializers/shipit/commit_serializer.rb +1 -0
  135. data/app/serializers/shipit/deploy_serializer.rb +2 -1
  136. data/app/serializers/shipit/hook_serializer.rb +1 -0
  137. data/app/serializers/shipit/pull_request_serializer.rb +1 -0
  138. data/app/serializers/shipit/rollback_serializer.rb +1 -0
  139. data/app/serializers/shipit/short_commit_serializer.rb +1 -0
  140. data/app/serializers/shipit/stack_serializer.rb +7 -1
  141. data/app/serializers/shipit/tail_task_serializer.rb +1 -0
  142. data/app/serializers/shipit/task_serializer.rb +2 -17
  143. data/app/serializers/shipit/user_serializer.rb +6 -1
  144. data/app/validators/ascii_only_validator.rb +4 -3
  145. data/app/validators/subset_validator.rb +1 -0
  146. data/app/views/layouts/_head.html.erb +0 -0
  147. data/app/views/layouts/shipit.html.erb +6 -4
  148. data/app/views/shipit/_variables.html.erb +1 -1
  149. data/app/views/shipit/api_clients/index.html.erb +36 -0
  150. data/app/views/shipit/api_clients/new.html.erb +33 -0
  151. data/app/views/shipit/api_clients/show.html.erb +35 -0
  152. data/app/views/shipit/ccmenu/project.xml.builder +2 -1
  153. data/app/views/shipit/deploys/new.html.erb +17 -12
  154. data/app/views/shipit/deploys/show.html.erb +2 -2
  155. data/app/views/shipit/merge_status/logged_out.erb +1 -1
  156. data/app/views/shipit/stacks/_header.html.erb +27 -12
  157. data/app/views/shipit/stacks/_links.html.erb +1 -0
  158. data/app/views/shipit/stacks/all_tasks.html.erb +28 -0
  159. data/app/views/shipit/stacks/index.html.erb +7 -2
  160. data/app/views/shipit/stacks/settings.html.erb +19 -0
  161. data/app/views/shipit/stacks/statistics.html.erb +82 -0
  162. data/app/views/shipit/tasks/show.html.erb +1 -1
  163. data/config/initializers/inflections.rb +2 -1
  164. data/config/locales/en.yml +18 -5
  165. data/config/routes.rb +14 -2
  166. data/db/migrate/20191209231045_create_shipit_repositories.rb +12 -0
  167. data/db/migrate/20191209231307_add_repository_reference_to_stacks.rb +15 -0
  168. data/db/migrate/20191216162728_backfill_repository_data.rb +22 -0
  169. data/db/migrate/20191216163010_remove_repository_information_from_stacks.rb +20 -0
  170. data/db/migrate/20191219205202_add_archived_since_to_stacks.rb +6 -0
  171. data/db/migrate/20200102175621_optional_task_commits.rb +6 -0
  172. data/db/migrate/20200109132519_add_sha_to_commit_deployments.rb +5 -0
  173. data/db/migrate/20200226211925_add_index_to_tasks_status.rb +5 -0
  174. data/db/migrate/20200427135152_add_pull_request_head_sha_to_commit.rb +5 -0
  175. data/db/migrate/20200615181558_add_rollback_once_aborted_to.rb +5 -0
  176. data/lib/shipit.rb +18 -20
  177. data/lib/shipit/cast_value.rb +1 -0
  178. data/lib/shipit/command.rb +14 -18
  179. data/lib/shipit/commands.rb +5 -4
  180. data/lib/shipit/csv_serializer.rb +1 -0
  181. data/lib/shipit/deploy_commands.rb +1 -0
  182. data/lib/shipit/engine.rb +11 -2
  183. data/lib/shipit/environment_variables.rb +11 -1
  184. data/lib/shipit/first_parent_commits_iterator.rb +1 -0
  185. data/lib/shipit/flock.rb +1 -0
  186. data/lib/shipit/github_app.rb +60 -6
  187. data/lib/shipit/github_http_cache_middleware.rb +57 -0
  188. data/lib/shipit/null_serializer.rb +1 -0
  189. data/lib/shipit/octokit_check_runs.rb +3 -2
  190. data/lib/shipit/octokit_iterator.rb +3 -2
  191. data/lib/shipit/paginator.rb +3 -2
  192. data/lib/shipit/rollback_commands.rb +1 -0
  193. data/lib/shipit/same_site_cookie_middleware.rb +29 -0
  194. data/lib/shipit/simple_message_verifier.rb +1 -0
  195. data/lib/shipit/stack_commands.rb +6 -3
  196. data/lib/shipit/stat.rb +1 -0
  197. data/lib/shipit/task_commands.rb +22 -14
  198. data/lib/shipit/version.rb +2 -1
  199. data/lib/snippets/release-gem +5 -1
  200. data/lib/tasks/cron.rake +2 -0
  201. data/lib/tasks/dev.rake +3 -2
  202. data/lib/tasks/shipit.rake +16 -17
  203. data/lib/tasks/teams.rake +1 -0
  204. data/test/controllers/api/base_controller_test.rb +3 -2
  205. data/test/controllers/api/ccmenu_controller_test.rb +9 -8
  206. data/test/controllers/api/commits_controller_test.rb +3 -2
  207. data/test/controllers/api/deploys_controller_test.rb +15 -14
  208. data/test/controllers/api/hooks_controller_test.rb +8 -7
  209. data/test/controllers/api/locks_controller_test.rb +7 -6
  210. data/test/controllers/api/outputs_controller_test.rb +3 -2
  211. data/test/controllers/api/pull_requests_controller_test.rb +8 -7
  212. data/test/controllers/api/release_statuses_controller_test.rb +2 -1
  213. data/test/controllers/api/rollback_controller_test.rb +113 -0
  214. data/test/controllers/api/stacks_controller_test.rb +44 -15
  215. data/test/controllers/api/tasks_controller_test.rb +13 -12
  216. data/test/controllers/api_clients_controller_test.rb +104 -0
  217. data/test/controllers/ccmenu_controller_test.rb +4 -3
  218. data/test/controllers/commit_checks_controller_test.rb +4 -3
  219. data/test/controllers/commits_controller_test.rb +3 -2
  220. data/test/controllers/deploys_controller_test.rb +33 -22
  221. data/test/controllers/github_authentication_controller_test.rb +1 -0
  222. data/test/controllers/merge_status_controller_test.rb +27 -9
  223. data/test/controllers/pull_requests_controller_test.rb +4 -3
  224. data/test/controllers/release_statuses_controller_test.rb +3 -2
  225. data/test/controllers/rollbacks_controller_test.rb +9 -8
  226. data/test/controllers/stacks_controller_test.rb +64 -15
  227. data/test/controllers/status_controller_test.rb +1 -0
  228. data/test/controllers/tasks_controller_test.rb +20 -19
  229. data/test/controllers/webhooks_controller_test.rb +36 -9
  230. data/test/dummy/config/application.rb +1 -1
  231. data/test/dummy/config/environments/development.rb +24 -4
  232. data/test/dummy/config/environments/test.rb +2 -0
  233. data/test/dummy/db/schema.rb +25 -11
  234. data/test/dummy/db/seeds.rb +34 -17
  235. data/test/fixtures/shipit/commit_deployment_statuses.yml +4 -4
  236. data/test/fixtures/shipit/commit_deployments.yml +8 -8
  237. data/test/fixtures/shipit/commits.yml +38 -0
  238. data/test/fixtures/shipit/repositories.yml +27 -0
  239. data/test/fixtures/shipit/stacks.yml +190 -30
  240. data/test/fixtures/shipit/tasks.yml +66 -3
  241. data/test/fixtures/timeout +2 -1
  242. data/test/helpers/api_helper.rb +1 -0
  243. data/test/helpers/fixture_aliases_helper.rb +1 -0
  244. data/test/helpers/hooks_helper.rb +2 -1
  245. data/test/helpers/json_helper.rb +15 -11
  246. data/test/helpers/links_helper.rb +4 -3
  247. data/test/helpers/payloads_helper.rb +1 -0
  248. data/test/helpers/queries_helper.rb +3 -2
  249. data/test/jobs/cache_deploy_spec_job_test.rb +2 -1
  250. data/test/jobs/chunk_rollup_job_test.rb +1 -0
  251. data/test/jobs/deliver_hook_job_test.rb +2 -1
  252. data/test/jobs/destroy_stack_job_test.rb +10 -0
  253. data/test/jobs/emit_event_job_test.rb +2 -1
  254. data/test/jobs/fetch_commit_stats_job_test.rb +1 -0
  255. data/test/jobs/fetch_deployed_revision_job_test.rb +1 -0
  256. data/test/jobs/github_sync_job_test.rb +1 -0
  257. data/test/jobs/mark_deploy_healthy_job_test.rb +1 -0
  258. data/test/jobs/merge_pull_requests_job_test.rb +5 -4
  259. data/test/jobs/perform_task_job_test.rb +4 -3
  260. data/test/jobs/purge_old_deliveries_job_test.rb +1 -0
  261. data/test/jobs/reap_dead_tasks_job_test.rb +68 -0
  262. data/test/jobs/refresh_github_user_job_test.rb +1 -0
  263. data/test/jobs/refresh_status_job_test.rb +1 -0
  264. data/test/jobs/unique_job_test.rb +1 -0
  265. data/test/jobs/update_github_last_deployed_ref_job_test.rb +13 -11
  266. data/test/middleware/same_site_cookie_middleware_test.rb +52 -0
  267. data/test/models/api_client_test.rb +1 -0
  268. data/test/models/commit_checks_test.rb +1 -0
  269. data/test/models/commit_deployment_status_test.rb +34 -4
  270. data/test/models/commit_deployment_test.rb +9 -11
  271. data/test/models/commits_test.rb +99 -7
  272. data/test/models/delivery_test.rb +3 -2
  273. data/test/models/deploy_spec_test.rb +47 -42
  274. data/test/models/deploy_stats_test.rb +113 -0
  275. data/test/models/deploys_test.rb +60 -13
  276. data/test/models/duration_test.rb +1 -0
  277. data/test/models/github_hook_test.rb +1 -0
  278. data/test/models/hook_test.rb +20 -16
  279. data/test/models/membership_test.rb +1 -0
  280. data/test/models/output_chunk_test.rb +1 -0
  281. data/test/models/pull_request_test.rb +18 -11
  282. data/test/models/release_statuses_test.rb +1 -0
  283. data/test/models/rollbacks_test.rb +1 -0
  284. data/test/models/shipit/check_run_test.rb +1 -0
  285. data/test/models/shipit/repository_test.rb +77 -0
  286. data/test/models/shipit/wehbooks/handlers_test.rb +27 -0
  287. data/test/models/stacks_test.rb +110 -56
  288. data/test/models/status/group_test.rb +1 -0
  289. data/test/models/status/missing_test.rb +1 -0
  290. data/test/models/status_test.rb +1 -0
  291. data/test/models/task_definitions_test.rb +9 -8
  292. data/test/models/tasks_test.rb +18 -1
  293. data/test/models/team_test.rb +4 -2
  294. data/test/models/undeployed_commits_test.rb +14 -0
  295. data/test/models/users_test.rb +109 -1
  296. data/test/test_command_integration.rb +3 -2
  297. data/test/test_helper.rb +38 -34
  298. data/test/unit/anonymous_user_serializer_test.rb +14 -0
  299. data/test/unit/command_test.rb +12 -7
  300. data/test/unit/commands_test.rb +1 -0
  301. data/test/unit/commit_serializer_test.rb +16 -0
  302. data/test/unit/csv_serializer_test.rb +3 -2
  303. data/test/unit/deploy_commands_test.rb +14 -4
  304. data/test/unit/deploy_serializer_test.rb +17 -0
  305. data/test/unit/environment_variables_test.rb +5 -4
  306. data/test/unit/github_app_test.rb +165 -0
  307. data/test/unit/github_url_helper_test.rb +1 -0
  308. data/test/unit/rollback_commands_test.rb +2 -1
  309. data/test/unit/shipit_helper_test.rb +17 -0
  310. data/test/unit/shipit_test.rb +1 -0
  311. data/test/unit/user_serializer_test.rb +14 -0
  312. data/test/unit/variable_definition_test.rb +1 -0
  313. metadata +215 -157
  314. data/lib/shipit/strip_cache_control.rb +0 -40
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ require 'test_helper'
3
+
4
+ module Shipit
5
+ module Webhooks
6
+ class HandlersTest < ActiveSupport::TestCase
7
+ test 'custom handlers do not replace default shipit handlers' do
8
+ event = 'push'
9
+ mock_handler = mock
10
+ Shipit::Webhooks.register_handler(event, mock_handler)
11
+
12
+ assert_includes Shipit::Webhooks.for_event(event), mock_handler
13
+ assert_includes Shipit::Webhooks.for_event(event), Shipit::Webhooks::Handlers::PushHandler
14
+
15
+ Shipit::Webhooks.reset_handlers!
16
+ end
17
+
18
+ test "unknown events have no handlers" do
19
+ event = '_'
20
+
21
+ handlers = Shipit::Webhooks.for_event(event)
22
+
23
+ assert_equal [], handlers
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
  require 'securerandom'
3
4
 
@@ -9,43 +10,6 @@ module Shipit
9
10
  GithubHook.any_instance.stubs(:teardown!)
10
11
  end
11
12
 
12
- test "repo_owner, repo_name and environment uniqueness is enforced" do
13
- clone = Stack.new(@stack.attributes.except('id'))
14
- refute clone.save
15
- assert_equal ["cannot be used more than once with this environment"], clone.errors[:repo_name]
16
- end
17
-
18
- test "repo_owner, repo_name, and environment can only be ASCII" do
19
- @stack.update(repo_owner: 'héllò', repo_name: 'wørld', environment: 'pródüctïòn')
20
- refute_predicate @stack, :valid?
21
- end
22
-
23
- test "repo_owner and repo_name are case insensitive" do
24
- assert_no_difference -> { Stack.count } do
25
- error = assert_raises ActiveRecord::RecordInvalid do
26
- Stack.create!(
27
- repo_owner: @stack.repo_owner.upcase,
28
- repo_name: @stack.repo_name.upcase,
29
- environment: @stack.environment,
30
- )
31
- end
32
- assert_equal 'Validation failed: Repo name cannot be used more than once with this environment', error.message
33
- end
34
-
35
- new_stack = Stack.create!(repo_owner: 'FOO', repo_name: 'BAR')
36
- assert_equal new_stack, Stack.find_by(repo_owner: 'foo', repo_name: 'bar')
37
- end
38
-
39
- test "repo_owner is automatically downcased" do
40
- @stack.repo_owner = 'George'
41
- assert_equal 'george', @stack.repo_owner
42
- end
43
-
44
- test "repo_name is automatically downcased" do
45
- @stack.repo_name = 'Cyclim.se'
46
- assert_equal 'cyclim.se', @stack.repo_name
47
- end
48
-
49
13
  test "branch defaults to master" do
50
14
  @stack.branch = ""
51
15
  assert @stack.save
@@ -64,18 +28,6 @@ module Shipit
64
28
  assert_equal 'foo:bar', @stack.environment
65
29
  end
66
30
 
67
- test "repo_owner cannot contain a `/`" do
68
- assert @stack.valid?
69
- @stack.repo_owner = 'foo/bar'
70
- refute @stack.valid?
71
- end
72
-
73
- test "repo_name cannot contain a `/`" do
74
- assert @stack.valid?
75
- @stack.repo_name = 'foo/bar'
76
- refute @stack.valid?
77
- end
78
-
79
31
  test "repo_http_url" do
80
32
  assert_equal "https://github.com/#{@stack.repo_owner}/#{@stack.repo_name}", @stack.repo_http_url
81
33
  end
@@ -104,6 +56,30 @@ module Shipit
104
56
  assert_equal shipit_deploys(:shipit_complete).until_commit_id, deploy.since_commit_id
105
57
  end
106
58
 
59
+ test "#trigger_deploy emits a hook" do
60
+ original_receivers = Shipit.internal_hook_receivers
61
+
62
+ FakeReceiver = Module.new do
63
+ mattr_accessor :hooks
64
+ self.hooks = []
65
+
66
+ def self.deliver(event, stack, payload)
67
+ hooks << [event, stack, payload]
68
+ end
69
+ end
70
+ Shipit.internal_hook_receivers = [FakeReceiver]
71
+
72
+ last_commit = shipit_commits(:third)
73
+ deploy = @stack.trigger_deploy(last_commit, AnonymousUser.new)
74
+ assert_includes(FakeReceiver.hooks, [
75
+ :deploy,
76
+ @stack,
77
+ { deploy: deploy, status: "pending", stack: @stack },
78
+ ])
79
+ ensure
80
+ Shipit.internal_hook_receivers = original_receivers
81
+ end
82
+
107
83
  test "#trigger_deploy deploy until the commit passed in argument" do
108
84
  last_commit = shipit_commits(:third)
109
85
  deploy = @stack.trigger_deploy(last_commit, AnonymousUser.new)
@@ -225,7 +201,7 @@ module Shipit
225
201
 
226
202
  test "#create queues a GithubSyncJob" do
227
203
  assert_enqueued_with(job: GithubSyncJob) do
228
- Stack.create!(repo_name: 'rails', repo_owner: 'rails')
204
+ Stack.create!(repository: shipit_repositories(:rails))
229
205
  end
230
206
  end
231
207
 
@@ -273,7 +249,10 @@ module Shipit
273
249
  end
274
250
 
275
251
  test ".run_deploy_in_foreground triggers a deploy" do
276
- stack = Stack.create!(repo_owner: 'foo', repo_name: 'bar', environment: 'production')
252
+ stack = Stack.create!(
253
+ repository: Repository.new(owner: "foo", name: "bar"),
254
+ environment: 'production',
255
+ )
277
256
  commit = shipit_commits(:first)
278
257
  stack.commits << commit
279
258
 
@@ -328,7 +307,7 @@ module Shipit
328
307
  end
329
308
 
330
309
  test "#monitoring returns deploy_spec's content" do
331
- assert_equal [{'image' => 'https://example.com/monitor.png', 'width' => 200, 'height' => 300}], @stack.monitoring
310
+ assert_equal [{ 'image' => 'https://example.com/monitor.png', 'width' => 200, 'height' => 300 }], @stack.monitoring
332
311
  end
333
312
 
334
313
  test "#destroy deletes the related commits" do
@@ -360,7 +339,7 @@ module Shipit
360
339
  time = Time.current
361
340
  @stack.update(lock_reason: "Just for fun", lock_author: shipit_users(:walrus))
362
341
  travel 1.day
363
- expect_hook(:lock, @stack, locked: false, lock_details: {from: time, until: Time.current}, stack: @stack) do
342
+ expect_hook(:lock, @stack, locked: false, lock_details: { from: time, until: Time.current }, stack: @stack) do
364
343
  @stack.update(lock_reason: nil)
365
344
  end
366
345
  end
@@ -411,7 +390,7 @@ module Shipit
411
390
 
412
391
  test "updating the stack emit a hook" do
413
392
  expect_hook(:stack, @stack, action: :updated, stack: @stack) do
414
- @stack.update(repo_name: 'foo')
393
+ @stack.update(environment: 'foo')
415
394
  end
416
395
  end
417
396
 
@@ -505,7 +484,9 @@ module Shipit
505
484
 
506
485
  assert_no_enqueued_jobs do
507
486
  assert_no_difference -> { Deploy.count } do
508
- @stack.trigger_continuous_delivery
487
+ value = @stack.trigger_continuous_delivery
488
+
489
+ assert_nil value
509
490
  end
510
491
  end
511
492
  end
@@ -573,7 +554,24 @@ module Shipit
573
554
  end
574
555
  end
575
556
 
557
+ test "#trigger_continuous_delivery bails out if no DeploySpec has been cached" do
558
+ @stack = shipit_stacks(:check_deploy_spec)
559
+ deploy_spec = @stack.cached_deploy_spec
560
+
561
+ assert_predicate @stack, :deployable?
562
+ refute_predicate @stack, :deployed_too_recently?
563
+ assert(deploy_spec.blank?, "DeploySpec blank? returned false")
564
+
565
+ assert_no_enqueued_jobs(only: Shipit::PerformTaskJob) do
566
+ assert_no_difference -> { Deploy.count } do
567
+ @stack.trigger_continuous_delivery
568
+ end
569
+ end
570
+ end
571
+
576
572
  test "#trigger_continuous_delivery enqueues deployment ref update job" do
573
+ Shipit.stubs(:update_latest_deployed_ref).returns(true)
574
+
577
575
  @stack = shipit_stacks(:shipit_canaries)
578
576
  shipit_tasks(:canaries_running).delete
579
577
 
@@ -589,6 +587,8 @@ module Shipit
589
587
  end
590
588
 
591
589
  test "#trigger_continuous_delivery executes ref update job with correct sha" do
590
+ Shipit.stubs(:update_latest_deployed_ref).returns(true)
591
+
592
592
  @stack = shipit_stacks(:shipit_canaries)
593
593
  shipit_tasks(:canaries_running).delete
594
594
 
@@ -620,7 +620,7 @@ module Shipit
620
620
  @stack.tasks.delete_all
621
621
 
622
622
  deploy = @stack.trigger_continuous_delivery
623
- assert_equal({'SAFETY_DISABLED' => '0'}, deploy.env)
623
+ assert_equal({ 'SAFETY_DISABLED' => '0' }, deploy.env)
624
624
  end
625
625
 
626
626
  test "#continuous_delivery_delayed! bumps updated_at" do
@@ -870,6 +870,56 @@ module Shipit
870
870
  )
871
871
  end
872
872
 
873
+ test "#trigger_continuous_delivery sets delay if commit was pushed recently" do
874
+ freeze_time do
875
+ @stack.tasks.delete_all
876
+
877
+ commit = @stack.next_commit_to_deploy
878
+ commit.touch(:created_at)
879
+
880
+ assert_no_enqueued_jobs(only: Shipit::PerformTaskJob) do
881
+ assert_no_difference -> { Deploy.count } do
882
+ @stack.trigger_continuous_delivery
883
+ end
884
+ end
885
+ end
886
+ end
887
+
888
+ test "#links performs template substitutions" do
889
+ @stack.repo_name = "expected-repository-name"
890
+ @stack.environment = "expected-environment"
891
+ @stack.cached_deploy_spec = create_deploy_spec(
892
+ "links" => {
893
+ "logs" => "http://logs.$GITHUB_REPO_NAME.$ENVIRONMENT.domain.com",
894
+ "monitoring" => "https://graphs.$GITHUB_REPO_NAME.$ENVIRONMENT.domain.com",
895
+ },
896
+ )
897
+
898
+ assert_equal(
899
+ {
900
+ "logs" => "http://logs.expected-repository-name.expected-environment.domain.com",
901
+ "monitoring" => "https://graphs.expected-repository-name.expected-environment.domain.com",
902
+ },
903
+ @stack.links,
904
+ )
905
+ end
906
+
907
+ test "#env includes the stack's environment" do
908
+ expected_environment = {
909
+ 'ENVIRONMENT' => @stack.environment,
910
+ 'LAST_DEPLOYED_SHA' => @stack.last_deployed_commit.sha,
911
+ 'GITHUB_REPO_OWNER' => @stack.repository.owner,
912
+ 'GITHUB_REPO_NAME' => @stack.repository.name,
913
+ 'DEPLOY_URL' => @stack.deploy_url,
914
+ 'BRANCH' => @stack.branch,
915
+ }
916
+
917
+ assert_equal(
918
+ @stack.env,
919
+ expected_environment,
920
+ )
921
+ end
922
+
873
923
  private
874
924
 
875
925
  def generate_revert_commit(stack:, reverted_commit:, author: reverted_commit.author)
@@ -882,5 +932,9 @@ module Shipit
882
932
  committed_at: Time.zone.now,
883
933
  )
884
934
  end
935
+
936
+ def create_deploy_spec(spec)
937
+ Shipit::DeploySpec.new(spec.stringify_keys)
938
+ end
885
939
  end
886
940
  end
@@ -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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -11,10 +12,10 @@ module Shipit
11
12
  'steps' => ['touch tmp/restart'],
12
13
  'allow_concurrency' => true,
13
14
  'variables' => [
14
- {'name' => 'FOO', 'title' => 'Set to 0 to foo', 'default' => '1'},
15
- {'name' => 'BAR', 'title' => 'Set to 1 to bar', 'default' => '0'},
16
- {'name' => 'WALRUS', 'title' => 'Use with caution', 'default' => ' '},
17
- {'name' => 'NODEFAULT', 'title' => 'Variable without default'},
15
+ { 'name' => 'FOO', 'title' => 'Set to 0 to foo', 'default' => '1' },
16
+ { 'name' => 'BAR', 'title' => 'Set to 1 to bar', 'default' => '0' },
17
+ { 'name' => 'WALRUS', 'title' => 'Use with caution', 'default' => ' ' },
18
+ { 'name' => 'NODEFAULT', 'title' => 'Variable without default' },
18
19
  ],
19
20
  )
20
21
  end
@@ -43,10 +44,10 @@ module Shipit
43
44
  checklist: [],
44
45
  allow_concurrency: true,
45
46
  variables: [
46
- {'name' => 'FOO', 'title' => 'Set to 0 to foo', 'default' => '1', 'select' => nil},
47
- {'name' => 'BAR', 'title' => 'Set to 1 to bar', 'default' => '0', 'select' => nil},
48
- {'name' => 'WALRUS', 'title' => 'Use with caution', 'default' => ' ', 'select' => nil},
49
- {'name' => 'NODEFAULT', 'title' => 'Variable without default', 'default' => '', 'select' => nil},
47
+ { 'name' => 'FOO', 'title' => 'Set to 0 to foo', 'default' => '1', 'select' => nil },
48
+ { 'name' => 'BAR', 'title' => 'Set to 1 to bar', 'default' => '0', 'select' => nil },
49
+ { 'name' => 'WALRUS', 'title' => 'Use with caution', 'default' => ' ', 'select' => nil },
50
+ { 'name' => 'NODEFAULT', 'title' => 'Variable without default', 'default' => '', 'select' => nil },
50
51
  ],
51
52
  }
52
53
  assert_equal as_json, TaskDefinition.load(TaskDefinition.dump(@definition)).as_json
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
4
5
  class TasksTest < ActiveSupport::TestCase
5
6
  test "#title interpolates env" do
6
7
  task = shipit_tasks(:shipit_rendered_failover)
7
- assert_equal({'POD_ID' => '12'}, task.env)
8
+ assert_equal({ 'POD_ID' => '12' }, task.env)
8
9
  assert_equal 'Failover pod 12', task.title
9
10
  end
10
11
 
@@ -30,5 +31,21 @@ module Shipit
30
31
 
31
32
  task.write("hello\nworld")
32
33
  end
34
+
35
+ test "#chunk_output truncates output exceeding the storage limit" do
36
+ task = shipit_tasks(:shipit)
37
+ task.chunks.delete_all
38
+ # Dont persist the chunk to the DB, as it may exceed the MySQL max packet size on CI
39
+ task.chunks.build(text: 'a' * (Task::OUTPUT_SIZE_LIMIT * 1.1))
40
+
41
+ output = task.chunk_output
42
+
43
+ assert output.size <= Task::OUTPUT_SIZE_LIMIT, "Output was not truncated to the limit"
44
+ # We don't use assert_includes because it will print the whole message
45
+ assert(
46
+ output.include?(Task::OUTPUT_TRUNCATED_MESSAGE),
47
+ "'#{Task::OUTPUT_TRUNCATED_MESSAGE.chomp}' was not present in the output",
48
+ )
49
+ end
33
50
  end
34
51
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -11,16 +12,17 @@ module Shipit
11
12
  end
12
13
 
13
14
  test ".find_or_create_by_handle fetch the team from github if it's not in the db already" do
14
- Shipit.github.api.expects(:org_teams).with('shopify', per_page: 100)
15
15
  response = stub(rels: {}, data: [new_team])
16
+ Shipit.github.api.expects(:org_teams).with('shopify', per_page: 100).returns(response.data)
16
17
  Shipit.github.api.expects(:last_response).returns(response)
18
+
17
19
  assert_difference -> { Team.count }, 1 do
18
20
  Team.find_or_create_by_handle('Shopify/new-team')
19
21
  end
20
22
  end
21
23
 
22
24
  test "#refresh_members! fetch all the team members from github" do
23
- response = stub(rels: {members: members_resource})
25
+ response = stub(rels: { members: members_resource })
24
26
  Shipit.github.api.expects(:get).with(@team.api_url).returns(response)
25
27
  assert_difference -> { User.count }, 1 do
26
28
  @team.refresh_members!
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
@@ -52,6 +53,19 @@ module Shipit
52
53
  assert_predicate undeployed_commit, :expected_to_be_deployed?
53
54
  end
54
55
 
56
+ test "#expected_to_be_deployed? returns true if the active task has no commit range" do
57
+ commit = shipit_commits(:task_no_commits)
58
+ next_expected_commit_to_deploy = commit.stack.next_expected_commit_to_deploy
59
+ undeployed_commit = UndeployedCommit.new(commit, index: 1, next_expected_commit_to_deploy: next_expected_commit_to_deploy)
60
+
61
+ refute_predicate next_expected_commit_to_deploy, :nil?
62
+ assert_predicate undeployed_commit.stack, :continuous_deployment
63
+ assert next_expected_commit_to_deploy.id >= undeployed_commit.id
64
+ refute_predicate undeployed_commit, :active?
65
+
66
+ assert_predicate undeployed_commit, :expected_to_be_deployed?
67
+ end
68
+
55
69
  test "#expected_to_be_deployed? returns false if the stack has continuous deployment disabled" do
56
70
  commit = shipit_commits(:cyclimse_first)
57
71
  next_expected_commit_to_deploy = commit.stack.next_expected_commit_to_deploy
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  module Shipit
4
5
  class UsersTest < ActiveSupport::TestCase
5
6
  setup do
7
+ @previous_preferred_org_emails = Shipit.preferred_org_emails
6
8
  @user = shipit_users(:walrus)
7
9
  @github_user = stub(
8
10
  id: 42,
@@ -12,6 +14,8 @@ module Shipit
12
14
  avatar_url: 'https://avatars.githubusercontent.com/u/42?v=3',
13
15
  url: 'https://api.github.com/user/george',
14
16
  )
17
+ @org_domain = "shopify.com"
18
+ @emails_url = "https://api.github.com/user/emails"
15
19
  @minimal_github_user = stub(
16
20
  id: 43,
17
21
  name: nil,
@@ -23,6 +27,10 @@ module Shipit
23
27
  )
24
28
  end
25
29
 
30
+ teardown do
31
+ Shipit.preferred_org_emails = @previous_preferred_org_emails
32
+ end
33
+
26
34
  test "find_or_create_from_github persist a new user if he is unknown" do
27
35
  assert_difference 'User.count', 1 do
28
36
  fetch_user
@@ -58,13 +66,113 @@ module Shipit
58
66
  end
59
67
 
60
68
  test "find_or_create_from_github accepts minimal users without name nor email" do
69
+ Shipit.preferred_org_emails = [].freeze
61
70
  user = User.find_or_create_from_github(@minimal_github_user)
62
71
  assert_equal @minimal_github_user.login, user.login
63
72
  end
64
73
 
74
+ test "find_or_create_from_github selects any email when org email is unspecified" do
75
+ github_org_user = stub(
76
+ id: 42,
77
+ name: 'Jim Jones',
78
+ login: 'jim',
79
+ email: "jim@#{@org_domain}",
80
+ avatar_url: 'https://avatars.githubusercontent.com/u/42?v=3',
81
+ url: 'https://api.github.com/user/jim',
82
+ )
83
+
84
+ Shipit.preferred_org_emails = [].freeze
85
+ user = User.find_or_create_from_github(github_org_user)
86
+ assert_equal github_org_user.email, user.email
87
+ end
88
+
89
+ test "find_or_create_from_github selects org email for user" do
90
+ Shipit.preferred_org_emails = [@org_domain]
91
+ expected_email = "myuser@#{@org_domain}"
92
+
93
+ stub_request(:get, @emails_url).to_return(
94
+ status: %w(200 OK),
95
+ body: [{ email: expected_email }].to_json,
96
+ headers: { "Content-Type" => "application/json" },
97
+ )
98
+
99
+ user = User.find_or_create_from_github(@github_user)
100
+ assert_equal expected_email, user.email
101
+ end
102
+
103
+ test "find_or_create_from_github selects private and primary org email for user when necessary" do
104
+ Shipit.preferred_org_emails = [@org_domain]
105
+ expected_email = "myuser@#{@org_domain}"
106
+ result_email_records = [
107
+ {
108
+ email: "notmyuser1@#{@org_domain}",
109
+ primary: false,
110
+ },
111
+ {
112
+ email: "notmyuser2@#{@org_domain}",
113
+ },
114
+ {
115
+ email: expected_email,
116
+ primary: true,
117
+ },
118
+ ]
119
+
120
+ stub_request(:get, @emails_url).to_return(
121
+ status: %w(200 OK),
122
+ body: result_email_records.to_json,
123
+ headers: { "Content-Type" => "application/json" },
124
+ )
125
+
126
+ user = User.find_or_create_from_github(@github_user)
127
+ assert_equal expected_email, user.email
128
+ end
129
+
130
+ test "find_or_create_from_github selects no email when org emails are provided but not found" do
131
+ Shipit.preferred_org_emails = [@org_domain]
132
+ result_email_records = [
133
+ {
134
+ email: "notmyuser1@not#{@org_domain}",
135
+ primary: false,
136
+ },
137
+ {
138
+ email: "notmyuser2@not#{@org_domain}",
139
+ },
140
+ ]
141
+
142
+ stub_request(:get, @emails_url).to_return(
143
+ status: %w(200 OK),
144
+ body: result_email_records.to_json,
145
+ headers: { "Content-Type" => "application/json" },
146
+ )
147
+
148
+ user = User.find_or_create_from_github(@github_user)
149
+ assert_nil user.email
150
+ end
151
+
152
+ test "find_or_create_from_github handles user 404" do
153
+ Shipit.preferred_org_emails = [@org_domain]
154
+ Octokit::Client.any_instance.expects(:emails).raises(Octokit::NotFound)
155
+ user = User.find_or_create_from_github(@minimal_github_user)
156
+ assert_nil user.email
157
+ end
158
+
159
+ test "find_or_create_from_github handles user 403" do
160
+ Shipit.preferred_org_emails = [@org_domain]
161
+ Octokit::Client.any_instance.expects(:emails).raises(Octokit::Forbidden)
162
+ user = User.find_or_create_from_github(@minimal_github_user)
163
+ assert_nil user.email
164
+ end
165
+
166
+ test "find_or_create_from_github handles user 401" do
167
+ Shipit.preferred_org_emails = [@org_domain]
168
+ Octokit::Client.any_instance.expects(:emails).raises(Octokit::Unauthorized)
169
+ user = User.find_or_create_from_github(@minimal_github_user)
170
+ assert_nil user.email
171
+ end
172
+
65
173
  test "#identifiers_for_ping returns a hash with the user's github_id, name, email and github_login" do
66
174
  user = shipit_users(:bob)
67
- expected_ouput = {github_id: user.github_id, name: user.name, email: user.email, github_login: user.login}
175
+ expected_ouput = { github_id: user.github_id, name: user.name, email: user.email, github_login: user.login }
68
176
  assert_equal expected_ouput, user.identifiers_for_ping
69
177
  end
70
178