August 31, 2011
Simple staging on Heroku

Not everything runs the same on production as it does on localhost so you need a staging environment to vet changes before making them public.

When developing Piazza (on GitHub) we put together a simple workflow to manage production and staging deployments. Our app is built on the Heroku Cedar stack with Java and the Play framework but this workflow should be applicable to all other apps on Heroku.

Git branches

We need Git branches to track what we have on Heroku. We will be pushing these back to our central repository origin (GitHub in our case) to facilitate easier collaboration.

git checkout -b prod
git checkout -b staging
git push origin prod
git push origin staging

Heroku setup

You will need two different Heroku applications, one for staging and one for production. If you’re starting from scratch you can create these applications and attach them to the right Git remote repository.

heroku create --stack cedar --remote prod
heroku create --stack cedar --remote staging

If you already have a Heroku app under the Git remote heroku you can rename it and create a new app for staging.

git remote rename heroku prod
heroku create --stack cedar --remote staging

make me a sandwich

Create a file in your project root named makefile (with the lowercase m). We will create two make targets in this file which are basically project specific shortcuts. There’s a lot more you can do with make but we’re sticking to basics. Our two make targets look like this:

make stage will now deploy the contents of the staging branch to the appropriate Heroku app followed by GitHub. make deploy will do the same with the prod branch. You will have to merge changes from master into these branches yourself like so:

git checkout staging
git merge master
make stage

Bonus: Keeping branches clean

Since you have to update the staging and prod branches manually it is good to put in some safety measures to prevent bad deployments. For our part, we require the Git branch to be clean. A simple Bash script can check Git to see if there are any uncommitted changes and abort the make target

The new make targets should look like

Now if you try to make stage with a dirty repo the deployment will be aborted.

$ git checkout prod
Switched to branch 'prod'
$ touch newfile
$ make deploy
There are uncommitted changes.
make: *** [deploy] Error 1

Appendix

  1. paksoy posted this