How to Heroku: automatic translations

Written by Allard Stijnman on 29th March 2015

For our ideal workflow we wanted to keep compiled files out of our git repo, since these generally only cause merge errors. However, Heroku only accepts git deploys and commands given to your app are run in a so called ‘one off dyno’, which is not ideal for our use case.

Identifying the problem

Ok, some more in-depth information. We want to keep compiled files out of our repo because we work in a team on multiple feature branches at once. To ensure your code works, it has to be tested and so the dev compiles after every change, leading to a lot of different versions of the compiled file across different branches. The solution is simple, delete and regenerate the file when you want to merge.

But why ignore .pyc files and include .mo files?

We’ve set our git to ignore those pesky .mo files and tried to let our server generate them on every new deploy. Of course this is tested beforehand on a staging environment to filter out human error in the source files. This leads to the following issues:

  1. Make gettext available on Heroku
  2. Make the generated files available on every dyno
  3. Make Heroku compile the files automatically after every deploy

The gettext library

The wonderful piotras actually did the heavy lifting for us. However at first it didn’t seem to work, so I spend some time searching for alternatives, which was stupid of me. The problem was that in one off dyno’s it worked, but in post compile hooks it didn’t. So I figured the post compile hook fired before gettext was added and put some debugging lines in place. The problem was that the modified path just wasn’t available to post compile hooks.

TLDR: Use this buildpack: https://github.com/piotras/heroku-buildpack-gettext.git

Your app slug

The answers to issues #2 and #3 are actually solved by the same thing; adding a post compile hook to your app. Like I mentioned above, you need to manually configure the path in your compile hook. After you’ve figured that out it’s fairly simple. Just read the documention here and add this file: bin/post_compile with the following contents:

#!/usr/bin/env bash
 set -eo pipefail
 # The post_compile hook is run by heroku-buildpack-python
 indent() {
    RE="s/^/       /"
    [ $(uname) == "Darwin" ] && sed -l "$RE" || sed -u "$RE"
 }
 echo "-----> In post-compile hook"
 export PATH=/app/gettext/bin:$PATH
 MANAGE_FILE=$(find . -maxdepth 3 -type f -name 'manage.py' | head -1)
 MANAGE_FILE=${MANAGE_FILE:2}
 echo "-----> Compiling translation files"
 python "$MANAGE_FILE" compilemessages 2>&1 | indent
 echo "-----> Done post-compile hook"
 echo ""

And you’re done! Enjoy your .mo free repo.

Your thoughts

  • Written by Carmelo on 9th June 2015

    It’s difficult to find well-informed people on this topic, however, you
    seem like you know what you’re talking about! Thanks

Devhouse Spindle