Skip to content
Skip to Content

Docs / Guides

Use the GitHub Action

Run verbatra in GitHub Actions with the composite action: translate on a push or gate a pull request, with annotations and a job summary.

Use the action to run verbatra in a GitHub Actions job and see what happened. It runs translate, check or diff with --json; for any other command or flag, such as --prune, run the CLI directly.

Before you start, you need:

  • A verbatra config directly inside the directory the action runs in (see Config discovery).
  • An exact @verbatra/cli version to pin, 0.9.3 or newer.
  • For translate only: your provider's API key as a repository secret.
  • Actions Runner v2.327.1 or newer, and verbatra/action v1.3.0 or newer, which this page describes and qa, require-reviewed, sensitive, locales and needs-human need.

Add the action to a workflow

The action lives in verbatra/action and on the GitHub Marketplace; there is no npm package. Pin it to a commit SHA, as below, or use the moving verbatra/action@v1 tag. The old mariokreitz/verbatra/packages/github-action path no longer resolves.

.github/workflows/translate.yml
name: translate
on:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  verbatra:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<commit-sha>
      - uses: verbatra/action@<commit-sha> # a commit on the v1 line
        with:
          version: 0.12.0 # an exact @verbatra/cli release, 0.9.3 or newer
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

The action installs @verbatra/cli and @verbatra/sdk at exactly that version into a scratch directory, leaving your dependencies untouched, so the job needs no install step.

Pass the provider key

Map the key from your repository secrets under the variable your provider reads; Providers lists them. The action has no key input, so a key never travels as an input or a CLI argument.

Gate a pull request

Set command: check to fail a pull request whose locale files drifted, or command: diff to list the pending keys as well. Both are read-only and call no provider, so they need no key and run on fork pull requests:

      - uses: verbatra/action@<commit-sha> # a commit on the v1 line
        with:
          version: 0.12.0
          command: check

Checking translation quality

Add qa: "true" to command: check to run verbatra check --qa over every committed translation, including values typed by hand.

      - uses: verbatra/action@<commit-sha> # a commit on the v1 line
        with:
          version: 0.12.0
          command: check
          qa: "true"
  • Each finding becomes one annotation titled verbatra qa: <locale>: an error for a value the integrity gate would refuse, a warning for a review reason.
  • The step fails on any error finding. Add qa-strict: "true" to fail on warnings and incomplete plurals too, or qa-severity: error to report errors only. The CLI rejects both together.

Require reviewed translations

Add require-reviewed: "true" to command: check to run verbatra check --require-reviewed. The step fails while a machine-written translation is not approved in the committed verbatra.provenance.json, where Studio records review decisions. It stays read-only and keyless and combines with qa.

      - uses: verbatra/action@<commit-sha> # a commit on the v1 line
        with:
          version: 0.12.0
          command: check
          require-reviewed: "true"
  • Each locale with unapproved keys gets one REVIEW_REQUIRED error annotation naming them, and the job summary adds an unreviewed column.
  • A verbatra.provenance.json that is corrupt or from a newer verbatra fails the gate with one REVIEW_STATE_UNREADABLE annotation.

Pick locales and scan sources

Set locales to a comma-separated list such as de,fr to limit any command to those locales.

      - uses: verbatra/action@<commit-sha> # a commit on the v1 line
        with:
          version: 0.12.0
          command: check
          locales: "de,fr"

Sensitive content

Add sensitive: "true" to command: check to run verbatra check --sensitive. The step fails when the source file or glossary holds content a sensitiveData detector or pattern matches, such as emails, keys or card numbers, and annotates each affected key without printing the match. An older version, or a 0.12.0-next.* prerelease, fails the step before anything is installed.

Human-only mode

With provider: { id: "none" } (see Human-only workflow), translate exits 3 when it leaves keys for a person. The action treats that as work to hand off, not a failure: the step passes, each affected locale gets a NEEDS_HUMAN warning, the job summary lists the keys, and the needs-human output is "true". Branch on it:

      - uses: verbatra/action@<commit-sha> # a commit on the v1 line
        id: verbatra
        with:
          version: 0.12.0
      - if: steps.verbatra.outputs.needs-human == 'true'
        run: echo "Some keys need a human translation; see the job summary."

Only translate gets this; check and diff never exit 3, so a failure from them still fails the step.

Config discovery

With config-path empty, the action requires a recognized config file directly inside working-directory (the repository root by default). It never looks in a parent directory, so in a monorepo point working-directory at the app and keep its config there:

      with:
        version: 0.12.0
        working-directory: apps/docs

If no config is found, the step fails before installing the CLI and names the directory it checked. To load a config from elsewhere, set config-path: a relative path resolves against working-directory.

Persist translations

translate writes the updated locale files into the runner's checkout; the action never commits. Add your own step that commits and pushes, or opens a pull request, and grant contents: write or pull-requests: write to that job only.

Inputs

InputDefaultEffect
versionrequiredexact @verbatra/cli release to run, 0.9.3 or newer; a dist-tag, range or ^/~ prefix fails the step
commandtranslatetranslate, check or diff; anything else fails the step
config-path""config file to load (--config); relative to working-directory
working-directory""directory to run in (--cwd); the repository root when empty
dry-run"false""true" previews without calling a provider or writing (--dry-run); translate only
qa"false""true" adds the quality check (--qa); check only
qa-severity""lowest severity to report, error or warning (--severity); requires qa
qa-strict"false""true" also fails on warnings (--strict); requires qa
require-reviewed"false""true" also fails on unapproved machine-written translations (--require-reviewed); check only
sensitive"false""true" adds the sensitive-content scan (--sensitive); check only
locales""comma-separated target locales to limit the run to (--locales)
node-version"24"Node.js version to set up. CLI 0.13.0+: 22.22.0+ on 22, 24+ (action v1.4.0: even-numbered majors only); CLI 0.12.x: `^22.18.0

The boolean inputs accept only "true" or "false". A bad boolean, or an input without the command or qa it needs, fails the step with exit 1 before the CLI install. The CLI rejects an unknown qa-severity, and qa-severity: error with qa-strict, with exit 2 after it.

Outputs

OutputValue
needs-human"true" when translate exited 3 and left keys for a person, otherwise "false"

What a run shows you

  • Annotations. Under translate with exit 1, each failed or partial locale becomes one error annotation titled verbatra: <locale>. Under check or diff, each drifted locale gets one titled verbatra check: <locale> or verbatra diff: <locale>. All of these attach to that locale's file when the action can find it. A partial locale's LOCALE_PARTIAL annotation names the withheld keys, grouped by cause. Every check adds one PLURAL_CATEGORIES_INCOMPLETE warning per locale whose plurals lack a CLDR category the language uses. With sensitive, each flagged key gets a SENSITIVE_CONTENT error annotation and a line in the summary. A run that fails as a whole gets one verbatra annotation with the error code, its cause as (cause: X) and a Next step: hint when the CLI gives them. GitHub shows at most 10 annotations per severity, so the action orders them drift, review, quality errors, warnings, and adds one notice counting the rest.
  • Job summary. One row per locale with the counts for the command that ran, an aggregate line, and the partial and failed locales. With qa it adds a findings table of up to 1000 findings; incomplete plurals get their own section.
  • Exit status. The action emits the annotations and summary first, then exits with the CLI's own exit code, except that a translate exit 3 passes and a failure before the CLI runs (no working directory, no config, a failed install) exits 1; a refused input gets one ::error::, no summary.

Security

Pin both references: uses: to a commit SHA and version to an exact release (current one on npm); the action rejects anything that could resolve latest. Inputs reach the CLI as a quoted argument array, never spliced into shell text.

Edit on GitHub

On this page