Skip to content

Instantly share code, notes, and snippets.



Created Aug 13, 2019
What would you like to do?
Refresh demo/staging data in Heroku (cf.
#!/usr/bin/env bash
set -ex
# Pass in Heroku API token
# We run this script in a stateless Docker image, so to make the script a bit
# cleaner, we just write out the credentials to a file that the Heroku Toolbelt
# knows to read.
if ! grep -lq ~/.netrc 2>/dev/null; then
echo "machine" > ~/.netrc
echo " login" >> ~/.netrc
echo " password $token" >> ~/.netrc
chmod 0600 ~/.netrc
# Helper function for calling Heroku API
function hapi {
curl \
--fail \
--silent \
--netrc \
--header 'Accept: application/vnd.heroku+json; version=3' \$*
# Routine to wait for DB to be caught up, then promote it and de-provision the
# old instance.
function promote {
heroku pg:wait --wait-interval 10 -a $app
heroku pg:unfollow -a $app --confirm $app $app::NEW_DATABASE || true
heroku addons:attach -a $app $app::DATABASE --as OLD_DATABASE
heroku pg:promote -a $app NEW_DATABASE
heroku addons:detach -a $app NEW_DATABASE
heroku addons:destroy -a $app --confirm $app OLD_DATABASE
heroku run:detached -a $app rails runner 'Ops::Staging::Search.massacre!'
# Routine to create a new DB with a deterministic name so that we can more
# easily promote it later.
# There is also some logic here to recover from a build which got interrupted
# mid-way so that we don't accumulate orphaned DBs that we have to pay for.
function create {
shift 2
existing=$(hapi /addons/$app::DATABASE | jq -Mr .name)
new=$(hapi /addons/$app::NEW_DATABASE | jq -Mr .name || true)
if [ -z "$new" ]; then
heroku addons:create \
-a $app heroku-postgresql:$plan \
if [ "$new" == "$existing" ]; then
heroku addons:detach -a $app NEW_DATABASE
create $app $plan
true # already got a new one in waiting
# Takes a snapshot and copies it. This takes longer, breaks the destination
# DB until it has completed, so is only used for demo to demo-staging, which
# use Hobby DBs which cannot be followed/forked.
# One benefit of this which might be worth applying to staging/dev is that the
# destination data sizes (tables+indexes) are much smaller, which suits the
# smaller instance sizes used there.
function copy {
heroku pg:copy $src::DATABASE NEW_DATABASE \
--wait-interval 10 \
--app $dst \
--confirm $dst
# Create new DBs and trigger loading of data
create covidence-dev premium-0 --fork covidence-production::DATABASE --fast
create covidence-staging premium-2 --fork covidence-production::DATABASE --fast
create covidence-demo-staging hobby-basic
copy covidence-demo covidence-demo-staging
# Promote DBs (these steps block until each DB to be ready for promotion)
promote covidence-dev
promote covidence-staging
promote covidence-demo-staging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment