-
-
Save jphenow/5694169 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Deploy and rollback on Heroku in staging and production | |
%w[staging production].each do |app| | |
desc "Deploy to #{app}" | |
task "deploy:#{app}" => %W[deploy:set_#{app}_app deploy:push deploy:restart deploy:tag] | |
desc "Deploy #{app} with migrations" | |
task "deploy:#{app}:migrations" => %W[deploy:set_#{app}_app deploy:push deploy:off deploy:migrate deploy:restart deploy:on deploy:tag] | |
desc "Rollback staging" | |
task "staging:rollback" => [:set_staging_app, :off, :push_previous, :restart, :on] | |
%w[logs config ps releases].each do |app_task| | |
desc "#{app} #{app_task}" | |
task "app:#{app}:#{app_task}" => ["deploy:set_#{app}_app", "app:#{app_task}"] | |
end | |
end | |
namespace :deploy do | |
PRODUCTION_APP = 'YOUR_PRODUCTION_APP_NAME_ON_HEROKU' | |
STAGING_APP = 'YOUR_STAGING_APP_NAME_ON_HEROKU' | |
task :set_staging_app do | |
raise "NOT SET" if !STAGING_APP || STAGING_APP.empty? || STAGING_APP == 'YOUR_STAGING_APP_NAME_ON_HEROKU' | |
APP = STAGING_APP | |
end | |
task :set_production_app do | |
raise "NOT SET" if !PRODUCTION_APP || PRODUCTION_APP.empty? || PRODUCTION_APP == 'YOUR_PRODUCTION_APP_NAME_ON_HEROKU' | |
APP = PRODUCTION_APP | |
end | |
task :push do | |
git_status = `git status -v` | |
abort("local branch is out of sync with github origin. please push there first") if git_status.match(/\*[^\]]+?\[ahead|behind/s) != nil | |
current_branch = `git rev-parse --abbrev-ref HEAD`.chomp | |
current_branch += ":master" if current_branch != "master" | |
puts "Deploying #{current_branch} to #{APP} ..." | |
puts `git push -f [email protected]:#{APP}.git #{current_branch}` | |
end | |
task :restart do | |
puts 'Restarting app servers ...' | |
Bundler.with_clean_env do | |
puts `heroku restart --app #{APP}` | |
end | |
end | |
task :tag do | |
release_name = "#{APP}-release-#{Time.now.utc.strftime("%Y%m%d%H%M%S")}" | |
puts "Tagging release as '#{release_name}'" | |
puts `git tag -a #{release_name} -m 'Tagged release'` | |
puts `git push --tags [email protected]:#{APP}.git` | |
puts `git push --tags origin` | |
end | |
task :migrate do | |
puts 'Running database migrations ...' | |
Bundler.with_clean_env do | |
puts `heroku rake db:migrate --app #{APP}` | |
end | |
end | |
task :off do | |
puts 'Putting the app into maintenance mode ...' | |
Bundler.with_clean_env do | |
puts `heroku maintenance:on --app #{APP}` | |
end | |
end | |
task :on do | |
puts 'Taking the app out of maintenance mode ...' | |
Bundler.with_clean_env do | |
puts `heroku maintenance:off --app #{APP}` | |
end | |
end | |
task :push_previous do | |
prefix = "#{APP}-release-" | |
releases = `git tag`.split("\n").select { |t| t[0..prefix.length-1] == prefix }.sort | |
current_release = releases.last | |
previous_release = releases[-2] if releases.length >= 2 | |
if previous_release | |
puts "Rolling back to '#{previous_release}' ..." | |
puts "Checking out '#{previous_release}' in a new branch on local git repo ..." | |
puts `git checkout #{previous_release}` | |
puts `git checkout -b #{previous_release}` | |
puts "Removing tagged version '#{previous_release}' (now transformed in branch) ..." | |
puts `git tag -d #{previous_release}` | |
puts `git push [email protected]:#{APP}.git :refs/tags/#{previous_release}` | |
puts "Pushing '#{previous_release}' to Heroku master ..." | |
puts `git push [email protected]:#{APP}.git +#{previous_release}:master --force` | |
puts "Deleting rollbacked release '#{current_release}' ..." | |
puts `git tag -d #{current_release}` | |
puts `git push [email protected]:#{APP}.git :refs/tags/#{current_release}` | |
puts "Retagging release '#{previous_release}' in case to repeat this process (other rollbacks)..." | |
puts `git tag -a #{previous_release} -m 'Tagged release'` | |
puts `git push --tags [email protected]:#{APP}.git` | |
puts "Turning local repo checked out on master ..." | |
puts `git checkout master` | |
puts 'All done!' | |
else | |
puts "No release tags found - can't roll back!" | |
puts releases | |
end | |
end | |
end | |
namespace :app do | |
task :logs do | |
puts "tailing logs..." | |
Bundler.clean_exec "heroku logs --tail --app #{APP}" | |
end | |
task :config do | |
puts "config..." | |
Bundler.with_clean_env do | |
puts `heroku config --app #{APP}` | |
end | |
end | |
task :ps do | |
puts "running processes..." | |
Bundler.with_clean_env do | |
puts `heroku ps --app #{APP}` | |
end | |
end | |
task :releases do | |
puts "releases..." | |
Bundler.with_clean_env do | |
puts `heroku releases --app #{APP}` | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment