Skip to content

Instantly share code, notes, and snippets.

@jewilmeer
Created February 19, 2024 15:51
Show Gist options
  • Save jewilmeer/7f0637616806a90c8cc4a7cd6d56df7c to your computer and use it in GitHub Desktop.
Save jewilmeer/7f0637616806a90c8cc4a7cd6d56df7c to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# example: ./upgrade_heroku_database myapp-staging
if ARGV.length != 1
puts "Usage: upgrade_heroku_database <namespace>"
exit
end
namespace = ARGV[0].chomp
# get the database names
output = `heroku pg:info -a #{namespace}`
database_names = output.split("\n").select { |line| line.start_with?('=== ') }.map { |line| line.gsub(/===\s/, '') }
target_database = database_names.find { |name| name != 'DATABASE_URL' }
warn "Target database: #{target_database}, enabling maintenance mode"
`heroku maintenance:on -a #{namespace}`
# get the current dynos
# example output: === web (Standard-1X): bundle exec puma -C config/puma.rb (1)
output = `heroku ps -a #{namespace}`
dynos = output.split("\n").select { |line| line.start_with?('=== ') }.map { |line| line.match(/===\s(\w+).*?\((\d)\)/) }.compact.map { |match| [match[1], match[2].to_i] }
warn 'Scaling down all dynos'
dynos.each do |dyno|
type, count = dyno
warn "Scaling down #{count} #{type} dynos"
`heroku ps:scale #{type}=0 -a #{namespace}`
end
warn 'Upgrading the database'
start_time = Time.now
`heroku pg:upgrade #{target_database} -a #{namespace} --confirm #{namespace}`
warn 'waiting for upgrade to finish'
`heroku pg:wait -a #{namespace}`
end_time = Time.now
# format the time difference in x minutes xx seconds
warn "upgrade finished in #{(end_time - start_time).divmod(60).join(' minutes ')} seconds"
warn "Promoting the new database"
`heroku pg:promote #{target_database} -a #{namespace}`
warn 'Scaling up the dynos'
dynos.each do |dyno|
type, count = dyno
warn "Scaling up #{count} #{type} dynos"
`heroku ps:scale #{type}=#{count} -a #{namespace}`
end
warn 'Disabling maintenance mode'
`heroku maintenance:off -a #{namespace}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment