shipit-engine 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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
-