Skip to content

Instantly share code, notes, and snippets.

@jfeaver
Last active September 29, 2015 00:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfeaver/587d0b83504650560361 to your computer and use it in GitHub Desktop.
Save jfeaver/587d0b83504650560361 to your computer and use it in GitHub Desktop.
Heroku Deploy Script
class DeployTask
attr_accessor :app_suffix, :heroku_app, :git_branch, :force, :enter_maintenance
def initialize(options = {})
@app_suffix = options[:app_suffix]
@heroku_app = options.fetch(:heroku_app, default_app_name)
@git_branch = options.fetch(:git_branch, current_branch)
@force = options.fetch(:force, false)
@enter_maintenance = options.fetch(:enter_maintenance, true)
end
def deploy
start = Time.now
maintenance do
push
migrate
end
open
puts "===== This whole process took #{Time.now - start} seconds"
end
def migrate
start = Time.now
maintenance do
migrate
end
puts "===== This whole process took #{Time.now - start} seconds"
end
private
def default_app_name
if defined?(Rails)
name = Rails.application.class.parent_name.underscore.dasherize
name += "-#{app_suffix}" if app_suffix
name
end
end
def current_branch
@current_branch ||= `git rev-parse --abbrev-ref HEAD`.chomp
end
def push
branch_to_branch = (current_branch.length > 0) ? "#{current_branch}:master" : ""
puts "===== I am going to deploy this application to heroku"
puts "git push#{ " -f" if force } git@heroku.com:#{heroku_app}.git #{branch_to_branch}"
puts `git push#{ " -f" if force } git@heroku.com:#{heroku_app}.git #{branch_to_branch}`
end
def maintenance
if enter_maintenance
maintenance_on
yield
maintenance_off
else
yield
end
end
def maintenance_on
puts '===== Putting the app into maintenance mode'
Bundler.with_clean_env { puts `heroku maintenance:on --app=#{heroku_app}` }
end
def maintenance_off
puts '===== Taking the app out of maintenance mode'
Bundler.with_clean_env { puts `heroku maintenance:off --app=#{heroku_app}` }
end
def migrate
puts 'Running database migrations'
Bundler.with_clean_env { puts `heroku run 'rake db:migrate' --app=#{heroku_app}` }
end
def open
sleep(0.2) # wait for any pending requests to finish
puts '===== Opening the app in your browser'
Bundler.with_clean_env { puts `heroku open --app=#{heroku_app}` }
end
end
namespace :deploy do
namespace :develop do
task :migrate do
DeployTask.new({
app_suffix: 'develop',
}).migrate
end
end
task :develop do
DeployTask.new({
app_suffix: 'develop'
}).deploy
end
namespace :production do
task :migrate do
DeployTask.new.migrate
end
end
task :production, [:branch] do |t, args|
args.with_defaults(branch: 'master')
DeployTask.new({
git_branch: args[:branch]
}).deploy
end
end
task :deploy do
DeployTask.new({
app_suffix: 'develop'
}).deploy
end
@jfeaver
Copy link
Author

jfeaver commented May 20, 2015

At the moment, this script makes some assumptions:

  1. You're deploying a Rails application
  2. Your project uses git
  3. You're deploying to Heroku
  4. You want to deploy the currently checked out git branch
  5. The Heroku app uses the dasherized version of your Rails Application name
  6. Your development server app name prepends '-develop' to your production app name
  7. You don't need to run any seeds or rake tasks during deployment (which should be done with maintenance mode turned on)

For example:

Rails application: CoolApp
Heroku endpoint: https://cool-app.herokuapp.com
Heroku develop (or staging) endpoint: https://cool-app-develop.herokuapp.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment