CI/CD Integration
koto is built for CI/CD. Translate on every PR, enforce quality gates, and keep locale files in sync without manual effort.
GitHub Actions
Basic setup
Create .github/workflows/translate.yml:
name: Translate
on: push: branches: [main] paths: - 'src/locales/en.json' - 'src/locales/en/**' - 'koto.config.ts'
jobs: translate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4 with: node-version: 20 cache: pnpm
- run: pnpm install --frozen-lockfile
- run: npx koto translate --fail-on-error env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: 'chore(i18n): update translations'Using the koto GitHub Action
For a simpler setup, use the official action:
- uses: koto-i18n/koto@v1 with: provider: openai api_key: ${{ secrets.OPENAI_API_KEY }} locales: es,fr,de,ja fail_on_error: truePR workflow
Translate on pull requests and commit the results back to the PR branch:
name: Translate PR
on: pull_request: paths: - 'src/locales/en.json' - 'src/locales/en/**'
jobs: translate: runs-on: ubuntu-latest permissions: contents: write
steps: - uses: actions/checkout@v4 with: ref: ${{ github.head_ref }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4 with: node-version: 20 cache: pnpm
- run: pnpm install --frozen-lockfile
- run: npx koto translate env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: 'chore(i18n): update translations'GitLab CI
translate: stage: build image: node:20 rules: - changes: - src/locales/en.json - src/locales/en/**/* - koto.config.ts before_script: - corepack enable - pnpm install --frozen-lockfile script: - npx koto translate --fail-on-error variables: OPENAI_API_KEY: $OPENAI_API_KEYGeneric CI
koto works in any CI environment with Node.js:
npx koto translate --fail-on-errorThe --fail-on-error flag causes koto to exit with code 1 if:
- Any translation fails
- Quality score drops below the configured threshold
- Any source key is missing a translation
Quality gates
Set a quality threshold in your config, then use --fail-on-error to enforce it:
quality: { threshold: 90, // Fail if any translation scores below 90/100}If translations fall short, koto reports the failures and exits non-zero:
Diff check in CI
Use koto diff to verify translations are up to date without running a full translation:
npx koto diff --json | jq '.pending' | grep -q '0' || exit 1Caching in CI
koto uses koto-lock.json for incremental translation. Commit this file so CI runs only translate new or changed keys.
To also cache the translation cache directory between CI runs:
# GitHub Actions- uses: actions/cache@v4 with: path: node_modules/.cache/koto key: koto-cache-${{ hashFiles('koto-lock.json') }} restore-keys: | koto-cache-Environment variables
Set your provider’s API key as a CI secret:
| CI Platform | Where to set secrets |
|---|---|
| GitHub Actions | Settings > Secrets and variables > Actions |
| GitLab CI | Settings > CI/CD > Variables |
| CircleCI | Project Settings > Environment Variables |
| Jenkins | Credentials Manager |