class BbDeploy::Deployer

Attributes

phase[R]

Public Class Methods

new(phase) click to toggle source
# File lib/bb_deploy/deployer.rb, line 14
def initialize(phase)
  BbDeploy::Config.configure_from_yaml('config/deploy.yml')
  BbDeploy::Config.set_heroku_fields!(phase)
  @phase = phase
end

Public Instance Methods

deploy!() click to toggle source
# File lib/bb_deploy/deployer.rb, line 25
def deploy!
  BbDeploy::Git.check_git_status!
  check_access!
  staging_checks if phase == 'staging'
  prompt = "Do you want to deploy #{current_branch} to #{BbDeploy::Config.application_name} #{phase}?"
  if phase == 'production'
    do_deploy if BbDeploy::Task.ask(prompt, required_response: 'production', important: true)
  else
    do_deploy if BbDeploy::Task.ask(prompt)
  end
end

Private Instance Methods

check_access!() click to toggle source
# File lib/bb_deploy/deployer.rb, line 73
def check_access!
  unless BbDeploy::Heroku.has_access?(phase)
    exit_with_message("You do not have access to the #{BbDeploy::Config.application_name} #{phase} application!")
  end
end
current_branch() click to toggle source
# File lib/bb_deploy/deployer.rb, line 47
def current_branch
  BbDeploy::Git.current_branch(started_on_master?)
end
do_deploy() click to toggle source
# File lib/bb_deploy/deployer.rb, line 51
def do_deploy
  branch = current_branch

  chat_broadcast(":alert: '#{ENV['USER']}' is deploying the #{BbDeploy::Config.application_name} branch '#{branch}' to '#{phase}' :alert:", phase: phase, notify_eng_hub: true)

  do_heroku_deploy!

  open_in_browser

  if phase != 'qa' && !started_on_master?
    puts "Merging back to master ..."
    puts `git checkout master && git pull && git merge -`
    puts "You must now resolve any conflicts in the merge and then `git push origin master` ..."
   end

  chat_broadcast(":alertgreen: Deployment of the #{BbDeploy::Config.application_name} branch '#{branch}' to '#{phase}' completed! :alertgreen:", phase: phase, notify_eng_hub: true)
end
do_heroku_deploy!() click to toggle source
# File lib/bb_deploy/deployer.rb, line 84
def do_heroku_deploy! # rubocop:disable all
  run_migrations = run_migrations?

  exit(0) if run_migrations && !BbDeploy::Task.ask("There are new migrations to run.  If you proceed,\n\n*** YOU WILL INCUR SITE DOWNTIME!!! ***\n\nDo you wish to proceed?")

  enter_maint_mode = run_migrations || BbDeploy::Task.ask("Would you like to put #{BbDeploy::Config.application_name} into maintenance mode even though you don't have any migrations to run?")
  if enter_maint_mode
    stay_in_maint_mode = BbDeploy::Task.ask('Would you like to stay in maintenance mode after deployment, e.g. to run some rake tasks?')
    logger.with_consolidated_logging { BbDeploy::Heroku.toggle_maintenance(mode: :on, phase: phase) }
  end

  push_release!

  run_migrations! if run_migrations

  if enter_maint_mode
    if stay_in_maint_mode
      dputs "********** NOTE: YOU ARE STILL IN MAINTENANCE MODE, AND MUST MANUALLY DISABLE IT VIA `rake heroku:maint:off:#{phase}` **********"
    else
      logger.with_consolidated_logging { BbDeploy::Heroku.toggle_maintenance(mode: :off, phase: phase) }
    end
  end
end
dputs(*msgs) click to toggle source
# File lib/bb_deploy/deployer.rb, line 39
def dputs(*msgs)
  asterisks = "*" * 80
  puts asterisks
  puts(*msgs.map(&:to_s))
  puts asterisks
end
exit_with_message(msg) click to toggle source
# File lib/bb_deploy/deployer.rb, line 79
def exit_with_message(msg)
  puts "\n#{msg}\n"
  exit(0)
end
logger() click to toggle source
# File lib/bb_deploy/deployer.rb, line 69
def logger
  @logger ||= BbDeploy::Logger.logger(phase)
end
open_in_browser() click to toggle source
# File lib/bb_deploy/deployer.rb, line 128
def open_in_browser
  sleep 2 # because removing maint mode takes a couple seconds to propagate
  host_and_path =
    case phase
    when 'qa'; BbDeploy::Config.application_urls['qa']
    when 'staging'; BbDeploy::Config.application_urls['staging']
    when 'production'; BbDeploy::Config.application_urls['production']
    end

  puts "Opening the site for inspection ..."
  BbDeploy::Task.run("open https://#{host_and_path}")
end
push_release!() click to toggle source
# File lib/bb_deploy/deployer.rb, line 122
def push_release!
  puts "Deploying ..."
  chat_broadcast("Pushing #{BbDeploy::Config.application_name} branch '#{current_branch}' to #{phase} ...", phase: phase)
  logger.with_consolidated_logging { puts(BbDeploy::Git.push_to_phase(phase)) }
end
run_migrations!() click to toggle source
# File lib/bb_deploy/deployer.rb, line 108
def run_migrations!
  started_at = Time.current

  chat_broadcast("Running migrations from #{BbDeploy::Config.application_name} branch '#{current_branch}' in #{phase} ...", phase: phase)
  logger.with_consolidated_logging { BbDeploy::Heroku.migrate_db!(phase) }
  chat_broadcast("Successfully ran migrations from #{BbDeploy::Config.application_name} branch '#{current_branch}' in #{phase}.", phase: phase)

  time_spent = Time.zone.at(Time.current - started_at).getutc.strftime("%H:%M:%S")
  # The only time started_on_master is non-nil is when creating a new staging branch
  if started_on_master?
    chat_broadcast("Yo, @jake - the #{BbDeploy::Config.application_name} branch '#{current_branch}' contains migrations that take #{time_spent} to run", phase: phase, notify_eng_hub: true)
  end
end
run_migrations?() click to toggle source
# File lib/bb_deploy/deployer.rb, line 141
def run_migrations?
  sha = BbDeploy::Heroku.last_release_sha(phase)
  BbDeploy::Git.migrations_present?(sha)
end
staging_checks() click to toggle source
# File lib/bb_deploy/deployer.rb, line 154
def staging_checks
  if BbDeploy::Git.on_master?
    do_it = BbDeploy::Task.ask("You are on master. Do you want to create a ***NEW*** release branch from the HEAD of master and deploy it to #{BbDeploy::Config.application_name} #{phase}?")

    if do_it
      date = Time.zone.today.to_s(:db).tr('-', '_')
      new_branch = "release_#{date}"

      if BbDeploy::Git.local_release(new_branch).present?
        exit_with_message("There already exists a local release branch named #{new_branch}!")
      end

      if BbDeploy::Git.remote_release(new_branch).present?
        exit_with_message("There already exists a remote release branch named #{new_branch}!")
      end

      BbDeploy::Git.push_release_branch!

      started_on_master!
    end
  elsif BbDeploy::Git.on_a_release_branch?
    do_it = BbDeploy::Task.ask("Do you want to ***REDEPLOY*** the HEAD of your local version of #{current_branch} to #{BbDeploy::Config.application_name} #{phase}?")
  else
    exit_with_message("You may only deploy master or a release branch to #{BbDeploy::Config.application_name} #{phase}!")
  end
end
started_on_master!() click to toggle source
# File lib/bb_deploy/deployer.rb, line 146
def started_on_master!
  @started_on_mater = true
end
started_on_master?() click to toggle source
# File lib/bb_deploy/deployer.rb, line 150
def started_on_master?
  !!@started_on_master
end