Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rake tasks for Heroku Deployments.
#####################################
# Rake tasks for Heroku Deployments #
#####################################
#
# Assumptions:
# - You’re using Heroku to deploy a Rails application or similar.
# - You have two remotes, one called 'production', and one called 'staging'.
# - You have a 'master' branch, and it usually contains stable code.
#
# Usage:
# rake deploy:ENVIRONMENT[BRANCH]
#
# Where:
# - ENVIRONMENT is one of "production", "staging", or "all" (without quotes).
# - BRANCH is the name of the branch you wish to deploy (defaults to "master").
#
# Note: The [branch] section is optional for all commands.
#
# Mostly stolen from https://gist.github.com/croaky/1189285
namespace :deploy do
desc "Deploy to staging on Heroku"
task :staging, :branch do |t, args|
Deployment.new(environment: "staging", branch: args[:branch]).run
end
desc "Deploy to production on Heroku"
task :production, :branch do |t, args|
Deployment.new(environment: "production", branch: args[:branch]).run
end
desc "Deploy to all environments on Heroku"
task :all, :branch do |t, args|
%w[ staging production ].each do |remote|
Deployment.new(environment: remote, branch: args[:branch]).run
end
end
end
class Deployment
def initialize(opts = {})
@environment = opts[:environment]
@branch = opts[:branch] || "master"
@start_time = Time.now
end
def run
debug_output "Started deploying '#{@branch}' to #{@environment}."
push_heroku
migrate
debug_output "Deployment finished in #{duration}."
end
private
def push_heroku
debug_output "Pushing to Heroku remote…"
run_command "git push #{@environment} #{@branch}:master --force"
end
def migrate
debug_output "Migrating database…"
run_command "bundle exec heroku run rake db:migrate --remote #{@environment}"
end
def debug_output(message)
puts "[Deploy] #{message}"
end
def run_command(command)
puts "=> Running `#{command}`"
`#{command}`
# `ls -l`
debug_output "Done."
end
def duration
difference = Time.now - @start_time
total_seconds = Integer(difference)
if total_seconds == 0
"#{difference * 1000}ms"
else
hours = total_seconds / (60 * 60)
minutes = (total_seconds / 60) % 60
seconds = total_seconds % 60
hours_output = hours > 0 ? "#{hours} hours" : ""
hours_output << ", " if hours > 0 && minutes > 0
minutes_output = minutes > 0 ? "#{minutes} minutes" : ""
minutes_output << ", " if minutes > 0 && seconds > 0
seconds_output = seconds > 0 ? "#{seconds} seconds" : ""
output = hours_output + minutes_output + seconds_output
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.