shipit-engine 0.5.2 → 0.6.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 (274) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/shipit/api/cacheable.rb +13 -0
  3. data/app/controllers/concerns/shipit/api/paginable.rb +37 -0
  4. data/app/controllers/concerns/shipit/api/rendering.rb +25 -0
  5. data/app/controllers/concerns/{api/paginable.rb → shipit/pagination.rb} +5 -13
  6. data/app/controllers/shipit/api/base_controller.rb +68 -0
  7. data/app/controllers/shipit/api/deploys_controller.rb +17 -0
  8. data/app/controllers/shipit/api/hooks_controller.rb +53 -0
  9. data/app/controllers/shipit/api/locks_controller.rb +32 -0
  10. data/app/controllers/shipit/api/outputs_controller.rb +17 -0
  11. data/app/controllers/shipit/api/stacks_controller.rb +21 -0
  12. data/app/controllers/shipit/api/tasks_controller.rb +20 -0
  13. data/app/controllers/shipit/commit_checks_controller.rb +26 -0
  14. data/app/controllers/shipit/deploys_controller.rb +47 -0
  15. data/app/controllers/shipit/github_authentication_controller.rb +27 -0
  16. data/app/controllers/shipit/rollbacks_controller.rb +26 -0
  17. data/app/controllers/shipit/shipit_controller.rb +62 -0
  18. data/app/controllers/shipit/stacks_controller.rb +81 -0
  19. data/app/controllers/shipit/status_controller.rb +7 -0
  20. data/app/controllers/shipit/tasks_controller.rb +48 -0
  21. data/app/controllers/shipit/webhooks_controller.rb +101 -0
  22. data/app/helpers/shipit/chunks_helper.rb +8 -0
  23. data/app/helpers/shipit/deploys_helper.rb +28 -0
  24. data/app/helpers/shipit/github_url_helper.rb +48 -0
  25. data/app/helpers/shipit/shipit_helper.rb +64 -0
  26. data/app/helpers/shipit/stacks_helper.rb +78 -0
  27. data/app/helpers/shipit/tasks_helper.rb +11 -0
  28. data/app/jobs/shipit/background_job.rb +24 -0
  29. data/app/jobs/shipit/background_job/unique.rb +28 -0
  30. data/app/jobs/shipit/cache_deploy_spec_job.rb +12 -0
  31. data/app/jobs/shipit/chunk_rollup_job.rb +21 -0
  32. data/app/jobs/shipit/clear_git_cache_job.rb +9 -0
  33. data/app/jobs/shipit/deliver_hook_job.rb +9 -0
  34. data/app/jobs/shipit/destroy_stack_job.rb +9 -0
  35. data/app/jobs/shipit/emit_event_job.rb +10 -0
  36. data/app/jobs/shipit/fetch_commit_stats_job.rb +9 -0
  37. data/app/jobs/shipit/fetch_deployed_revision_job.rb +23 -0
  38. data/app/jobs/shipit/git_mirror_update_job.rb +12 -0
  39. data/app/jobs/shipit/github_sync_job.rb +55 -0
  40. data/app/jobs/shipit/perform_commit_checks_job.rb +7 -0
  41. data/app/jobs/shipit/perform_task_job.rb +57 -0
  42. data/app/jobs/shipit/refresh_github_user_job.rb +9 -0
  43. data/app/jobs/shipit/refresh_statuses_job.rb +14 -0
  44. data/app/jobs/shipit/setup_github_hook_job.rb +11 -0
  45. data/app/models/shipit/anonymous_user.rb +43 -0
  46. data/app/models/shipit/api_client.rb +44 -0
  47. data/app/models/shipit/commit.rb +209 -0
  48. data/app/models/shipit/commit_checks.rb +90 -0
  49. data/app/models/shipit/delivery.rb +47 -0
  50. data/app/models/shipit/deploy.rb +153 -0
  51. data/app/models/shipit/deploy_spec.rb +150 -0
  52. data/app/models/shipit/deploy_spec/bundler_discovery.rb +61 -0
  53. data/app/models/shipit/deploy_spec/capistrano_discovery.rb +29 -0
  54. data/app/models/shipit/deploy_spec/file_system.rb +64 -0
  55. data/app/models/shipit/deploy_spec/pypi_discovery.rb +34 -0
  56. data/app/models/shipit/deploy_spec/rubygems_discovery.rb +34 -0
  57. data/app/models/shipit/github_hook.rb +148 -0
  58. data/app/models/shipit/hook.rb +86 -0
  59. data/app/models/shipit/membership.rb +8 -0
  60. data/app/models/shipit/missing_status.rb +21 -0
  61. data/app/models/shipit/output_chunk.rb +11 -0
  62. data/app/models/shipit/rollback.rb +31 -0
  63. data/app/models/shipit/stack.rb +308 -0
  64. data/app/models/shipit/status.rb +44 -0
  65. data/app/models/shipit/status_group.rb +35 -0
  66. data/app/models/shipit/task.rb +201 -0
  67. data/app/models/shipit/task_definition.rb +38 -0
  68. data/app/models/shipit/team.rb +69 -0
  69. data/app/models/shipit/unknown_status.rb +43 -0
  70. data/app/models/shipit/user.rb +83 -0
  71. data/app/models/shipit/variable_definition.rb +21 -0
  72. data/app/serializers/concerns/shipit/conditional_attributes.rb +22 -0
  73. data/app/serializers/shipit/anonymous_user_serializer.rb +4 -0
  74. data/app/serializers/shipit/commit_serializer.rb +8 -0
  75. data/app/serializers/shipit/deploy_serializer.rb +15 -0
  76. data/app/serializers/shipit/hook_serializer.rb +12 -0
  77. data/app/serializers/shipit/rollback_serializer.rb +7 -0
  78. data/app/serializers/shipit/short_commit_serializer.rb +9 -0
  79. data/app/serializers/shipit/stack_serializer.rb +33 -0
  80. data/app/serializers/shipit/tail_task_serializer.rb +39 -0
  81. data/app/serializers/shipit/task_serializer.rb +30 -0
  82. data/app/serializers/shipit/user_serializer.rb +5 -0
  83. data/app/views/{commits → shipit/commits}/_commit.html.erb +1 -1
  84. data/app/views/{commits → shipit/commits}/_commit_author.html.erb +0 -0
  85. data/app/views/{deploys → shipit/deploys}/_checklist.html.erb +0 -0
  86. data/app/views/{deploys → shipit/deploys}/_checks.html.erb +0 -0
  87. data/app/views/{deploys → shipit/deploys}/_concurrent_deploy_warning.html.erb +0 -0
  88. data/app/views/{deploys → shipit/deploys}/_deploy.html.erb +1 -1
  89. data/app/views/{deploys → shipit/deploys}/_monitoring.html.erb +0 -0
  90. data/app/views/{deploys → shipit/deploys}/_summary.html.erb +0 -0
  91. data/app/views/{deploys → shipit/deploys}/new.html.erb +3 -3
  92. data/app/views/{deploys → shipit/deploys}/rollback.html.erb +2 -2
  93. data/app/views/{deploys → shipit/deploys}/show.html.erb +1 -1
  94. data/app/views/{github_authentication → shipit/github_authentication}/failed.html.erb +0 -0
  95. data/app/views/{stacks → shipit/stacks}/_header.html.erb +0 -0
  96. data/app/views/{stacks → shipit/stacks}/index.html.erb +0 -0
  97. data/app/views/{stacks → shipit/stacks}/new.html.erb +0 -0
  98. data/app/views/{stacks → shipit/stacks}/settings.html.erb +1 -1
  99. data/app/views/{stacks → shipit/stacks}/show.html.erb +2 -2
  100. data/app/views/{statuses → shipit/statuses}/_group.html.erb +1 -1
  101. data/app/views/{statuses → shipit/statuses}/_status.html.erb +0 -0
  102. data/app/views/{tasks → shipit/tasks}/_task.html.erb +1 -1
  103. data/app/views/{tasks → shipit/tasks}/_task_output.html.erb +1 -1
  104. data/app/views/{tasks → shipit/tasks}/index.html.erb +1 -1
  105. data/app/views/{tasks → shipit/tasks}/new.html.erb +1 -1
  106. data/app/views/{tasks → shipit/tasks}/show.html.erb +1 -1
  107. data/db/migrate/20160104151742_increase_tasks_type_size_back.rb +5 -0
  108. data/db/migrate/20160104151833_convert_sti_columns.rb +10 -0
  109. data/lib/shipit.rb +11 -10
  110. data/lib/shipit/command.rb +171 -0
  111. data/lib/shipit/commands.rb +25 -0
  112. data/lib/shipit/deploy_commands.rb +21 -0
  113. data/lib/shipit/engine.rb +3 -0
  114. data/lib/shipit/rollback_commands.rb +7 -0
  115. data/lib/shipit/stack_commands.rb +60 -0
  116. data/lib/shipit/task_commands.rb +68 -0
  117. data/lib/shipit/version.rb +1 -1
  118. data/lib/tasks/cron.rake +3 -3
  119. data/test/controllers/api/base_controller_test.rb +18 -14
  120. data/test/controllers/api/deploys_controller_test.rb +56 -52
  121. data/test/controllers/api/hooks_controller_test.rb +62 -58
  122. data/test/controllers/api/locks_controller_test.rb +38 -34
  123. data/test/controllers/api/outputs_controller_test.rb +15 -11
  124. data/test/controllers/api/stacks_controller_test.rb +56 -52
  125. data/test/controllers/api/tasks_controller_test.rb +30 -26
  126. data/test/controllers/commit_checks_controller_test.rb +29 -27
  127. data/test/controllers/deploys_controller_test.rb +68 -66
  128. data/test/controllers/github_authentication_controller_test.rb +9 -7
  129. data/test/controllers/rollbacks_controller_test.rb +43 -41
  130. data/test/controllers/stacks_controller_test.rb +131 -128
  131. data/test/controllers/status_controller_test.rb +8 -6
  132. data/test/controllers/tasks_controller_test.rb +70 -68
  133. data/test/controllers/webhooks_controller_test.rb +127 -125
  134. data/test/dummy/db/development.sqlite3 +0 -0
  135. data/test/dummy/db/schema.rb +2 -2
  136. data/test/dummy/db/seeds.rb +133 -131
  137. data/test/dummy/db/test.sqlite3 +0 -0
  138. data/test/fixtures/{api_clients.yml → shipit/api_clients.yml} +0 -0
  139. data/test/fixtures/{commits.yml → shipit/commits.yml} +0 -0
  140. data/test/fixtures/{deliveries.yml → shipit/deliveries.yml} +0 -0
  141. data/test/fixtures/{github_hooks.yml → shipit/github_hooks.yml} +4 -4
  142. data/test/fixtures/{hooks.yml → shipit/hooks.yml} +0 -0
  143. data/test/fixtures/{memberships.yml → shipit/memberships.yml} +0 -0
  144. data/test/fixtures/{output_chunks.yml → shipit/output_chunks.yml} +0 -0
  145. data/test/fixtures/{stacks.yml → shipit/stacks.yml} +0 -0
  146. data/test/fixtures/{statuses.yml → shipit/statuses.yml} +0 -0
  147. data/test/fixtures/{tasks.yml → shipit/tasks.yml} +8 -8
  148. data/test/fixtures/{teams.yml → shipit/teams.yml} +0 -0
  149. data/test/fixtures/{users.yml → shipit/users.yml} +0 -0
  150. data/test/helpers/api_helper.rb +1 -1
  151. data/test/helpers/fixture_aliases_helper.rb +4 -4
  152. data/test/jobs/cache_deploy_spec_job_test.rb +15 -13
  153. data/test/jobs/chunk_rollup_job_test.rb +30 -28
  154. data/test/jobs/deliver_hook_job_test.rb +11 -9
  155. data/test/jobs/destroy_stack_job_test.rb +11 -9
  156. data/test/jobs/emit_event_job_test.rb +10 -8
  157. data/test/jobs/fetch_commit_stats_job_test.rb +10 -8
  158. data/test/jobs/fetch_deployed_revision_job_test.rb +24 -22
  159. data/test/jobs/github_sync_job_test.rb +51 -49
  160. data/test/jobs/perform_task_job_test.rb +78 -76
  161. data/test/jobs/refresh_github_user_job_test.rb +10 -8
  162. data/test/jobs/refresh_status_job_test.rb +14 -12
  163. data/test/jobs/unique_job_test.rb +18 -15
  164. data/test/models/api_client_test.rb +20 -18
  165. data/test/models/commit_checks_test.rb +63 -61
  166. data/test/models/commits_test.rb +317 -314
  167. data/test/models/delivery_test.rb +29 -27
  168. data/test/models/deploys_test.rb +289 -287
  169. data/test/models/github_hook_test.rb +45 -43
  170. data/test/models/hook_test.rb +44 -42
  171. data/test/models/membership_test.rb +9 -7
  172. data/test/models/missing_status_test.rb +16 -14
  173. data/test/models/output_chunk_test.rb +14 -12
  174. data/test/models/rollbacks_test.rb +14 -12
  175. data/test/models/stacks_test.rb +272 -270
  176. data/test/models/status_group_test.rb +18 -16
  177. data/test/models/status_test.rb +42 -40
  178. data/test/models/task_definitions_test.rb +27 -25
  179. data/test/models/team_test.rb +39 -37
  180. data/test/models/users_test.rb +61 -59
  181. data/test/unit/command_test.rb +43 -41
  182. data/test/unit/commands_test.rb +8 -6
  183. data/test/unit/csv_serializer_test.rb +28 -26
  184. data/test/unit/deploy_commands_test.rb +179 -176
  185. data/test/unit/deploy_spec_test.rb +237 -235
  186. data/test/unit/github_url_helper_test.rb +19 -17
  187. data/test/unit/shipit_test.rb +44 -42
  188. metadata +139 -137
  189. data/app/controllers/api/base_controller.rb +0 -66
  190. data/app/controllers/api/deploys_controller.rb +0 -15
  191. data/app/controllers/api/hooks_controller.rb +0 -51
  192. data/app/controllers/api/locks_controller.rb +0 -30
  193. data/app/controllers/api/outputs_controller.rb +0 -15
  194. data/app/controllers/api/stacks_controller.rb +0 -19
  195. data/app/controllers/api/tasks_controller.rb +0 -18
  196. data/app/controllers/commit_checks_controller.rb +0 -24
  197. data/app/controllers/concerns/api/cacheable.rb +0 -11
  198. data/app/controllers/concerns/api/rendering.rb +0 -23
  199. data/app/controllers/concerns/pagination.rb +0 -25
  200. data/app/controllers/deploys_controller.rb +0 -45
  201. data/app/controllers/github_authentication_controller.rb +0 -25
  202. data/app/controllers/rollbacks_controller.rb +0 -24
  203. data/app/controllers/shipit_controller.rb +0 -54
  204. data/app/controllers/stacks_controller.rb +0 -79
  205. data/app/controllers/status_controller.rb +0 -5
  206. data/app/controllers/tasks_controller.rb +0 -46
  207. data/app/controllers/webhooks_controller.rb +0 -99
  208. data/app/helpers/chunks_helper.rb +0 -6
  209. data/app/helpers/deploys_helper.rb +0 -26
  210. data/app/helpers/github_url_helper.rb +0 -46
  211. data/app/helpers/shipit_helper.rb +0 -62
  212. data/app/helpers/stacks_helper.rb +0 -76
  213. data/app/helpers/tasks_helper.rb +0 -9
  214. data/app/jobs/background_job.rb +0 -22
  215. data/app/jobs/background_job/unique.rb +0 -26
  216. data/app/jobs/cache_deploy_spec_job.rb +0 -10
  217. data/app/jobs/chunk_rollup_job.rb +0 -19
  218. data/app/jobs/clear_git_cache_job.rb +0 -7
  219. data/app/jobs/deliver_hook_job.rb +0 -7
  220. data/app/jobs/destroy_stack_job.rb +0 -7
  221. data/app/jobs/emit_event_job.rb +0 -8
  222. data/app/jobs/fetch_commit_stats_job.rb +0 -7
  223. data/app/jobs/fetch_deployed_revision_job.rb +0 -21
  224. data/app/jobs/git_mirror_update_job.rb +0 -10
  225. data/app/jobs/github_sync_job.rb +0 -53
  226. data/app/jobs/perform_commit_checks_job.rb +0 -5
  227. data/app/jobs/perform_task_job.rb +0 -55
  228. data/app/jobs/refresh_github_user_job.rb +0 -7
  229. data/app/jobs/refresh_statuses_job.rb +0 -12
  230. data/app/jobs/setup_github_hook_job.rb +0 -9
  231. data/app/models/anonymous_user.rb +0 -41
  232. data/app/models/api_client.rb +0 -42
  233. data/app/models/commit.rb +0 -207
  234. data/app/models/commit_checks.rb +0 -88
  235. data/app/models/delivery.rb +0 -45
  236. data/app/models/deploy.rb +0 -151
  237. data/app/models/deploy_spec.rb +0 -148
  238. data/app/models/deploy_spec/bundler_discovery.rb +0 -59
  239. data/app/models/deploy_spec/capistrano_discovery.rb +0 -27
  240. data/app/models/deploy_spec/file_system.rb +0 -62
  241. data/app/models/deploy_spec/pypi_discovery.rb +0 -32
  242. data/app/models/deploy_spec/rubygems_discovery.rb +0 -32
  243. data/app/models/github_hook.rb +0 -144
  244. data/app/models/hook.rb +0 -84
  245. data/app/models/membership.rb +0 -6
  246. data/app/models/missing_status.rb +0 -18
  247. data/app/models/output_chunk.rb +0 -9
  248. data/app/models/rollback.rb +0 -29
  249. data/app/models/stack.rb +0 -306
  250. data/app/models/status.rb +0 -42
  251. data/app/models/status_group.rb +0 -33
  252. data/app/models/task.rb +0 -197
  253. data/app/models/task_definition.rb +0 -36
  254. data/app/models/team.rb +0 -67
  255. data/app/models/unknown_status.rb +0 -41
  256. data/app/models/user.rb +0 -81
  257. data/app/models/variable_definition.rb +0 -19
  258. data/app/serializers/anonymous_user_serializer.rb +0 -2
  259. data/app/serializers/commit_serializer.rb +0 -6
  260. data/app/serializers/concerns/conditional_attributes.rb +0 -20
  261. data/app/serializers/deploy_serializer.rb +0 -13
  262. data/app/serializers/hook_serializer.rb +0 -10
  263. data/app/serializers/rollback_serializer.rb +0 -5
  264. data/app/serializers/short_commit_serializer.rb +0 -7
  265. data/app/serializers/stack_serializer.rb +0 -31
  266. data/app/serializers/tail_task_serializer.rb +0 -37
  267. data/app/serializers/task_serializer.rb +0 -28
  268. data/app/serializers/user_serializer.rb +0 -3
  269. data/lib/command.rb +0 -169
  270. data/lib/commands.rb +0 -23
  271. data/lib/deploy_commands.rb +0 -19
  272. data/lib/rollback_commands.rb +0 -5
  273. data/lib/stack_commands.rb +0 -58
  274. data/lib/task_commands.rb +0 -66
@@ -0,0 +1,64 @@
1
+ module Shipit
2
+ module ShipitHelper
3
+ def include_plugins(stack)
4
+ stack.plugins.flat_map do |plugin, config|
5
+ plugin_tags(plugin, config)
6
+ end.join.html_safe
7
+ end
8
+
9
+ def plugin_tags(plugin, config)
10
+ tags = []
11
+ tags << tag('meta', name: "#{plugin}-config", content: config.to_json) if config
12
+ tags << javascript_include_tag("plugins/#{plugin}")
13
+ tags << stylesheet_link_tag("plugins/#{plugin}")
14
+ tags
15
+ end
16
+
17
+ def missing_github_oauth_message
18
+ (<<-MESSAGE).html_safe
19
+ Shipit requires a GitHub application to authenticate users.
20
+ If you haven't created an application on GitHub yet, you can do so in the
21
+ #{link_to 'Settings', Shipit.github_url('/settings/applications/new'), target: '_blank'}
22
+ section of your profile. You can also create applications for organizations.
23
+ MESSAGE
24
+ end
25
+
26
+ def missing_github_oauth_id_message
27
+ (<<-MESSAGE).html_safe
28
+ Copy the Client ID from your GitHub application,
29
+ and paste it into the secrets.yml file under <code>github_oauth.id</code>.
30
+ MESSAGE
31
+ end
32
+
33
+ def missing_github_oauth_secret_message
34
+ (<<-MESSAGE).html_safe
35
+ Copy the Client Secret from your GitHub application,
36
+ and paste it into the secrets.yml file under <code>github_oauth.secret</code>.
37
+ MESSAGE
38
+ end
39
+
40
+ def missing_github_api_credentials_message
41
+ (<<-MESSAGE).html_safe
42
+ Shipit needs API access to GitHub. You can
43
+ #{link_to 'create an access token', Shipit.github_url('/settings/tokens'), target: '_blank'}
44
+ with the following permissions:
45
+ <code>admin:repo_hook</code>, <code>admin:org_hook</code> and <code>repo</code>
46
+ and add it to the secrets.yml file under the key <code>github_api.access_token</code>.
47
+ MESSAGE
48
+ end
49
+
50
+ def missing_redis_url_message
51
+ (<<-MESSAGE).html_safe
52
+ Shipit needs a Redis server. Please configure the Redis URL in the secrets.yml file of your app,
53
+ under the key <code>redis_url</code>.
54
+ MESSAGE
55
+ end
56
+
57
+ def missing_host_message
58
+ (<<-MESSAGE).html_safe
59
+ Shipit needs the host of the application before generating links in background jobs.
60
+ Add the host name to the secrets.yml file, under the <code>host</code> key.
61
+ MESSAGE
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,78 @@
1
+ module Shipit
2
+ module StacksHelper
3
+ COMMIT_TITLE_LENGTH = 79
4
+
5
+ def redeploy_button(commit)
6
+ url = new_stack_deploy_path(@stack, sha: commit.sha)
7
+ classes = %W(btn btn--primary deploy-action #{commit.state})
8
+
9
+ unless commit.stack.deployable?
10
+ classes.push(ignore_lock? ? 'btn--warning' : 'btn--disabled')
11
+ end
12
+
13
+ caption = 'Redeploy'
14
+ caption = 'Locked' if commit.stack.locked? && !ignore_lock?
15
+ caption = 'Deploy in progress...' if commit.stack.deploying?
16
+
17
+ link_to(caption, url, class: classes)
18
+ end
19
+
20
+ def ignore_lock?
21
+ params[:force].present?
22
+ end
23
+
24
+ def deploy_button(commit)
25
+ url = new_stack_deploy_path(@stack, sha: commit.sha)
26
+ classes = %W(btn btn--primary deploy-action #{commit.state})
27
+ if deploy_button_disabled?(commit)
28
+ classes.push(params[:force].present? ? 'btn--warning' : 'btn--disabled')
29
+ end
30
+
31
+ link_to(deploy_button_caption(commit), url, class: classes)
32
+ end
33
+
34
+ def github_change_url(commit)
35
+ commit.pull_request_url || github_commit_url(commit)
36
+ end
37
+
38
+ def render_commit_message(commit)
39
+ message = commit.pull_request_title || commit.message
40
+ content_tag(:span, message.truncate(COMMIT_TITLE_LENGTH), class: 'event-message')
41
+ end
42
+
43
+ def render_commit_message_with_link(commit)
44
+ link_to(render_commit_message(commit), github_change_url(commit), target: '_blank')
45
+ end
46
+
47
+ def render_commit_id_link(commit)
48
+ if commit.pull_request?
49
+ pull_request_link(commit) + "&nbsp;(#{render_raw_commit_id_link(commit)})".html_safe
50
+ else
51
+ render_raw_commit_id_link(commit)
52
+ end
53
+ end
54
+
55
+ def pull_request_link(commit)
56
+ link_to("##{commit.pull_request_id}", commit.pull_request_url, target: '_blank', class: 'number')
57
+ end
58
+
59
+ def render_raw_commit_id_link(commit)
60
+ link_to(commit.short_sha, github_commit_url(commit), target: '_blank', class: 'number')
61
+ end
62
+
63
+ private
64
+
65
+ def deploy_button_disabled?(commit)
66
+ !commit.deployable? || !commit.stack.deployable?
67
+ end
68
+
69
+ def deploy_button_caption(commit)
70
+ state = commit.status.state
71
+ state = 'locked' if commit.stack.locked? && !ignore_lock?
72
+ if commit.deployable?
73
+ state = commit.stack.deploying? ? 'deploying' : 'enabled'
74
+ end
75
+ t("deploy_button.caption.#{state}")
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,11 @@
1
+ module Shipit
2
+ module TasksHelper
3
+ def task_description(task)
4
+ if task.class == Task
5
+ task.definition.action
6
+ else
7
+ t("#{task.class.name.underscore.pluralize}.description", sha: task.until_commit.short_sha)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ module Shipit
2
+ class BackgroundJob < ActiveJob::Base
3
+ class << self
4
+ attr_accessor :timeout
5
+ end
6
+
7
+ def perform(*)
8
+ with_timeout do
9
+ super
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def with_timeout(&block)
16
+ return yield unless timeout
17
+ Timeout.timeout(timeout, &block)
18
+ end
19
+
20
+ def logger
21
+ Rails.logger
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module Shipit
2
+ class BackgroundJob
3
+ module Unique
4
+ extend ActiveSupport::Concern
5
+
6
+ DEFAULT_TIMEOUT = 10
7
+
8
+ included do
9
+ around_perform { |job, block| job.acquire_lock(&block) }
10
+ cattr_accessor :lock_timeout
11
+ end
12
+
13
+ def acquire_lock(&block)
14
+ mutex = Redis::Lock.new(
15
+ lock_key(*arguments),
16
+ Shipit.redis,
17
+ expiration: self.class.timeout || DEFAULT_TIMEOUT,
18
+ timeout: self.class.lock_timeout || 0,
19
+ )
20
+ mutex.lock(&block)
21
+ end
22
+
23
+ def lock_key(*args)
24
+ ActiveJob::Arguments.serialize([self.class.name] + args).join('-')
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ module Shipit
2
+ class CacheDeploySpecJob < BackgroundJob
3
+ include BackgroundJob::Unique
4
+
5
+ def perform(stack)
6
+ commands = Commands.for(stack)
7
+ commands.with_temporary_working_directory(commit: stack.commits.last) do |path|
8
+ stack.update!(cached_deploy_spec: DeploySpec::FileSystem.new(path, stack.environment))
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Shipit
2
+ class ChunkRollupJob < BackgroundJob
3
+ include BackgroundJob::Unique
4
+
5
+ queue_as :default
6
+
7
+ def perform(task)
8
+ unless task.finished?
9
+ logger.error("Task ##{task.id} is not finished (current state: #{task.status}). Aborting.")
10
+ return
11
+ end
12
+
13
+ if task.rolled_up?
14
+ logger.error("Task ##{task.id} has already been rolled up. Aborting.")
15
+ return
16
+ end
17
+
18
+ task.rollup_chunks
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module Shipit
2
+ class ClearGitCacheJob < BackgroundJob
3
+ queue_as :default
4
+
5
+ def perform(stack)
6
+ stack.clear_git_cache!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Shipit
2
+ class DeliverHookJob < BackgroundJob
3
+ queue_as :hooks
4
+
5
+ def perform(delivery)
6
+ delivery.send!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Shipit
2
+ class DestroyStackJob < BackgroundJob
3
+ queue_as :default
4
+
5
+ def perform(stack)
6
+ stack.destroy!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Shipit
2
+ class EmitEventJob < BackgroundJob
3
+ queue_as :hooks
4
+
5
+ def perform(params)
6
+ event, stack_id, payload = params.with_indifferent_access.values_at('event', 'stack_id', 'payload')
7
+ Hook.deliver(event, stack_id, JSON.load(payload))
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Shipit
2
+ class FetchCommitStatsJob < BackgroundJob
3
+ queue_as :default
4
+
5
+ def perform(commit)
6
+ commit.fetch_stats!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ module Shipit
2
+ class FetchDeployedRevisionJob < BackgroundJob
3
+ queue_as :default
4
+
5
+ def perform(stack)
6
+ return if stack.deploying?
7
+
8
+ commands = StackCommands.new(stack)
9
+
10
+ begin
11
+ sha = commands.fetch_deployed_revision
12
+ rescue DeploySpec::Error
13
+ end
14
+
15
+ return unless sha.present?
16
+
17
+ begin
18
+ stack.update_deployed_revision(sha)
19
+ rescue ActiveRecord::RecordNotFound
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ module Shipit
2
+ class GitMirrorUpdateJob < BackgroundJob
3
+ queue_as :default
4
+
5
+ def perform(stack)
6
+ commands = StackCommands.new(stack)
7
+ stack.acquire_git_cache_lock do
8
+ commands.fetch.run
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,55 @@
1
+ module Shipit
2
+ class GithubSyncJob < BackgroundJob
3
+ include BackgroundJob::Unique
4
+
5
+ MAX_FETCHED_COMMITS = 10
6
+ queue_as :default
7
+
8
+ self.timeout = 60
9
+ self.lock_timeout = 20
10
+
11
+ def perform(params)
12
+ @stack = Stack.find(params[:stack_id])
13
+
14
+ handle_github_errors do
15
+ new_commits, shared_parent = fetch_missing_commits { @stack.github_commits }
16
+
17
+ @stack.transaction do
18
+ shared_parent.try!(:detach_children!)
19
+ new_commits.each do |gh_commit|
20
+ @stack.commits.create_from_github!(gh_commit)
21
+ end
22
+ end
23
+ end
24
+ CacheDeploySpecJob.perform_later(@stack)
25
+ end
26
+
27
+ def fetch_missing_commits(&block)
28
+ commits = []
29
+ iterator = Shipit::FirstParentCommitsIterator.new(&block)
30
+ iterator.each_with_index do |commit, index|
31
+ break if index >= MAX_FETCHED_COMMITS
32
+
33
+ if shared_parent = lookup_commit(commit.sha)
34
+ return commits, shared_parent
35
+ end
36
+ commits.unshift(commit)
37
+ end
38
+ return commits, nil
39
+ end
40
+
41
+ protected
42
+
43
+ def handle_github_errors
44
+ yield
45
+ rescue Octokit::NotFound
46
+ @stack.mark_as_inaccessible!
47
+ else
48
+ @stack.mark_as_accessible!
49
+ end
50
+
51
+ def lookup_commit(sha)
52
+ @stack.commits.find_by_sha(sha)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,7 @@
1
+ module Shipit
2
+ class PerformCommitChecksJob < BackgroundJob
3
+ def perform(commit:)
4
+ commit.checks.run
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,57 @@
1
+ module Shipit
2
+ class PerformTaskJob < BackgroundJob
3
+ queue_as :deploys
4
+
5
+ def perform(task)
6
+ @task = task
7
+ @commands = Commands.for(@task)
8
+ unless @task.pending?
9
+ logger.error("Task ##{@task.id} already in `#{@task.status}` state. Aborting.")
10
+ return
11
+ end
12
+ run
13
+ ensure
14
+ @task.clear_working_directory
15
+ end
16
+
17
+ def run
18
+ @task.run!
19
+ checkout_repository
20
+ perform_task
21
+ @task.complete!
22
+ rescue Command::Error => error
23
+ @task.report_failure!(error)
24
+ rescue StandardError => error
25
+ @task.report_error!(error)
26
+ end
27
+
28
+ def perform_task
29
+ Bundler.with_clean_env do
30
+ capture_all @commands.install_dependencies
31
+ capture_all @commands.perform
32
+ end
33
+ end
34
+
35
+ def checkout_repository
36
+ @task.acquire_git_cache_lock do
37
+ capture @commands.fetch
38
+ capture @commands.clone
39
+ end
40
+ capture @commands.checkout(@task.until_commit)
41
+ end
42
+
43
+ def capture_all(commands)
44
+ commands.map { |c| capture(c) }
45
+ end
46
+
47
+ def capture(command)
48
+ command.start
49
+ @task.write("$ #{command}\npid: #{command.pid}\n")
50
+ @task.pid = command.pid
51
+ command.stream! do |line|
52
+ @task.write(line)
53
+ end
54
+ @task.write("\n")
55
+ end
56
+ end
57
+ end