shipit-engine 0.11.0 → 0.12.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -37
  3. data/app/assets/javascripts/task/tty.js.coffee +40 -22
  4. data/app/assets/stylesheets/_pages/_deploy.scss +1 -0
  5. data/app/controllers/shipit/api/locks_controller.rb +3 -3
  6. data/app/controllers/shipit/api/stacks_controller.rb +14 -1
  7. data/app/controllers/shipit/commit_checks_controller.rb +9 -2
  8. data/app/controllers/shipit/shipit_controller.rb +1 -1
  9. data/app/controllers/shipit/stacks_controller.rb +11 -5
  10. data/app/controllers/shipit/status_controller.rb +1 -1
  11. data/app/controllers/shipit/webhooks_controller.rb +15 -5
  12. data/app/helpers/shipit/deploys_helper.rb +1 -1
  13. data/app/helpers/shipit/shipit_helper.rb +2 -0
  14. data/app/jobs/shipit/perform_commit_checks_job.rb +2 -0
  15. data/app/jobs/shipit/perform_task_job.rb +18 -8
  16. data/app/models/shipit/commit.rb +22 -12
  17. data/app/models/shipit/commit_checks.rb +20 -53
  18. data/app/models/shipit/deploy.rb +1 -1
  19. data/app/models/shipit/ephemeral_commit_checks.rb +76 -0
  20. data/app/models/shipit/stack.rb +40 -10
  21. data/app/models/shipit/status.rb +14 -8
  22. data/app/models/shipit/status_group.rb +1 -1
  23. data/app/models/shipit/task.rb +2 -0
  24. data/app/models/shipit/unknown_status.rb +4 -0
  25. data/app/models/shipit/user.rb +9 -1
  26. data/app/serializers/shipit/stack_serializer.rb +6 -1
  27. data/app/views/shipit/commit_checks/_checks.html.erb +13 -0
  28. data/app/views/shipit/commit_checks/show.html.erb +5 -0
  29. data/app/views/shipit/stacks/_header.html.erb +1 -1
  30. data/app/views/shipit/stacks/show.html.erb +15 -0
  31. data/config/routes.rb +2 -1
  32. data/db/migrate/20140226233935_create_baseline.rb +10 -10
  33. data/db/migrate/20160802092812_add_continuous_delivery_delayed_since_to_stacks.rb +5 -0
  34. data/db/migrate/20160822131405_add_locked_since_to_stacks.rb +5 -0
  35. data/lib/shipit.rb +4 -0
  36. data/lib/shipit/command.rb +1 -1
  37. data/lib/shipit/commands.rb +10 -7
  38. data/lib/shipit/csv_serializer.rb +1 -1
  39. data/lib/shipit/stack_commands.rb +17 -5
  40. data/lib/shipit/task_commands.rb +2 -2
  41. data/lib/shipit/version.rb +1 -1
  42. data/lib/snippets/push-to-heroku +20 -16
  43. data/test/controllers/api/deploys_controller_test.rb +8 -8
  44. data/test/controllers/api/hooks_controller_test.rb +11 -9
  45. data/test/controllers/api/locks_controller_test.rb +16 -6
  46. data/test/controllers/api/outputs_controller_test.rb +1 -1
  47. data/test/controllers/api/stacks_controller_test.rb +48 -3
  48. data/test/controllers/api/tasks_controller_test.rb +6 -6
  49. data/test/controllers/commit_checks_controller_test.rb +3 -3
  50. data/test/controllers/deploys_controller_test.rb +13 -13
  51. data/test/controllers/rollbacks_controller_test.rb +7 -7
  52. data/test/controllers/stacks_controller_test.rb +36 -29
  53. data/test/controllers/tasks_controller_test.rb +14 -14
  54. data/test/controllers/webhooks_controller_test.rb +16 -25
  55. data/test/dummy/config/application.rb +0 -3
  56. data/test/dummy/config/environments/test.rb +2 -2
  57. data/test/dummy/data/stacks/byroot/junk/production/git/bar.txt +2 -0
  58. data/test/dummy/data/stacks/byroot/junk/production/git/bin/slow +7 -0
  59. data/test/dummy/data/stacks/byroot/junk/production/git/bin/timeout +10 -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 +21 -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 +15 -13
  72. data/test/dummy/db/test.sqlite3 +0 -0
  73. data/test/fixtures/shipit/commit_deployments.yml +8 -8
  74. data/test/fixtures/shipit/output_chunks.yml +12 -12
  75. data/test/fixtures/shipit/tasks.yml +9 -1
  76. data/test/fixtures/shipit/users.yml +9 -2
  77. data/test/jobs/perform_task_job_test.rb +14 -11
  78. data/test/models/commits_test.rb +33 -14
  79. data/test/models/stacks_test.rb +78 -4
  80. data/test/models/users_test.rb +16 -0
  81. data/test/unit/commands_test.rb +4 -0
  82. data/test/unit/deploy_commands_test.rb +1 -1
  83. metadata +133 -34
  84. data/app/jobs/shipit/git_mirror_update_job.rb +0 -14
  85. data/app/views/shipit/deploys/_checks.html.erb +0 -11
@@ -13,18 +13,24 @@ module Shipit
13
13
 
14
14
  delegate :broadcast_update, to: :commit
15
15
 
16
- def self.replicate_from_github!(github_status)
17
- find_or_create_by!(
18
- state: github_status.state,
19
- description: github_status.description,
20
- target_url: github_status.rels.try(:[], :target).try(:href),
21
- context: github_status.context,
22
- created_at: github_status.created_at,
23
- )
16
+ class << self
17
+ def replicate_from_github!(github_status)
18
+ find_or_create_by!(
19
+ state: github_status.state,
20
+ description: github_status.description,
21
+ target_url: github_status.target_url,
22
+ context: github_status.context,
23
+ created_at: github_status.created_at,
24
+ )
25
+ end
24
26
  end
25
27
 
26
28
  delegate :stack, to: :commit
27
29
 
30
+ def unknown?
31
+ false
32
+ end
33
+
28
34
  def ignored?
29
35
  stack.soft_failing_statuses.include?(context)
30
36
  end
@@ -9,7 +9,7 @@ module Shipit
9
9
  @statuses = visible_statuses
10
10
  end
11
11
 
12
- delegate :pending?, :success?, :error?, :failure?, :state, to: :significant_status
12
+ delegate :pending?, :success?, :error?, :failure?, :unknown?, :state, to: :significant_status
13
13
 
14
14
  def description
15
15
  "#{success_count} / #{statuses.count} checks OK"
@@ -3,6 +3,7 @@ module Shipit
3
3
  PRESENCE_CHECK_TIMEOUT = 15
4
4
  ACTIVE_STATUSES = %w(pending running aborting).freeze
5
5
  COMPLETED_STATUSES = %w(success error failed flapping aborted).freeze
6
+ UNSUCCESSFUL_STATUSES = %w(error failed aborted flapping).freeze
6
7
 
7
8
  attr_accessor :pid
8
9
 
@@ -22,6 +23,7 @@ module Shipit
22
23
  scope :completed, -> { where(status: COMPLETED_STATUSES) }
23
24
  scope :active, -> { where(status: ACTIVE_STATUSES) }
24
25
  scope :exclusive, -> { where(allow_concurrency: false) }
26
+ scope :unsuccessful, -> { where(status: UNSUCCESSFUL_STATUSES) }
25
27
 
26
28
  scope :due_for_rollup, -> { completed.where(rolled_up: false).where('created_at <= ?', 1.hour.ago) }
27
29
 
@@ -5,6 +5,10 @@ module Shipit
5
5
  end
6
6
  alias_method :simple_state, :state
7
7
 
8
+ def unknown?
9
+ true
10
+ end
11
+
8
12
  def pending?
9
13
  false
10
14
  end
@@ -35,6 +35,14 @@ module Shipit
35
35
  end
36
36
  end
37
37
 
38
+ alias_method :original_github_access_token, :github_access_token
39
+ def github_access_token
40
+ original_github_access_token
41
+ rescue OpenSSL::Cipher::CipherError
42
+ update_columns(encrypted_github_access_token: nil, encrypted_github_access_token_iv: nil)
43
+ nil
44
+ end
45
+
38
46
  def github_api
39
47
  return Shipit.github_api unless github_access_token
40
48
 
@@ -55,7 +63,7 @@ module Shipit
55
63
 
56
64
  def stacks_contributed_to
57
65
  return [] unless id
58
- Commit.where('author_id = :id or committer_id = :id', id: id).uniq.pluck(:stack_id)
66
+ Commit.where('author_id = :id or committer_id = :id', id: id).distinct.pluck(:stack_id)
59
67
  end
60
68
 
61
69
  def refresh_from_github!
@@ -4,7 +4,8 @@ module Shipit
4
4
 
5
5
  has_one :lock_author
6
6
  attributes :id, :repo_owner, :repo_name, :environment, :html_url, :url, :tasks_url, :deploy_url, :deploy_spec,
7
- :undeployed_commits_count, :is_locked, :lock_reason, :continuous_deployment, :created_at, :updated_at
7
+ :undeployed_commits_count, :is_locked, :lock_reason, :continuous_deployment, :created_at,
8
+ :updated_at, :locked_since
8
9
 
9
10
  def url
10
11
  api_stack_url(object)
@@ -30,6 +31,10 @@ module Shipit
30
31
  object.locked?
31
32
  end
32
33
 
34
+ def include_locked_since?
35
+ object.locked?
36
+ end
37
+
33
38
  def deploy_spec
34
39
  object.cached_deploy_spec.cacheable.config
35
40
  end
@@ -0,0 +1,13 @@
1
+ <%= javascript_include_tag 'task' %>
2
+
3
+ <section>
4
+ <header class="section-header">
5
+ <h2>Checks</h2>
6
+ </header>
7
+
8
+ <%- url = stack_tail_commit_checks_path(commit.stack, sha: commit.sha, since: 0) -%>
9
+
10
+ <div class="task-output-container">
11
+ <pre class="commit-checks" data-status="<%= commit.checks.status %>"><code data-next-chunks-url="<%= url %>"></code></pre>
12
+ </div>
13
+ </section>
@@ -0,0 +1,5 @@
1
+ <%= render partial: 'shipit/stacks/header', locals: { stack: @stack } %>
2
+
3
+ <div class="wrapper">
4
+ <%= render_checks @commit %>
5
+ </div>
@@ -36,7 +36,7 @@
36
36
  </li>
37
37
  <% if stack.deploy_url.present? %>
38
38
  <li class="nav__list__item">
39
- <%= link_to 'View website', stack.deploy_url, :target => '_blank', :class => 'deploy-url' %>
39
+ <%= sanitize link_to 'View website', stack.deploy_url, :target => '_blank', :class => 'deploy-url' %>
40
40
  </li>
41
41
  <% end %>
42
42
  </ul>
@@ -49,6 +49,21 @@
49
49
  </div>
50
50
  <% end %>
51
51
 
52
+ <% if @stack.continuous_delivery_delayed? %>
53
+ <div class="banner">
54
+ <div class="banner__inner wrapper">
55
+ <div class="banner__content">
56
+ <h2 class="banner__title">Continuous Delivery Delayed!</h2>
57
+ <p class="banner__text">
58
+ Continuous Delivery for this stack is currently paused because
59
+ <%= link_to 'the pre-deploy checks failed', stack_commit_checks_path(@stack, sha: @stack.next_commit_to_deploy.sha) %>.
60
+ You can either wait for them to pass, or trigger a deploy manually.
61
+ </p>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ <% end %>
66
+
52
67
  <div class="wrapper" data-event-stream="<%= events_path(channels: ["stack.#{@stack.id}"]) %>">
53
68
 
54
69
  <section>
data/config/routes.rb CHANGED
@@ -24,7 +24,7 @@ Shipit::Engine.routes.draw do
24
24
  # API
25
25
  namespace :api do
26
26
  root to: 'base#index'
27
- resources :stacks, only: :index
27
+ resources :stacks, only: %i(index create)
28
28
  scope '/stacks/*id', id: stack_id_format, as: :stack do
29
29
  get '/' => 'stacks#show'
30
30
  end
@@ -62,6 +62,7 @@ Shipit::Engine.routes.draw do
62
62
  end
63
63
 
64
64
  scope '/*stack_id', stack_id: stack_id_format, as: :stack do
65
+ get '/commit/:sha/checks' => 'commit_checks#show', as: :commit_checks
65
66
  get '/commit/:sha/checks/tail' => 'commit_checks#tail', as: :tail_commit_checks, defaults: {format: :json}
66
67
 
67
68
  resources :rollbacks, only: %i(create)
@@ -49,13 +49,13 @@ class CreateBaseline < ActiveRecord::Migration
49
49
  create_table "github_hooks", force: :cascade do |t|
50
50
  t.integer "stack_id", limit: 4
51
51
  t.integer "github_id", limit: 4
52
- t.string "event", limit: 255
52
+ t.string "event", limit: 50
53
53
  t.datetime "created_at"
54
54
  t.datetime "updated_at"
55
55
  t.string "secret", limit: 255
56
56
  t.string "api_url", limit: 255
57
57
  t.string "type", limit: 255
58
- t.string "organization", limit: 255
58
+ t.string "organization", limit: 39
59
59
  end
60
60
 
61
61
  add_index "github_hooks", ["organization", "event"], name: "index_github_hooks_on_organization_and_event", unique: true, using: :btree
@@ -94,9 +94,9 @@ class CreateBaseline < ActiveRecord::Migration
94
94
  add_index "output_chunks", ["task_id"], name: "index_output_chunks_on_task_id", using: :btree
95
95
 
96
96
  create_table "stacks", force: :cascade do |t|
97
- t.string "repo_name", limit: 255, null: false
98
- t.string "repo_owner", limit: 255, null: false
99
- t.string "environment", limit: 255, default: "production", null: false
97
+ t.string "repo_name", limit: 100, null: false
98
+ t.string "repo_owner", limit: 39, null: false
99
+ t.string "environment", limit: 50, default: "production", null: false
100
100
  t.datetime "created_at"
101
101
  t.datetime "updated_at"
102
102
  t.string "branch", limit: 255, default: "master", null: false
@@ -127,12 +127,12 @@ class CreateBaseline < ActiveRecord::Migration
127
127
  t.integer "stack_id", limit: 4, null: false
128
128
  t.integer "since_commit_id", limit: 4, null: false
129
129
  t.integer "until_commit_id", limit: 4, null: false
130
- t.string "status", limit: 255, default: "pending", null: false
130
+ t.string "status", limit: 10, default: "pending", null: false
131
131
  t.datetime "created_at"
132
132
  t.datetime "updated_at"
133
133
  t.integer "user_id", limit: 4
134
134
  t.boolean "rolled_up", default: false, null: false
135
- t.string "type", limit: 255
135
+ t.string "type", limit: 20
136
136
  t.integer "parent_id", limit: 4
137
137
  t.integer "additions", limit: 4, default: 0
138
138
  t.integer "deletions", limit: 4, default: 0
@@ -148,9 +148,9 @@ class CreateBaseline < ActiveRecord::Migration
148
148
  create_table "teams", force: :cascade do |t|
149
149
  t.integer "github_id", limit: 4
150
150
  t.string "api_url", limit: 255
151
- t.string "slug", limit: 255
151
+ t.string "slug", limit: 50
152
152
  t.string "name", limit: 255
153
- t.string "organization", limit: 255
153
+ t.string "organization", limit: 39
154
154
  t.datetime "created_at", null: false
155
155
  t.datetime "updated_at", null: false
156
156
  end
@@ -161,7 +161,7 @@ class CreateBaseline < ActiveRecord::Migration
161
161
  t.integer "github_id", limit: 4
162
162
  t.string "name", limit: 255, null: false
163
163
  t.string "email", limit: 255
164
- t.string "login", limit: 255
164
+ t.string "login", limit: 39
165
165
  t.string "api_url", limit: 255
166
166
  t.datetime "created_at"
167
167
  t.datetime "updated_at"
@@ -0,0 +1,5 @@
1
+ class AddContinuousDeliveryDelayedSinceToStacks < ActiveRecord::Migration
2
+ def change
3
+ add_column :stacks, :continuous_delivery_delayed_since, :datetime, null: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddLockedSinceToStacks < ActiveRecord::Migration
2
+ def change
3
+ add_column :stacks, :locked_since, :datetime, null: true
4
+ end
5
+ end
data/lib/shipit.rb CHANGED
@@ -175,6 +175,10 @@ module Shipit
175
175
  {'SHIPIT' => '1'}.merge(secrets.env || {})
176
176
  end
177
177
 
178
+ def shell_paths
179
+ [Shipit::Engine.root.join('lib', 'snippets').to_s]
180
+ end
181
+
178
182
  def revision
179
183
  @revision ||= begin
180
184
  if revision_file.exist?
@@ -69,7 +69,7 @@ module Shipit
69
69
 
70
70
  def with_full_path
71
71
  old_path = ENV['PATH']
72
- ENV['PATH'] = "#{ENV['PATH']}:#{Shipit::Engine.root.join('lib', 'snippets')}"
72
+ ENV['PATH'] = "#{ENV['PATH']}:#{Shipit.shell_paths.join(':')}"
73
73
  yield
74
74
  ensure
75
75
  ENV['PATH'] = old_path
@@ -1,17 +1,20 @@
1
1
  module Shipit
2
2
  class Commands
3
- def self.for(model)
4
- "#{model.class.name}Commands".constantize.new(model)
5
- end
3
+ class << self
4
+ def for(model)
5
+ "#{model.class.name}Commands".constantize.new(model)
6
+ end
6
7
 
7
- def self.git_version
8
- @git_version ||= begin
9
- `git --version` =~ /([\d\.]+)/
8
+ def git_version
9
+ @git_version ||= parse_git_version(`git --version`)
10
+ end
11
+
12
+ def parse_git_version(raw_git_version)
13
+ raw_git_version =~ /(\d+\.\d+\.\d+)/
10
14
  raise 'git command not found' unless $1
11
15
  Gem::Version.new($1)
12
16
  end
13
17
  end
14
-
15
18
  delegate :git_version, to: :class
16
19
 
17
20
  def env
@@ -9,7 +9,7 @@ module Shipit
9
9
 
10
10
  def dump(array)
11
11
  return nil if array.blank?
12
- array.join(',')
12
+ Array.wrap(array).join(',')
13
13
  end
14
14
  end
15
15
  end
@@ -16,6 +16,15 @@ module Shipit
16
16
  end
17
17
  end
18
18
 
19
+ def fetched?(commit)
20
+ git_dir = File.join(@stack.git_path, '.git')
21
+ if Dir.exist?(git_dir)
22
+ git('rev-parse', '--quiet', '--verify', "#{commit.sha}^{commit}", env: env, chdir: @stack.git_path)
23
+ else
24
+ Command.new('test', '-d', git_dir, env: env, chdir: @stack.deploys_path)
25
+ end
26
+ end
27
+
19
28
  def fetch_deployed_revision
20
29
  with_temporary_working_directory do |dir|
21
30
  spec = DeploySpec::FileSystem.new(dir, @stack.environment)
@@ -33,14 +42,17 @@ module Shipit
33
42
  end
34
43
 
35
44
  def with_temporary_working_directory(commit: nil)
36
- @stack.acquire_git_cache_lock do
37
- fetch.run!
38
- git('checkout', '--force', "origin/#{@stack.branch}", env: env, chdir: @stack.git_path).run!
45
+ if commit
46
+ @stack.acquire_git_cache_lock do
47
+ fetch.run! unless fetched?(commit).tap(&:run).success?
48
+ end
39
49
  end
50
+
40
51
  Dir.mktmpdir do |dir|
41
52
  git('clone', @stack.git_path, @stack.repo_name, chdir: dir).run!
42
- git('checkout', commit.sha, chdir: dir) if commit
43
- yield Pathname.new(File.join(dir, @stack.repo_name))
53
+ git_dir = File.join(dir, @stack.repo_name)
54
+ git('checkout', commit.sha, chdir: git_dir).run! if commit
55
+ yield Pathname.new(git_dir)
44
56
  end
45
57
  end
46
58
 
@@ -1,6 +1,6 @@
1
1
  module Shipit
2
2
  class TaskCommands < Commands
3
- delegate :fetch, to: :stack_commands
3
+ delegate :fetch, :fetched?, to: :stack_commands
4
4
 
5
5
  def initialize(task)
6
6
  @task = task
@@ -32,7 +32,7 @@ module Shipit
32
32
  super.merge(
33
33
  'ENVIRONMENT' => @stack.environment,
34
34
  'BRANCH' => @stack.branch,
35
- 'USER' => "#{@task.author.login} (#{normalized_name}) via Shipit",
35
+ 'SHIPIT_USER' => "#{@task.author.login} (#{normalized_name}) via Shipit",
36
36
  'EMAIL' => @task.author.email,
37
37
  'BUNDLE_PATH' => Rails.root.join('data', 'bundler').to_s,
38
38
  'SHIPIT_LINK' => permalink,
@@ -1,3 +1,3 @@
1
1
  module Shipit
2
- VERSION = '0.11.0'.freeze
2
+ VERSION = '0.12.0'.freeze
3
3
  end
@@ -13,8 +13,9 @@ function yellow() {
13
13
  HEROKU_APP=$1
14
14
  HEROKU_RELEASES=`heroku releases --app $HEROKU_APP 2>&1`
15
15
  GIT_COMMAND=${GIT_COMMAND:="git push git@heroku.com:$HEROKU_APP.git $SHA:master $GIT_FLAGS"}
16
+ POST_MIGRATION_DEPLOY=${POST_MIGRATION_DEPLOY:="true"}
16
17
 
17
- if [ -z $HEROKU_APP ]; then
18
+ if [[ -z "${HEROKU_APP}" ]]; then
18
19
  red "Usage: $0 <app-name>"
19
20
  red "Supported environment variables:"
20
21
  red " - GIT_COMMAND: override the entire 'git push' command."
@@ -24,49 +25,52 @@ fi
24
25
 
25
26
  echo "$HEROKU_RELEASES" | head -n2 | tail -n1 | grep '^\(v[0-9]\+\)' >/dev/null
26
27
 
27
- if [ $? -ne 0 ]; then
28
+ if [[ $? -ne 0 ]]; then
28
29
  red "Error detecting current heroku release. Message from 'heroku releases':"
29
- echo "$HEROKU_RELEASES"
30
- red "Please contact a heroku collaborator for $HEROKU_APP:"
30
+ echo "${HEROKU_RELEASES}"
31
+ red "Please contact a heroku collaborator for ${HEROKU_APP}:"
31
32
  heroku sharing --app $HEROKU_APP
32
33
  exit 1;
33
34
  fi
34
35
 
35
36
  HEROKU_LAST_GOOD_RELEASE=`echo "$HEROKU_RELEASES" | head -n2 | tail -n1 | sed -e 's/^\(v[0-9]\+\).*/\1/'`
36
- green "Current heroku release: $HEROKU_LAST_GOOD_RELEASE"
37
+ green "Current heroku release: ${HEROKU_LAST_GOOD_RELEASE}"
37
38
 
38
39
  green "Pushing to heroku."
39
40
  $GIT_COMMAND
40
- if [ $? -ne 0 ]; then
41
+ if [[ $? -ne 0 ]]; then
41
42
  red "Heroku push rejected. See message above."
42
- red "Please contact a heroku collaborator for $HEROKU_APP:"
43
+ red "Please contact a heroku collaborator for ${HEROKU_APP}:"
43
44
  heroku sharing --app $HEROKU_APP
44
45
  exit 1;
45
46
  fi
46
47
 
47
- MIGRATIONS=`heroku run rake db:migrate:status --app $HEROKU_APP | grep -e '^\s*down'`
48
+ MIGRATION_STATUS=`heroku run rake db:migrate:status --app $HEROKU_APP | grep -e '^\s*down'`
48
49
 
49
- if [ "$MIGRATIONS" != "" ]; then
50
+ if [[ "${MIGRATION_STATUS}" != "" ]]; then
50
51
  green "There are pending migrations to apply:"
51
- echo $MIGRATIONS
52
+ echo $MIGRATION_STATUS
52
53
 
53
54
  green "Migrating database."
54
55
  heroku run rake db:migrate --app $HEROKU_APP
55
- if [ $? -ne 0 ]; then
56
+
57
+ POST_MIGRATION_STATUS=`heroku run rake db:migrate:status --app $HEROKU_APP | grep -e '^\s*down'`
58
+ if [[ "${POST_MIGRATION_STATUS}" != "" ]]; then
56
59
  red "Migration failed! This is bad."
57
- red "Please contact a heroku collaborator for $HEROKU_APP:"
60
+ red "Please contact a heroku collaborator for ${HEROKU_APP}:"
58
61
  heroku sharing --app $HEROKU_APP
59
- red "The app $HEROKU_APP will now be reverted to its last working version $HEROKU_LAST_GOOD_RELEASE."
62
+ red "The app ${HEROKU_APP} will now be reverted to its last working version ${HEROKU_LAST_GOOD_RELEASE}."
60
63
  heroku releases:rollback $HEROKU_LAST_GOOD_RELEASE --app $HEROKU_APP
61
64
  red "Abort."
62
65
  exit 1
63
66
  fi
64
67
 
65
- green "Post-migration dyno restart."
66
- heroku restart --app $HEROKU_APP
68
+ if [[ "${POST_MIGRATION_DEPLOY}" == "true" ]]; then
69
+ green "Post-migration dyno restart."
70
+ heroku restart --app $HEROKU_APP
71
+ fi
67
72
  else
68
73
  green "There are no pending migrations."
69
74
  fi
70
75
 
71
76
  green "All done."
72
-