Skip to content

Instantly share code, notes, and snippets.

@fgrehm

fgrehm/deploy.rake

Forked from njvitto/deploy.rake
Last active Jul 27, 2018
Embed
What would you like to do?
Rakefile to deploy and rollback to Heroku in two different environments (staging and production) for the same app
# Deploy and rollback on Heroku in staging and production
namespace :deploy do
PRODUCTION_APP = 'YOUR_PRODUCTION_APP'
STAGING_APP = 'YOUR_STAGING_APP'
REMOTE = ENV["REMOTE_HOST"] || "git@heroku.com"
def heroku_cmd(cmd)
Bundler.with_clean_env do
sh "heroku #{cmd}"
end
end
desc 'Deploy app to staging'
task :staging => [:set_staging_app, :off, :push, :migrate, :on]#, :tag]
task :staging_rollback => [:set_staging_app, :off, :push_previous, :restart, :on]
desc 'Deploy app to production'
task :production => [:set_production_app, :off, :push, :migrate, :on, :tag]
task :production_rollback => [:set_production_app, :off, :push_previous, :restart, :on]
task :set_staging_app do
APP = STAGING_APP
end
task :set_production_app do
APP = PRODUCTION_APP
end
task :push do
puts 'Deploying site to Heroku ...'
sh "git push #{REMOTE}:#{APP}.git master"
end
task :restart do
puts 'Restarting app servers ...'
heroku_cmd "heroku restart --app #{APP}"
end
task :tag do
release_name = "#{APP}_release-#{Time.now.utc.strftime("%Y%m%d%H%M%S")}"
puts "Tagging release as '#{release_name}'"
sh "git tag -a #{release_name} -m 'Tagged release'"
sh "git push --tags #{REMOTE}:#{APP}.git"
end
task :migrate do
puts 'Running database migrations ...'
heroku_cmd "run rake db:migrate --app #{APP}"
end
task :off do
puts 'Putting the app into maintenance mode ...'
heroku_cmd "maintenance:on --app #{APP}"
end
task :on do
puts 'Taking the app out of maintenance mode ...'
heroku_cmd "maintenance:off --app #{APP}"
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 ..."
sh "git checkout #{previous_release}"
sh "git checkout -b #{previous_release}"
puts "Removing tagged version '#{previous_release}' (now transformed in branch) ..."
sh "git tag -d #{previous_release}"
sh "git push #{REMOTE}:#{APP}.git :refs/tags/#{previous_release}"
puts "Pushing '#{previous_release}' to Heroku master ..."
sh "git push #{REMOTE}:#{APP}.git +#{previous_release}:master --force"
puts "Deleting rollbacked release '#{current_release}' ..."
sh "git tag -d #{current_release}"
sh "git push #{REMOTE}:#{APP}.git :refs/tags/#{current_release}"
puts "Retagging release '#{previous_release}' in case to repeat this process (other rollbacks)..."
sh "git tag -a #{previous_release} -m 'Tagged release'"
sh "git push --tags #{REMOTE}:#{APP}.git"
puts "Turning local repo checked out on master ..."
sh "git checkout master"
puts 'All done!'
else
puts "No release tags found - can't roll back!"
puts releases
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.