shipit-engine 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -2
  3. data/app/assets/stylesheets/_pages/_deploy.scss +3 -2
  4. data/app/controllers/shipit/api/base_controller.rb +5 -0
  5. data/app/controllers/shipit/api/deploys_controller.rb +2 -1
  6. data/app/controllers/shipit/api/tasks_controller.rb +4 -1
  7. data/app/controllers/shipit/deploys_controller.rb +1 -1
  8. data/app/controllers/shipit/github_authentication_controller.rb +4 -2
  9. data/app/controllers/shipit/rollbacks_controller.rb +1 -1
  10. data/app/controllers/shipit/tasks_controller.rb +14 -2
  11. data/app/helpers/shipit/github_url_helper.rb +4 -2
  12. data/app/helpers/shipit/stacks_helper.rb +3 -3
  13. data/app/jobs/shipit/continuous_delivery_job.rb +12 -0
  14. data/app/jobs/shipit/create_on_github_job.rb +11 -0
  15. data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -1
  16. data/app/models/shipit/anonymous_user.rb +4 -0
  17. data/app/models/shipit/commit.rb +8 -10
  18. data/app/models/shipit/commit_deployment.rb +56 -0
  19. data/app/models/shipit/commit_deployment_status.rb +57 -0
  20. data/app/models/shipit/deploy.rb +32 -6
  21. data/app/models/shipit/deploy_spec.rb +8 -0
  22. data/app/models/shipit/deploy_spec/rubygems_discovery.rb +1 -1
  23. data/app/models/shipit/rollback.rb +10 -0
  24. data/app/models/shipit/stack.rb +30 -12
  25. data/app/models/shipit/status_group.rb +1 -1
  26. data/app/models/shipit/task.rb +1 -0
  27. data/app/models/shipit/task_definition.rb +20 -1
  28. data/app/models/shipit/user.rb +10 -2
  29. data/app/models/shipit/variable_definition.rb +2 -4
  30. data/app/serializers/shipit/commit_serializer.rb +19 -1
  31. data/app/serializers/shipit/deploy_serializer.rb +7 -1
  32. data/app/serializers/shipit/short_commit_serializer.rb +1 -1
  33. data/app/serializers/shipit/task_serializer.rb +17 -1
  34. data/app/views/shipit/_variables.html.erb +15 -0
  35. data/app/views/shipit/deploys/_concurrent_deploy_warning.html.erb +1 -1
  36. data/app/views/shipit/deploys/_deploy.html.erb +2 -2
  37. data/app/views/shipit/deploys/new.html.erb +3 -17
  38. data/app/views/shipit/deploys/rollback.html.erb +3 -17
  39. data/app/views/shipit/tasks/new.html.erb +12 -4
  40. data/config/locales/en.yml +11 -0
  41. data/db/migrate/20160210183823_add_allow_concurrency_to_tasks.rb +5 -0
  42. data/db/migrate/20160303163611_create_shipit_commit_deployments.rb +14 -0
  43. data/db/migrate/20160303170913_create_shipit_commit_deployment_statuses.rb +12 -0
  44. data/db/migrate/20160303203940_add_encrypted_token_to_users.rb +6 -0
  45. data/lib/shipit.rb +7 -1
  46. data/lib/shipit/engine.rb +3 -1
  47. data/lib/shipit/environment_variables.rb +34 -0
  48. data/lib/shipit/simple_message_verifier.rb +0 -1
  49. data/lib/shipit/task_commands.rb +1 -0
  50. data/lib/shipit/version.rb +1 -1
  51. data/test/controllers/api/deploys_controller_test.rb +15 -0
  52. data/test/controllers/api/tasks_controller_test.rb +15 -0
  53. data/test/controllers/github_authentication_controller_test.rb +23 -5
  54. data/test/controllers/tasks_controller_test.rb +27 -2
  55. data/test/controllers/webhooks_controller_test.rb +8 -2
  56. data/test/dummy/config/database.mysql.yml +1 -1
  57. data/test/dummy/config/secrets.example.yml +2 -2
  58. data/test/dummy/config/secrets.yml +2 -2
  59. data/test/dummy/data/stacks/byroot/junk/production/git/bar.txt +1 -0
  60. data/test/dummy/data/stacks/byroot/junk/production/git/dkfdsf +0 -0
  61. data/test/dummy/data/stacks/byroot/junk/production/git/dskjfsd +0 -0
  62. data/test/dummy/data/stacks/byroot/junk/production/git/dslkjfjsdf +0 -0
  63. data/test/dummy/data/stacks/byroot/junk/production/git/plopfizz +0 -0
  64. data/test/dummy/data/stacks/byroot/junk/production/git/sd +0 -0
  65. data/test/dummy/data/stacks/byroot/junk/production/git/sdkfjsdf +1 -0
  66. data/test/dummy/data/stacks/byroot/junk/production/git/sdlfjsdfdsfj +0 -0
  67. data/test/dummy/data/stacks/byroot/junk/production/git/sdlkfjsdlkfjsdlkfjdsfsdfksdfjsldkfjsdlkfjsdf +0 -0
  68. data/test/dummy/data/stacks/byroot/junk/production/git/shipit.yml +27 -0
  69. data/test/dummy/data/stacks/byroot/junk/production/git/toto.txt +2 -0
  70. data/test/dummy/db/development.sqlite3 +0 -0
  71. data/test/dummy/db/schema.rb +35 -7
  72. data/test/dummy/db/seeds.rb +3 -0
  73. data/test/dummy/db/test.sqlite3 +0 -0
  74. data/test/fixtures/shipit/commit_deployment_statuses.yml +19 -0
  75. data/test/fixtures/shipit/commit_deployments.yml +37 -0
  76. data/test/fixtures/shipit/commits.yml +1 -1
  77. data/test/fixtures/shipit/stacks.yml +12 -0
  78. data/test/fixtures/shipit/tasks.yml +4 -0
  79. data/test/fixtures/shipit/users.yml +2 -0
  80. data/test/jobs/fetch_deployed_revision_job_test.rb +3 -3
  81. data/test/models/commit_deployment_status_test.rb +27 -0
  82. data/test/models/commit_deployment_test.rb +37 -0
  83. data/test/models/commits_test.rb +7 -4
  84. data/test/models/deploys_test.rb +17 -1
  85. data/test/models/stacks_test.rb +13 -13
  86. data/test/models/task_definitions_test.rb +10 -0
  87. data/test/models/team_test.rb +8 -2
  88. data/test/models/users_test.rb +20 -2
  89. data/test/unit/deploy_spec_test.rb +29 -0
  90. data/test/unit/environment_variables_test.rb +36 -0
  91. data/test/unit/github_url_helper_test.rb +0 -8
  92. metadata +76 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13126d19eca4966f56856152cf632751bf1ba9d1
4
- data.tar.gz: 665a8bce4eb15e193e55b0da971a5840b7888bf6
3
+ metadata.gz: d3b3153e7b24f260f276933b246bca9d9bc2ebdd
4
+ data.tar.gz: 93ca93e3b0d8347a453979039c8cb16159ed044c
5
5
  SHA512:
6
- metadata.gz: 87cf3290c48593691fec2c278607cc1783206af426ca3dbefcab269b639614d98e5e8632cd1bc4fa27842f70615886f9b7c3914191d99dfc8168d43ab61ffcae
7
- data.tar.gz: 12077a22444887bb58eb55faed2b395e257d97f2a762fc64164ef216b61921c6606d8261de6f202192324b17e461e4b3c9f008d4278503c7631a41513a309ce2
6
+ metadata.gz: 7adfee4675b580ed2eba9e0f5057ba4647d51c9ce2b604ccfb598afbdbd9d8601841689e746de78d879975994d3b54eab450d8f0e11400774272702c9d6b399e
7
+ data.tar.gz: 1cb49f0e1c633f95cf293b9df55314bc6f800920b59308cbcebb58aeaa56d236877762d74410b8f1088d85d651db8b0eb59b3b26a4750c2f3e5c2eb13d2896f9
data/README.md CHANGED
@@ -125,6 +125,10 @@ The settings in the `shipit.yml` file relate to the different things you can do
125
125
 
126
126
  All the settings in `shipit.yml` are optional. Most applications can be deployed from Shipit without any configuration.
127
127
 
128
+ Aslo, if your repository is deployed different ways depending on the environment, you can have alternative `shipit.yml` by including the environment name.
129
+
130
+ For example for a stack like: `my-org/my-repo/staging`, `shipit.staging.yml` will have priority over `shipit.yml`.
131
+
128
132
  * * *
129
133
 
130
134
  <h3 id="installing-dependencies">Installing dependencies</h3>
@@ -183,6 +187,22 @@ deploy:
183
187
  ```
184
188
  <br>
185
189
 
190
+ You can also accept custom environment variables defined by the user that trigger the deploy:
191
+
192
+ **<code>deploy.variables</code>** contains an array of variable definitions.
193
+
194
+ For example:
195
+
196
+ ```yaml
197
+ deploy:
198
+ variables:
199
+ -
200
+ name: RUN_MIGRATIONS
201
+ title: Run database migrations on deploy
202
+ default: 1
203
+ ```
204
+ <br>
205
+
186
206
  **<code>rollback.override</code>** contains an array of the shell commands required to rollback the application to a previous state. Shipit will try to infer it from the repository structure, but you can change the default inference. This key defaults to disabled unless Capistrano is detected.
187
207
 
188
208
  For example:
@@ -255,6 +275,33 @@ tasks:
255
275
  - ssh deploy@myserver.example.com 'touch myapp/restart.txt'
256
276
  ```
257
277
 
278
+ By default custom tasks are not allowed to be triggered while a deploy is running. But if it's safe for that specific task you can change that behavior with the `allow_concurrency` attribute:
279
+
280
+ ```yml
281
+ tasks:
282
+ flush_cache:
283
+ action: "Flush Cache"
284
+ steps:
285
+ - ssh deploy@myserver.example.com 'myapp/flush_cache.sh'
286
+ allow_concurrency: true
287
+ ```
288
+
289
+ Tasks like deploys can prompt for user defined environment variables:
290
+
291
+ ```yml
292
+ tasks:
293
+ restart:
294
+ action: "Restart Application"
295
+ description: "Sometimes needed if you the application to restart but don't want to ship any new code."
296
+ steps:
297
+ - ssh deploy@myserver.example.com 'touch myapp/restart.txt'
298
+ variables:
299
+ -
300
+ name: FORCE
301
+ title: Restart server without waiting for in-flight requests to complete (Dangerous).
302
+ default: 0
303
+ ```
304
+
258
305
  <h3 id="review-process">Review process</h3>
259
306
 
260
307
  You can display review elements, such as monitoring data or a pre-deployment checklist, on the deployment page in Shipit:
@@ -267,7 +314,7 @@ For example:
267
314
  review:
268
315
  checklist:
269
316
  - >
270
- Do you know if it is safe to revert the code being shipped? What happens if we need to undo this deploy?
317
+ Do you know if it is safe to revert the code being shipped? What happens if we need to undo this deploy?
271
318
  - Has the Docs team been notified of any major changes to the app?
272
319
  - Is the app stable right now?
273
320
  ```
@@ -381,7 +428,8 @@ Your deploy scripts have access to the following environment variables:
381
428
  * `SHIPIT_LINK`: URL to the task output, usefull to broadcast it in an IRC channel
382
429
  * `USER`: Full name of the user that triggered the deploy/task
383
430
  * `EMAIL`: Email of the user that triggered the deploy/task (if available)
384
- * `ENVIRONMENT`: The stack environment (e.g production / staging)
431
+ * `ENVIRONMENT`: The stack environment (e.g `production` / `staging`)
432
+ * `BRANCH`: The stack branch (e.g `master`)
385
433
  * `LAST_DEPLOYED_SHA`: The git SHA of the last deployed commit
386
434
  * All the content of the `secrets.yml` `env` key
387
435
  * All the content of the `shipit.yml` `machine.environment` key
@@ -9,11 +9,12 @@
9
9
  display: flex;
10
10
  }
11
11
 
12
- .environment-variables {
12
+ .variables-header {
13
13
  margin: 1rem 0;
14
+ padding-top: 1rem;
14
15
  }
15
16
 
16
- .environment-variable {
17
+ .variables-fields {
17
18
  input {
18
19
  display: inline-block;
19
20
  width: inherit;
@@ -7,6 +7,7 @@ module Shipit
7
7
  include Paginable
8
8
 
9
9
  rescue_from ApiClient::InsufficientPermission, with: :insufficient_permission
10
+ rescue_from EnvironmentVariables::NotPermitted, with: :validation_error
10
11
  rescue_from TaskDefinition::NotFound, with: :not_found
11
12
 
12
13
  class << self
@@ -60,6 +61,10 @@ module Shipit
60
61
  render status: :forbidden, json: {message: error.message}
61
62
  end
62
63
 
64
+ def validation_error(error)
65
+ render status: :unprocessable_entity, json: {message: error.message}
66
+ end
67
+
63
68
  def not_found(_error)
64
69
  render status: :not_found, json: {status: '404', error: 'Not Found'}
65
70
  end
@@ -6,11 +6,12 @@ module Shipit
6
6
  params do
7
7
  requires :sha, String, length: {in: 6..40}
8
8
  accepts :force, Boolean, default: false
9
+ accepts :env, Hash, default: {}
9
10
  end
10
11
  def create
11
12
  commit = stack.commits.by_sha(params.sha) || param_error!(:sha, 'Unknown revision')
12
13
  param_error!(:force, "Can't deploy a locked stack") if !params.force && stack.locked?
13
- render_resource stack.trigger_deploy(commit, current_user), status: :accepted
14
+ render_resource stack.trigger_deploy(commit, current_user, env: params.env), status: :accepted
14
15
  end
15
16
  end
16
17
  end
@@ -12,8 +12,11 @@ module Shipit
12
12
  render_resource stack.tasks.find(params[:id])
13
13
  end
14
14
 
15
+ params do
16
+ accepts :env, Hash, default: {}
17
+ end
15
18
  def trigger
16
- render_resource stack.trigger_task(params[:task_name], current_user), status: :accepted
19
+ render_resource stack.trigger_task(params[:task_name], current_user, env: params.env), status: :accepted
17
20
  end
18
21
  end
19
22
  end
@@ -16,7 +16,7 @@ module Shipit
16
16
  end
17
17
 
18
18
  def create
19
- return redirect_to new_stack_deploy_path(@stack, sha: @until_commit.sha) if !params[:force] && @stack.deploying?
19
+ return redirect_to new_stack_deploy_path(@stack, sha: @until_commit.sha) if !params[:force] && @stack.active_task?
20
20
 
21
21
  @deploy = @stack.trigger_deploy(@until_commit, current_user, env: deploy_params[:env])
22
22
  respond_with(@deploy.stack, @deploy)
@@ -9,6 +9,7 @@ module Shipit
9
9
  return render 'failed', layout: false if auth.blank?
10
10
 
11
11
  session[:user_id] = sign_in_github(auth)
12
+
12
13
  redirect_to return_url
13
14
  end
14
15
 
@@ -20,8 +21,9 @@ module Shipit
20
21
  private
21
22
 
22
23
  def sign_in_github(auth)
23
- user = Shipit.github_api.user(auth[:info][:nickname])
24
- User.find_or_create_from_github(user).id
24
+ user = User.find_or_create_from_github(auth.extra.raw_info)
25
+ user.update(github_access_token: auth.credentials.token)
26
+ user.id
25
27
  end
26
28
  end
27
29
  end
@@ -4,7 +4,7 @@ module Shipit
4
4
  before_action :load_deploy
5
5
 
6
6
  def create
7
- return redirect_to rollback_stack_deploy_path(@stack, @deploy) if !params[:force] && @stack.deploying?
7
+ return redirect_to rollback_stack_deploy_path(@stack, @deploy) if !params[:force] && @stack.active_task?
8
8
  @rollback = @deploy.trigger_rollback(current_user, env: rollback_params[:env])
9
9
  redirect_to stack_deploy_path(@stack, @rollback)
10
10
  end
@@ -22,8 +22,14 @@ module Shipit
22
22
  end
23
23
 
24
24
  def create
25
- @task = stack.trigger_task(params[:definition_id], current_user)
26
- redirect_to [stack, @task]
25
+ @definition = stack.find_task_definition(params[:definition_id])
26
+
27
+ if @definition.allow_concurrency? || params[:force] || !@stack.active_task?
28
+ @task = stack.trigger_task(params[:definition_id], current_user, env: task_params[:env])
29
+ redirect_to [stack, @task]
30
+ else
31
+ redirect_to new_stack_tasks_path(stack, @definition)
32
+ end
27
33
  end
28
34
 
29
35
  def abort
@@ -44,5 +50,11 @@ module Shipit
44
50
  def stack
45
51
  @stack ||= Stack.from_param!(params[:stack_id])
46
52
  end
53
+
54
+ def task_params
55
+ return {} unless params[:task]
56
+ @definition = stack.find_task_definition(params[:definition_id])
57
+ @task_params ||= params.require(:task).permit(env: @definition.variables.map(&:name))
58
+ end
47
59
  end
48
60
  end
@@ -1,5 +1,7 @@
1
1
  module Shipit
2
2
  module GithubUrlHelper
3
+ private
4
+
3
5
  def github_avatar(user, options = {})
4
6
  uri = user.avatar_uri
5
7
  attributes = options.slice(:class).merge(alt: user.try!(:name))
@@ -35,8 +37,8 @@ module Shipit
35
37
  github_repo_url(commit.stack.repo_owner, commit.stack.repo_name, 'commit', commit.sha)
36
38
  end
37
39
 
38
- def github_diff_url(owner, repo, from_sha, to_sha)
39
- github_repo_url(owner, repo, 'compare', "#{from_sha}...#{to_sha}")
40
+ def github_pull_request_url(commit)
41
+ github_repo_url(commit.stack.repo_owner, commit.stack.repo_name, 'pull', commit.pull_request_number)
40
42
  end
41
43
 
42
44
  def link_to_github_deploy(deploy)
@@ -12,7 +12,7 @@ module Shipit
12
12
 
13
13
  caption = 'Redeploy'
14
14
  caption = 'Locked' if commit.stack.locked? && !ignore_lock?
15
- caption = 'Deploy in progress...' if commit.stack.deploying?
15
+ caption = 'Deploy in progress...' if commit.stack.active_task?
16
16
 
17
17
  link_to(caption, url, class: classes)
18
18
  end
@@ -53,7 +53,7 @@ module Shipit
53
53
  end
54
54
 
55
55
  def pull_request_link(commit)
56
- link_to("##{commit.pull_request_id}", commit.pull_request_url, target: '_blank', class: 'number')
56
+ link_to("##{commit.pull_request_number}", commit.pull_request_url, target: '_blank', class: 'number')
57
57
  end
58
58
 
59
59
  def render_raw_commit_id_link(commit)
@@ -70,7 +70,7 @@ module Shipit
70
70
  state = commit.status.state
71
71
  state = 'locked' if commit.stack.locked? && !ignore_lock?
72
72
  if commit.deployable?
73
- state = commit.stack.deploying? ? 'deploying' : 'enabled'
73
+ state = commit.stack.active_task? ? 'deploying' : 'enabled'
74
74
  end
75
75
  t("deploy_button.caption.#{state}")
76
76
  end
@@ -0,0 +1,12 @@
1
+ module Shipit
2
+ class ContinuousDeliveryJob < BackgroundJob
3
+ include BackgroundJob::Unique
4
+
5
+ queue_as :default
6
+
7
+ def perform(stack)
8
+ return unless stack.continuous_deployment?
9
+ stack.trigger_continuous_deploy
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module Shipit
2
+ class CreateOnGithubJob < BackgroundJob
3
+ include BackgroundJob::Unique
4
+
5
+ queue_as :default
6
+
7
+ def perform(record)
8
+ record.create_on_github!
9
+ end
10
+ end
11
+ end
@@ -3,7 +3,7 @@ module Shipit
3
3
  queue_as :default
4
4
 
5
5
  def perform(stack)
6
- return if stack.deploying?
6
+ return if stack.active_task?
7
7
 
8
8
  commands = StackCommands.new(stack)
9
9
 
@@ -39,5 +39,9 @@ module Shipit
39
39
  def read_attribute_for_serialization(attr)
40
40
  public_send(attr)
41
41
  end
42
+
43
+ def github_api
44
+ Shipit.github_api
45
+ end
42
46
  end
43
47
  end
@@ -117,10 +117,10 @@ module Shipit
117
117
  end
118
118
 
119
119
  def pull_request_url
120
- parsed && Shipit.github_url("/#{stack.repo_owner}/#{stack.repo_name}/pull/#{pull_request_id}")
120
+ parsed && Shipit.github_url("/#{stack.repo_owner}/#{stack.repo_name}/pull/#{pull_request_number}")
121
121
  end
122
122
 
123
- def pull_request_id
123
+ def pull_request_number
124
124
  parsed && parsed['pr_id'].to_i
125
125
  end
126
126
 
@@ -141,10 +141,8 @@ module Shipit
141
141
  end
142
142
 
143
143
  def schedule_continuous_delivery
144
- return unless state == 'success' && stack.continuous_deployment?
145
- return unless stack.deployable?
146
- return if already_deployed?
147
- stack.trigger_deploy(self, committer)
144
+ return unless state == 'success' && stack.continuous_deployment? && stack.deployable?
145
+ ContinuousDeliveryJob.perform_later(stack)
148
146
  end
149
147
 
150
148
  def github_commit
@@ -188,6 +186,10 @@ module Shipit
188
186
  non_success_statuses.reject(&:pending?).first || non_success_statuses.first || UnknownStatus.new(self)
189
187
  end
190
188
 
189
+ def deployed?
190
+ stack.last_deployed_commit.id >= id
191
+ end
192
+
191
193
  private
192
194
 
193
195
  def missing_statuses
@@ -198,10 +200,6 @@ module Shipit
198
200
  stack.touch
199
201
  end
200
202
 
201
- def already_deployed?
202
- stack.last_deployed_commit.id >= id
203
- end
204
-
205
203
  def simple_state(status)
206
204
  status.state == 'error' ? 'failure' : status.state
207
205
  end
@@ -0,0 +1,56 @@
1
+ module Shipit
2
+ class CommitDeployment < ActiveRecord::Base
3
+ belongs_to :commit
4
+ belongs_to :task
5
+ has_many :statuses, class_name: 'CommitDeploymentStatus'
6
+
7
+ after_commit :schedule_create_on_github, on: :create
8
+
9
+ delegate :stack, :author, to: :task
10
+
11
+ def create_on_github!
12
+ return unless commit.pull_request?
13
+
14
+ create_deployment_on_github!
15
+ statuses.order(id: :asc).each(&:create_on_github!)
16
+ end
17
+
18
+ def create_deployment_on_github!
19
+ return if github_id?
20
+
21
+ response = begin
22
+ create_deployment_on_github(author.github_api)
23
+ rescue Octokit::NotFound, Octokit::Forbidden
24
+ raise if Shipit.github_api == author.github_api
25
+ # If the deploy author didn't gave us the permission to create the deployment we falback the the main shipit
26
+ # user.
27
+ #
28
+ # Octokit currently raise NotFound, but I'm convinced it should be Forbidden if the user can see the repository.
29
+ # So to be future proof I catch boths.
30
+ create_deployment_on_github(Shipit.github_api)
31
+ end
32
+ update!(github_id: response.id, api_url: response.url)
33
+ end
34
+
35
+ def pull_request_head
36
+ pull_request = Shipit.github_api.pull_request(stack.github_repo_name, commit.pull_request_number)
37
+ pull_request.head.sha
38
+ end
39
+
40
+ def schedule_create_on_github
41
+ CreateOnGithubJob.perform_later(self)
42
+ end
43
+
44
+ private
45
+
46
+ def create_deployment_on_github(client)
47
+ client.create_deployment(
48
+ stack.github_repo_name,
49
+ pull_request_head,
50
+ auto_merge: false,
51
+ description: "Via Shipit",
52
+ environment: stack.environment,
53
+ )
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,57 @@
1
+ module Shipit
2
+ class CommitDeploymentStatus < ActiveRecord::Base
3
+ belongs_to :commit_deployment
4
+
5
+ after_commit :schedule_create_on_github, on: :create
6
+
7
+ delegate :stack, :task, :author, to: :commit_deployment
8
+
9
+ def create_on_github!
10
+ return if github_id?
11
+ response = begin
12
+ create_status_on_github(author.github_api)
13
+ rescue Octokit::NotFound, Octokit::Forbidden
14
+ raise if Shipit.github_api == author.github_api
15
+ # If the deploy author didn't gave us the permission to create the deployment we falback the the main shipit
16
+ # user.
17
+ #
18
+ # Octokit currently raise NotFound, but I'm convinced it should be Forbidden if the user can see the repository.
19
+ # So to be future proof I catch boths.
20
+ create_status_on_github(Shipit.github_api)
21
+ end
22
+ update!(github_id: response.id, api_url: response.url)
23
+ end
24
+
25
+ def description
26
+ I18n.t(
27
+ "deployment_description.#{task_type}.#{status}",
28
+ sha: task.until_commit.sha,
29
+ author: task.author.login,
30
+ stack: stack.to_param,
31
+ )
32
+ end
33
+
34
+ def task_type
35
+ task.class.name.demodulize.underscore
36
+ end
37
+
38
+ def schedule_create_on_github
39
+ CreateOnGithubJob.perform_later(commit_deployment)
40
+ end
41
+
42
+ private
43
+
44
+ def create_status_on_github(client)
45
+ client.create_deployment_status(
46
+ commit_deployment.api_url,
47
+ status,
48
+ target_url: url_helpers.stack_deploy_url(stack, task),
49
+ description: description,
50
+ )
51
+ end
52
+
53
+ def url_helpers
54
+ Engine.routes.url_helpers
55
+ end
56
+ end
57
+ end