Automated Localization: Github Actions + Localazy

Automated Localization

You have probably already heard of continuous localization. It’s important as software development is a never-ending process, and with new features, you usually need to add new strings.

Fully automated localization is a level above it. As a developer, you only set up it once, and then, you can forget about it completely.

And as we are going to use Github Actions, it’s gonna be fun!

Configure Localization Platform

Let’s suppose that your mobile, desktop or web app is ready for localization, and strings in the source language are stored in JSON, YAML, iOS’ strings, Flutter’s ARB, or some other common format.

Sign up with Localazy, create a new project, install the CLI tool, and then create and test your localazy.json configuration. You should be able to upload the source language files and download localized ones.

My configuration is as simple as:

{
  "readKey": "read-key",
  "writeKey": "write-key",
  "upload": {  
    "type": "json",
    "files": "locales/en.json"         
  },
  
  "download": {
    "files": "locales/${lang}.json"
  }
}

From this moment on, Localazy is the place to manage your translations, translators, and contributors. And as a bonus, it translates your app to up to 80 languages for free by sharing translations with other apps.

Creating and testing localazy.json is essential as it’s used by the Github actions described below.

Setup Secrets

Private data should not be committed, and so, before the commit, let’s remove the read and write keys from the configuration file above and instead place them to Github Secrets.

Create a repository on Github if you haven’t yet, go to Settings > Secrets, and add keys here. My configuration looks like:

![](upload://ajWOhB2hsCJNWaFNnsaOxguMwPV.png)

Ignore Localized Files

The source language file - in my case en.json - is the source of truth, and for localized files, it’s the latest version on Localazy. I don’t need those files to be committed to my repository.

With a simple .gitignore file placed in the locales folder, I can filter out all localized files except for the source language one:

!en.json
*.json

Automate Uploading

If you are not familiar with Github Actions, I recommend reading more about it. It may take some time to get used to it, but it saves you a lot of time. We use it extensively for building releases of our Localazy CLI.

The configuration below is all I need for uploading the source language file en.json to Localazy with each commit that changes it. I add a new feature, add new strings to en.json, commit it, and push it. Done.

And all you need to do now is to create .github/workflows/upload.yml file with this content:

name: Upload to Localazy
on: 
  push:
    paths: 
      - 'locales/en.json'
jobs:
  localazy-upload:
    name: Upload strings to Localazy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/[email protected]
      - uses: localazy/[email protected]
        with:
          read_key: ${{ secrets.LOCALAZY_READ_KEY }}
          write_key: ${{ secrets.LOCALAZY_WRITE_KEY }}

If you need to fine-tune it, there is the documentation for the upload action on Github Marketplace.

It’s also simple to configure the on clause to upload strings to Localazy only for releases, certain tags or branches. See its configuration on Github docs.

On each push touching en.json, I get this beauty:

![](upload://arqhwMEyVPAzj2TlUW2ez6FQhXB.png)

Automate Downloading

Normally, you would integrate downloading localizable files from Localazy into your build chain, so they are added before building the release.

For clarity, let’s test just the downloading and omit other steps.

Create file .github/workflows/download.yml for downloading the latest version of localizable files whenever the tag v* is pushed.

name: Download from Localazy
on: 
  push:
    tags:
    - 'v*'
jobs:
  localazy-download-test:
    name: Download strings from Localazy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/[email protected]
      - uses: localazy/[email protected]
        with:
          read_key: ${{ secrets.LOCALAZY_READ_KEY }}
          write_key: ${{ secrets.LOCALAZY_WRITE_KEY }}
          
      - run: |
          # Test that localized files were downloaded by listing 
          # the content of locales folder.
          ls locales/*.json

Of course, this example effectively does nothing as files are only downloaded to the action, and if we don’t use them to produce the release build, they are lost once the action is finished and cleared.

The documentation for the localazy/download action is available on Github Marketplace.

Pushing v2 tag to my test repository (notice that there is cs.json file):

![](upload://h8RidxPnRN2W8O5FbYtyYd8aJyf.png)

Source Code

The source code of a demonstrational project for this post is available on Github. Do not forget to explore the content of the .github/workflows folder!

Closing Words

As you can see, it’s simple enough to completely remove the localization burden from your shoulders with Localazy. No more file handling. All the translations of your lovely app can be managed in a single place with beautiful UI designed for developers and those that want them to bring their apps into the multilingual realm.


This is a companion discussion topic for the original entry at https://localazy.com/blog/automated-localization-github-actions-localazy

how to create commit from github action to the repository only if there is a changes after doing localazy download?

Hello. You can use for example git-auto-commit action. By default, it performs dirty check which means it only runs when there are some changes.

Then it depends on which occasions you’d like to run the workflow. E.g. for every commit in every branch, in PR merges and commits in selected branches or differently.

Here’s an example of downloading the latest translation on pull requests and pushes to branches develop (staging) and master (production)

name: Build
on: [push, pull_request]
jobs:
  localazy-download:
    if: ${{ github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' }}
    name: Download translations from Localazy
    runs-on: [linux]
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ github.head_ref }}
      - uses: localazy/download@v1
      - uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: Commit latest translations from Localazy.