GitHub Action

Translatize Sync wraps the Translatize CLI so you can keep your repository and your Translatize project in sync from CI – push new source keys, pull completed translations, and gate pull requests on missing or changed strings.

What it does

The action runs a single Translatize CLI command inside your workflow:

CommandWhat it does
pushUploads source keys from your repo to the token branch.
pullDownloads translations from the token branch into your local files.
statusReports the diff between repo and branch; can fail the job on missing or changed strings.

It authenticates with a branch-bound API token (mcni_...), which the action passes to the CLI as the TRANSLATIZE_API_TOKEN environment variable. A token carries a base branch, so most workflows never set a branch at all. A token whose scope is create-own may additionally target branches it created – pass --branch <name> through args (or set branch in the config) to sync one.

Under the hood the step runs:

npx --yes @translatize/cli@<version> <command> --config <config> [--api-url <api-url>] <args>

status follows the CLI exit-code contract – 0 on success; 1 when a --fail-on-* gate trips or an API/execution error occurs (for example an expired token); 2 on a usage or configuration error – so a failed check fails the job.

Quickstart

  1. Create a token. In Translatize, open Project Settings → Integrations and create an API token. Pick the branch it should be bound to (for example main). Copy the mcni_... value – it is shown only once.
  2. Store it as a secret. In your GitHub repo, go to Settings → Secrets and variables → Actions → New repository secret, name it TRANSLATIZE_TOKEN, and paste the token.
  3. Commit your config. Add a translatize.config.json at the repo root – the same file the CLI reads locally. See the CLI documentation for its schema.
  4. Add a workflow. Start with the status gate below, then add push and pull.
.github/workflows/translatize.yml
name: Translatize
on: [workflow_dispatch]
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: translatize/sync-action@v1
        with:
          command: status
          token: ${{ secrets.TRANSLATIZE_TOKEN }}

Workflow recipes

Push new source keys on every push to main

Whenever your source strings change on main, upload the new keys to Translatize so translators can start working.

.github/workflows/push-keys.yml
name: Push source keys to Translatize

on:
  push:
    branches: [main]
    paths:
      - 'locales/en.json'
      - 'src/**/*.json'

jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Push source keys
        uses: translatize/sync-action@v1
        with:
          command: push
          token: ${{ secrets.TRANSLATIZE_TOKEN }}

Nightly translation pull that opens a pull request

Pull finished translations every night and open a PR with the changes, so a human reviews and merges them.

.github/workflows/nightly-pull.yml
name: Nightly translation pull

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write

jobs:
  pull:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Pull latest translations
        uses: translatize/sync-action@v1
        with:
          command: pull
          token: ${{ secrets.TRANSLATIZE_TOKEN }}

      - name: Open a pull request
        uses: peter-evans/create-pull-request@v7
        with:
          commit-message: 'chore(i18n): sync translations from Translatize'
          title: 'Update translations from Translatize'
          body: 'Automated nightly translation sync from the Translatize branch bound to TRANSLATIZE_TOKEN.'
          branch: chore/translatize-sync
          labels: i18n, automated
Permissions
create-pull-request needs the contents: write and pull-requests: write permissions shown above. If the PR step fails to open a PR, also enable Settings → Actions → General → Allow GitHub Actions to create and approve pull requests.

Block a PR when translations are missing

Run status --fail-on-missing on pull requests so a PR that adds untranslated source keys turns the check red until translations land.

.github/workflows/status-gate.yml
name: Translation status gate

on:
  pull_request:
    branches: [main]

jobs:
  status:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Fail if translations are missing
        uses: translatize/sync-action@v1
        with:
          command: status
          token: ${{ secrets.TRANSLATIZE_TOKEN }}
          args: --fail-on-missing
Swap --fail-on-missing for --fail-on-diff to instead fail when a source string changed but its translations were not updated. Pass both to enforce either condition.

Inputs

InputRequiredDefaultDescription
commandyesCLI command to run: pull, push, or status. Any other value fails the step.
tokenyesBranch-bound Translatize API token (mcni_...). Passed to the CLI as TRANSLATIZE_API_TOKEN. Use a secret.
versionnolatest@translatize/cli npm version to run (for example 0.1.0).
confignotranslatize.config.jsonPath to the CLI config file, relative to the workspace.
api-urlno""Override the Translatize API base URL (self-hosted / staging). Empty uses the CLI default.
argsno""Extra CLI flags appended verbatim, e.g. --dry-run, --json, --fail-on-missing, --fail-on-diff.
node-versionno20Node.js version used to run the CLI.

This action has no outputs – surface results through the step exit status (a red check) and the CLI --json output in the logs.

Setting up the token secret

Tokens are created in Project Settings → Integrations at app.translatize.com and are prefixed mcni_. Store the value as a repository (or environment/organization) secret named TRANSLATIZE_TOKEN and reference it as token: ${{ secrets.TRANSLATIZE_TOKEN }}. Never paste the raw token into a workflow file.

A token carries its own role (translator can write translations; developer, admin, and owner can also create source keys) and may be IP-allowlisted or given an expiry – set these to match what the workflow needs.

One token per branch

Each API token has a base branch, chosen when you mint it. A standard (fixed-scope) token may act only on that branch, so naming a different one is rejected by the API – the branch is decided by the token, not the workflow. A create-own-scope token is the exception: it may also target branches it created, selected with --branch via args or the config branch field. Teams that sync several branches with fixed-scope tokens typically create one token per branch – a main-bound token for the workflows on main, and a separate token bound to staging stored as a second secret. Rotate a token by creating a new one and updating the secret; revoking the old token in Translatize invalidates it immediately.

Publishing status

Published on the GitHub Marketplace
The action is live on the GitHub Marketplace, with its source at github.com/Translatize/sync-action. Reference it as uses: translatize/sync-action@v1, exactly as the examples above do.

You can also consume the action without the Marketplace: copy the github-action/ folder into your repository (for example to .github/actions/translatize) and reference it by path with uses: ./.github/actions/translatize, or fork it into a repo you control and pin to a tag or commit SHA. Both take the same inputs as the Marketplace version.