Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save padi/5c61b1b3ab14da990c50084a9fad84ca to your computer and use it in GitHub Desktop.
Save padi/5c61b1b3ab14da990c50084a9fad84ca to your computer and use it in GitHub Desktop.
Heroku Release Phase script for managing Rails DB migrations, and playing nice with Review Apps and postdeploy scripts

Heroku Release Phase + Review Apps + Rails

This is a simplified, but fairly thorough, set of scripts and configuration to enable Heroku Release Phase for Rails apps. Further, this particular set up plays nicely with Heroku Review Apps in that the release phase script will:

  1. Fail, loudly, if the DB does not yet exist.
  2. Load the DB schema if the current schema version (as determined by bin/rails db:version) is 0.
  3. Run DB migrations otherwise.

For a "normal" app that usually means it will run the DB migrations. For a Review App, on the first deploy the release phase will bin/rails db:schema:load. And then the postdeploy script will seed data. During subsequent deploys to the Review App, the release phase will bin/rails db:migrate.

{
"name": "your-app-name",
"description": "Configuration for per-Pull-Request Reviews Apps on Heroku.",
"scripts": {
"postdeploy": "LOG_LEVEL=INFO bin/rake review_app:seed"
},
"stack": "heroku-16",
"formation": [
{ "process": "web", "quantity": 1 },
{ "process": "worker", "quantity": 1 }
],
"addons": [
"heroku-postgresql:hobby-dev"
],
"buildpacks": [
{
"url": "heroku/ruby"
}
],
"env": {
"Lots of other Env Vars...": "as you need",
"HEROKU_APP_NAME": {
"required": true
},
"HEROKU_PARENT_APP_NAME": {
"required": true
}
}
}
#!/usr/bin/env bash
#
# Usage: bin/heroku_deploy
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NO_COLOR='\033[0m'
set -euo pipefail
schema_version=$(bin/rails db:version | { grep "^Current version: [0-9]\\+$" || true; } | tr -s ' ' | cut -d ' ' -f3)
if [ -z "$schema_version" ]; then
printf "💀${RED} [Release Phase]: Database schema version could not be determined. Does the database exist?${NO_COLOR}\n"
exit 1
fi
if [ "$schema_version" -eq "0" ]; then
printf "\n⏳${YELLOW} [Release Phase]: Loading the database schema.${NO_COLOR}\n"
bin/rails db:schema:load
else
printf "\n⏳${YELLOW} [Release Phase]: Running database migrations.${NO_COLOR}\n"
bin/rails db:migrate
fi
printf "\n🎉${GREEN} [Release Phase]: Database is up to date.${NO_COLOR}\n"
web: bundle exec puma -C ./config/puma.rb
worker: DB_POOL_SIZE=${WORKER_CONCURRENCY:-20} bundle exec sidekiq -c ${WORKER_CONCURRENCY:-20} -t ${WORKER_TIMEOUT:-25} -q default,1 -q mailers,1
# === Heroku Release Phase, ignored by `heroku local`. See: https://devcenter.heroku.com/articles/release-phase
release: bin/heroku_release
# frozen_string_literal: true
namespace :review_app do
desc 'Ensure environment is one we shish to spread seed in'
task :ensure_review_app do
abort 'This is not a Heroku Review App' unless review_app?
end
desc 'Seeds a review app with a subset of realistic-looking data'
task :seed, [] => %w[
ensure_review_app
environment
db:seed
seed:administrator
seed:widgets
] do
Rails.logger.tagged('Seed App') { |l| l.info("Finished seeding new Review App: #{ENV['HEROKU_APP_NAME']}") }
end
def review_app?
!!ENV['HEROKU_PARENT_APP_NAME']
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment