Automate translations in CI
Keep pull requests fast, let development builds update translations, and keep production releases deliberate.
Pull request
Check the app and find new text
Development build
Send new text for translation
Production release
Review and publish the selected languageGitHub Actions example
Pull requests do not need a project token. The development job runs only on main and receives its token from a protected CI environment.
name: Linguana
on:
pull_request:
push:
branches: [main]
jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
LINGUANA_UPLOAD: "false"
LINGUANA_TRANSLATE: "false"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14
- run: bun install --frozen-lockfile
- run: bun run check-types
- run: bun run docs:verify
- name: Snapshot source
run: bun run source:before
- name: Extraction-only build
run: bun run build
- name: Verify source integrity
run: bun run source:after
- uses: actions/upload-artifact@v4
with:
name: linguana-manifest
path: .linguana/manifest.json
if-no-files-found: error
retention-days: 14
translate-development:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: validate
runs-on: ubuntu-latest
timeout-minutes: 15
environment: linguana-development
env:
LINGUANA_API_URL: ${{ vars.LINGUANA_API_URL }}
LINGUANA_PROJECT_TOKEN: ${{ secrets.LINGUANA_PROJECT_TOKEN }}
LINGUANA_UPLOAD: "true"
LINGUANA_TRANSLATE: "true"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14
- run: bun install --frozen-lockfile
- name: Upload and translate development catalog
run: bun run buildConfigure the plugin with an explicit charge and wait ceiling:
translation: process.env.LINGUANA_PROJECT_TOKEN &&
process.env.LINGUANA_TRANSLATE !== "false"
? {
enabled: true,
maxChargeMicros: 100_000,
waitTimeoutMs: 300_000,
publish: "development",
}
: undefined,Other CI providers
Use the same stage boundaries:
export LINGUANA_UPLOAD=false
export LINGUANA_TRANSLATE=false
bun install --frozen-lockfile
bun run check-types
bun run docs:verify
bun run source:before
bun run build
bun run source:aftertest -n "$LINGUANA_PROJECT_TOKEN"
export LINGUANA_UPLOAD=true
export LINGUANA_TRANSLATE=true
bun run buildKeep credentials private
| Value | Store | Browser-safe? |
|---|---|---|
LINGUANA_PROJECT_TOKEN | Protected CI environment secret | No |
| Provider API key | Translation service secret store | No |
VITE_LINGUANA_API_URL | Build/public variable | Yes |
| Publishable catalog key | Public runtime configuration | Yes |
Do not print environment values, authorization headers, source bodies, or translated bodies. Retain the manifest artifact, manifest hash, job IDs, request IDs, and redacted logs.
If something fails
Keep the error code, translation-run ID, and request ID from the build logs. Check an existing run before retrying so you do not start the same translation twice.
The build integration updates development languages only. Production remains an explicit dashboard action after review.
Next
Test the setup with Test your integration, then complete the production checklist.
Keep pull requests fast, update development languages, and keep production releases deliberate.
Last updated October 3, 2026
Did this page get you to a working result?