This time I wanna share with you something rather small, but really helpful: my default Heroku deploy script. It will push new code to your Heroku application and run migrations, if necessary.

I took the basics of this script from Thoughtbot's hound bin/deploy script but extended it a bit to conditionally execute migrations, depending on if we've modified anything on the schema.

Here is the complete script:

#!/bin/sh                                                                        

set -e                                                                           

branch="$(git symbolic-ref HEAD --short)"                                        
target="${1:-staging}"                                                           

git push "$target" "$branch:master"                                              

target_version="$(heroku run rake db:version --remote "$target" | grep -oE "\d+")"
branch_version="$(bundle exec rake db:version | grep -oE "\d+")"                 

if [ "$target_version" -ne "$branch_version" ]                                   
then                                                                             
  heroku run rake db:migrate --remote "$target"                                  
  heroku restart --remote "$target"                                              
fi

First we get the currently checked out branch in our git repository. We also set a remote branch, which is the first argument to the script or its default, 'staging'. We then push the current branch to the remote's master branch, which will trigger a deploy on Heroku.

We then check for the current DB version on Heroku, as well as locally. If they are equal we do nothing and we're done with our deploy. If they aren't the same, we run a rake db:migrate on the Heroku app and finally restart the application, so that Rails will pick up any changes to the database models.

That's it! I copy this script to every new Rails application I'm setting up on Heroku, as it eases deployment and encapsulates a set of repetitive tasks in a single bin/deploy.