Translate

Check translations in GitLab CI

The job installs the kaeris package and runs kaeris check on merge requests that touch your locale files. A lost placeholder or a missing key fails the pipeline. It is offline and free: no API key, no account.

The recipe

The job

Add it to .gitlab-ci.yml. Change --source to your base-language file and --langs to the locales you ship. The rules block runs the job only on merge requests that change something under locales/; drop the changes lines to run it on every merge request.

Config.gitlab-ci.yml
i18n-check:
  stage: test
  image: python:3.12-slim
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - locales/**/*
  script:
    - pip install kaeris
    - kaeris check --source locales/en.json --langs de,fr --ci

What it prints, on real runs

Output of kaeris 0.2.35, captured 27 October 2026. The last line of each box is the exit code the CI job sees.

What the job prints

The two script lines, run in order. Left: files that are fine. Right: de.json with {nam} instead of {name} and the checkout key missing; the job stops with exit code 1.

Files that are finejob log
$ pip install kaeris
Collecting kaeris
  Using cached kaeris-0.2.35-py3-none-any.whl.metadata (26 kB)
Using cached kaeris-0.2.35-py3-none-any.whl (131 kB)
Installing collected packages: kaeris
Successfully installed kaeris-0.2.35

$ kaeris check --source locales/en.json --langs de,fr --ci
✓ de: complete & placeholder-safe
✓ fr: complete & placeholder-safe
✓ all locales complete & placeholder-safe
Job succeeded
exit code: 0
A broken translationjob log
$ pip install kaeris
Requirement already satisfied: kaeris in C:\Users\Inzagi\AppData\Local\Temp\claude\C--Users-Inzagi-projects-kaeris\bfeebe69-3cfd-4f28-bbe7-e5600be082b9\scratchpad\venv-gl2\Lib\site-packages (0.2.35)

$ kaeris check --source locales/en.json --langs de,fr --ci
✗ de: 1 missing key(s): checkout
✗ de: 1 placeholder mismatch(es):
    greeting: missing ['{name}'], added ['{nam}']
✗ de: 2 translation fault(s):
    greeting: lost placeholder {name}
    greeting: invented placeholder {nam} (not in source)
✓ fr: complete & placeholder-safe
✗ 1 missing key, 1 placeholder mismatch, 2 translation faults
ERROR: Job failed: exit code 1
exit code: 1

Set it up in three steps

  1. Add the job

    Paste the job into .gitlab-ci.yml and set your own --source and --langs.

  2. Open a merge request

    Change a locale file on a branch and open a merge request. The job runs and shows every finding in its log.

  3. Require the pipeline

    In the project settings under merge requests, turn on that pipelines must succeed. A red job then blocks the merge.

How we checked this

Every command on this page was run before it was written here. What was not run is listed too.

Options worth knowing

Questions

Does it need an API key or an account?

No. kaeris check is described in its own help as static, local and no-API, so the job needs no secret. Translating is a separate command that does need a key.

What does the check catch?

A lost or invented placeholder ({name}, %s, {{x}}, ICU plurals), a missing key and a locale file that is not there. The comparison is local and static. What it checks, with every flag

Can I save the result as a file?

Yes: --json prints the result as JSON and --sarif PATH writes a SARIF report. Add the file under artifacts if you want to keep it. Both flags are in the help of kaeris check; we did not run an artifact upload on GitLab.

Keep going

Other recipes: GitHub Actions · pre-commit · Make and npm scripts

CLI reference · Check reference · GitHub Action reference · Free check in the browser · Translate in the browser