Pull-Request Based Translation Workflow

At Jimdo, GitHub is a central part of our development workflow. We are using pull-requests to introduce new features or changes. As we deploy our production branch automatically, we have to ensure that all requirements are fulfilled before a pull-request gets merged.

Since Jimdo is available in eight languages, our translators are working hard to enable a native experience for users all around the world. We have switched from plain .po files to PhraseApp several months ago. In order to improve the translation workflow for the developers, we have build a tool that fits our pull-request based on translation process.

The translation process naturally includes lots of people, tools and time. For developers, the translation process might feel odd, as it mostly consists of simple but repeated steps: checking if new keys are needed / used, send the new keys with context, wait for all languages before deploying the change. When we thought about improving the process, we wanted the process to be really simple and easy to use.

As a developer I want to get a notification if I have introduced new translation keys.

I want to be able to deliver them to the translators easily.

I want to get notified if the translations are ready.

Introducing Babelfish

As you open a pull-request in our repository, Babelfish will search all modified files for translations. If you have introduced new translation keys that do not exist in PhraseApp, Babelfish comments the pull-request providing a link where you can push the new keys (with additional information) to PhraseApp in one simple step.

After the keys were pushed to PhraseApp, Babelfish will monitor them for you, showing the current status as a comment on the pull-request. This way, you'll get notified by GitHub when the translations are ready and the pull-request can be merged safely.

Under the hood

Searching for new keys in a pull-request

GitHub notifies Babelfish when a pull-request is created or updated. Babelfish then checks all files that were changed in the pull request. It uses the List pull requests files and then fetches the content using Get contents. It is required to fetch the full file content instead of the only the diff, because the translation key could span multiple lines and therefore could start or end outside the diff (we are using German texts as translation keys to have a fallback).

Babelfish uses regular expressions to extract all translation keys from the file contents. The found keys will be diffed against all translation keys, which are downloaded from PhraseApp on the fly (using Download translations).

The diff result contains only keys that do not exist in PhraseApp and therefore were introduced in this pull-request. If new keys were found, BabelFish uses the github API to create a comment.

Periodically checks

Babelfish does not remember which pull-requests contain translations. But GitHub does. Babelfish asks the GitHub API periodically which pull-requests it has commented on (using List issues with filter:subscribed). All of these will be checked for new translations or the current status of the translation progress. The PhraseApp API offers the translation status of a tag, that can be used to determine if all translations are ready. If so, the pull request is ready to be merged.


Babelfish is a stateless application that only knows about the API of GitHub and PhraseApp. Hosted at Heroku, deployed by travis. It uses angular for the frontend and node with express for the webserver and api. Based on the angular-fullstack yeoman generator. We are working on open sourcing babelfish.

Paul Mölders JavaScript Entwickler