module Jumpup module Heroku class Integrate def self.deploy integrate.deploy end def self.deploy_to_production app = Env.all[:production_app] new(app).deploy_to_production end def self.add_remote integrate.add_remote end def self.check integrate.check end def self.lock integrate.lock end def self.unlock integrate.unlock end def self.integrate envs = Env.all app = envs[:app] || envs[:staging_app] new(app) end def initialize(app) @app = app @envs = Env.all end def deploy backup push migrate seed restart end def deploy_to_production confirm_deploy spec confirm_maintenance maintenance backup tag push migrate seed close_maintenance restart end def add_remote puts "--> Adding Heroku git remotes for app #{app}" remote = run_with_clean_env("git remote | grep heroku", true).strip run_with_clean_env("git remote add heroku git@heroku.com:#{app}.git") if remote.blank? end def check puts "--> Checking if there's already someone integrating to #{app}" var = run_with_clean_env("heroku config -s --app #{app} | grep INTEGRATING_BY", true).strip integrating_by = var.split('=')[1] integrating_by.strip! unless integrating_by.blank? if integrating_by != user and not integrating_by.blank? puts "--> Project is already being integrated by '#{integrating_by}', halting" exit end end def lock puts "--> Locking Heroku integration for you (#{user})" run_with_clean_env("heroku config:set INTEGRATING_BY='#{user}' --app #{app}") end def unlock puts "--> Unlocking Heroku integration" run_with_clean_env("heroku config:unset INTEGRATING_BY --app #{app}") end private attr_reader :app, :envs, :maintenance_mode def user @user ||= run_with_clean_env("git config --get user.name", true).strip end def run_with_clean_env(command, capture_output = false) Bundler.with_clean_env { capture_output ? `#{command}` : system(command) } end def confirm(message) print "\n#{message}\nAre you sure? [yN] " raise 'Ok. Bye...' unless STDIN.gets.chomp.downcase == 'y' end def run_database_tasks? @envs[:run_database_tasks] end def backup return unless run_database_tasks? puts "--> Backing up database via Heroku" run_with_clean_env("heroku pgbackups:capture --expire --app #{app}") end def migrate return unless run_database_tasks? puts "--> Migrating" run_with_clean_env("heroku run rake db:migrate --app #{app}") end def seed return unless run_database_tasks? puts "--> Seeding" run_with_clean_env("heroku run rake db:seed --app #{app}") end def restart puts "--> Restarting" run_with_clean_env("heroku restart --app #{app}") end def push puts "--> Pushing" run_with_clean_env("git push git@heroku.com:#{app}.git HEAD:master") end def confirm_deploy confirm("Going deploy to production [#{app}]...") end def spec puts "--> Running all specs" Rake::Task['spec'].invoke end def confirm_maintenance print "\nPut #{app} in maintenance mode? [Yn] " @maintenance_mode = true if STDIN.gets.chomp.downcase == 'y' end def maintenance? @maintenance_mode end def maintenance if maintenance? puts "--> Setting Maintenance on" run_with_clean_env("heroku maintenance:on --app #{app}") restart puts "--> Waiting 20 seconds to app come back (in maintenance mode)" sleep(20) end end def tag iso_date = Time.now.strftime('%Y-%m-%dT%H%M%S') tag_name = "production-#{iso_date}" puts "--> Tagging as #{tag_name}" run_with_clean_env("git tag #{tag_name} master") puts "--> Pushing to origin" run_with_clean_env("git push origin #{tag_name}") end def close_maintenance if maintenance? puts "Setting Maintenance off" run_with_clean_env("heroku maintenance:off --app #{app}") end end end end end