Sunday, January 13, 2013

Builds that use git info on Heroku

If your build expects there to be a local git repo to do things like generate build numbers, change logs, etc, you'll find it won't work on Heroku.  The reason is because the slug compiler kindly removes the .git directory before the build runs.  Here is how I worked around it for my Maven 3-based Java build.

The key is to restore the .git directory before the rest of the Maven 3 build executes.  I do this by adding this profile to my build:

Of course, replace "https://bitbucket.org/mrdon/weapon-m.git" with your repository.

What this does is check to see if the ".git" directory is missing, which it will be only for Heroku builds as they remove the directory before Maven execution, clone the repo, then move its ".git" directory back where it belongs. 

This approach has several notable gotchas:
  1. Your repository url must contain any authentication information.  If your main repo is anonymous accessible, great, otherwise, you'll have to find someway to encode authentication credentials in the URL.
  2. You'll need to push to your main repo before you push to heroku.  This is a shame as I like to run "git push heroku master && git push origin master" to let me rewrite the commit in case the build fails on Heroku, which it occasionally does.  However, with this technique, if you want that git information in your build, you'll have to push to your main repo first.
  3. Only operations that view the history will work correctly.  If you tried to run "git status" or manipulated your local copy, git is all confused.
I hope that this saves someone the hours it took me to find this workaround :)