#!/bin/sh -e APP_NAME=$1 PIPELINE_APP_NAME=$APP_NAME-slug HEROKU_APP_REMOTE=git@heroku.com:$APP_NAME.git HEROKU_PIPELINE_REMOTE=git@heroku.com:$PIPELINE_APP_NAME.git WORKERS_COUNT=$(heroku ps --app $APP_NAME | grep "^worker." | wc -l | tr -d ' ') # configure pipeline deploy https://devcenter.heroku.com/articles/labs-pipelines heroku plugins:install git://github.com/heroku/heroku-pipeline.git if test $(heroku apps | grep $PIPELINE_APP_NAME -c) -gt 0; then echo "Using existing pipeline $PIPELINE_APP_NAME" git remote add pipeline $HEROKU_PIPELINE_REMOTE DIFF_REMOTE=pipeline else heroku apps:create $PIPELINE_APP_NAME --remote pipeline heroku labs:enable pipelines --app $PIPELINE_APP_NAME heroku pipeline:add $APP_NAME --app $PIPELINE_APP_NAME heroku pipeline --app $PIPELINE_APP_NAME git remote add heroku $HEROKU_APP_REMOTE DIFF_REMOTE=heroku fi # configure app and check for db changes git fetch $DIFF_REMOTE MIGRATION_CHANGES=$(git diff $CIRCLE_SHA1 $DIFF_REMOTE/master --name-only -- db | wc -l) echo "$MIGRATION_CHANGES db changes since last deploy." # use pipeline to prepare a slug to deploy git push pipeline $CIRCLE_SHA1:refs/heads/master DEPLOY_START=`date +%s` # migrations require downtime so enter maintenance mode if test $MIGRATION_CHANGES -gt 0; then heroku maintenance:on --app $APP_NAME # Make sure workers are not running during a migration heroku scale worker=0 --app $APP_NAME fi # Run our migrations in a subprocess so that failed db migrations # don't immediately abort our deploy script. ( # promote the compiled slug heroku pipeline:promote --app $PIPELINE_APP_NAME # run database migrations if needed and restart background workers once finished if test $MIGRATION_CHANGES -gt 0; then heroku run rake db:migrate --app $APP_NAME heroku run rake db:seed --app $APP_NAME fi ) MIGRATION_EXIT=$? # store the exit code # Always scale our workers back up, regardless of whether the migration failed if test $MIGRATION_CHANGES -gt 0; then heroku scale worker=$WORKERS_COUNT --app $APP_NAME fi # If the migration failed, now we can exit with that exit code if test $MIGRATION_EXIT -ne 0; then exit $MIGRATION_EXIT fi heroku run rake cache:flush --app $APP_NAME heroku maintenance:off --app $APP_NAME DEPLOY_END=`date +%s` ELAPSED=$(( $DEPLOY_END - $DEPLOY_START )) echo "Deploy completed!" if test $MIGRATION_CHANGES -gt 0; then echo " $ELAPSED seconds in maintenance mode." else echo " $ELAPSED seconds, without maintenance mode." fi exit 0