Skip to content
Skip to Content

Docs / Guides

Run verbatra in CI

Fail a pull request on translation drift, broken values or unreviewed machine output, and translate on a push, with the CLI in any CI system.

Use this guide when a pipeline should catch locale files that drifted from the source, or should translate them for you on a push. Every step runs the same CLI you run locally, so it works in any CI system; the examples use GitHub Actions.

Before you start, you need:

  • @verbatra/cli as a dev dependency, with your lockfile committed. The CLI needs Node ^22.22.0 || >=24.
  • A committed config, locale files and verbatra.lock.json.
  • For translating only: the API key of your provider in the CI secret store.

If you use GitHub Actions and want annotations and a job summary without writing the job yourself, use the GitHub Action instead.

Add a drift gate

verbatra check compares the source, the target files and the lock file, and exits 1 when a locale has missing or stale keys. It calls no provider, so the job needs no key and runs on pull requests from forks:

.github/workflows/i18n.yml
name: i18n
on: pull_request

permissions:
  contents: read

jobs:
  check-translations:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<commit-sha>
      - uses: pnpm/action-setup@<commit-sha>
      - uses: actions/setup-node@<commit-sha>
        with:
          node-version: 22
      - run: pnpm install --frozen-lockfile
      - run: pnpm exec verbatra check

Swap check for verbatra diff when you want the key names behind the drift, for example to post them in a pull request comment. It exits 1 on the same condition; orphaned keys show up in its output but never fail it on their own.

To gate only some locales, pass --locales de,fr. A --locales value naming a locale you have not configured exits 2, even next to valid ones, so a typo never turns the gate green.

Gate on translation quality

Drift is not the only failure worth catching. Add --qa to also run the integrity gate and the review flags over every committed translation, so a hand-edited value with a broken placeholder, broken markup or unfit ICU plural arms fails the job:

verbatra check --qa
  • Add --strict to fail on review warnings and missing plural categories too.
  • In an edit hook, verbatra check --file <path> checks one locale file on its own.

See the quality check and One file. The GitHub Action runs the same gate with qa: "true".

Gate on review decisions

Add --require-reviewed to fail while any machine-written translation is not approved in the committed verbatra.provenance.json, the file Studio's Review queue and the MCP review tools write to:

verbatra check --require-reviewed

It needs no key either. See Require reviewed translations for the codes it reports.

Translate on a push

Run verbatra translate and map the provider key from your secret store into the step's environment. The CLI takes no key argument and reads no key from the config; Providers lists the variable each provider reads.

      - run: pnpm exec verbatra translate --json
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
  • The step writes locale files into the checkout and stops there. Add your own step that commits them or opens a pull request, and grant contents: write or pull-requests: write to that job only.
  • To preview first, run verbatra translate --dry-run or --estimate: neither calls a provider nor needs a key. See Estimating cost.
  • Against a rate-limited provider, translate one locale per step with --locales.

Preflight with doctor

Put verbatra doctor before either job to fail early on a broken setup. It checks the config, the format, the provider, the key variable, the network policy, the source file and locale support, and never calls a provider or reads a key value. It does report an unset key variable as a failed check, so map the key into any job where that check has to pass.

Exit codes

Branch on the exit code, never on the text. What each code means, with its edge cases, is on Exit codes and JSON output; an error code in the output is explained on Error codes.

JSON output

Pass --json for one envelope per record on stdout. Its fields are on Exit codes and JSON output, and each command's result is on its command page. Script verbatra with JSON has recipes that parse it.

Keys and installs

  • Install with pnpm install --frozen-lockfile or npm ci, so the job runs the exact @verbatra/cli release your lockfile records.
  • Keep secrets out of jobs that never call a provider: check, diff, report, export, import, extract, pseudo, types and tmx.
  • In CI, rely on env:. Which commands also load .env.local and .env is on Environment files.
Edit on GitHub

On this page