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.
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
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
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