Advanced patterns for CI/CD localization - workflow selection, translation completeness checks, and merge conflict resolution.
Choosing a workflow#
Four workflow patterns cover most team setups. Each has different trade-offs around automation, review overhead, and branch hygiene.
| Workflow | Best for | Trade-off |
|---|---|---|
| Commit to main | Small teams, zero-friction updates | No review step for translations |
| PR from main | Teams that want to review translations | Requires manual PR approval |
| Commit to feature branch | Long-lived feature branches | Translation commits in branch history |
| PR from feature branch | Maximum control per feature | Multiple PRs per feature to manage |
On GitHub, the Lingo.dev GitHub App handles most of these patterns for you server-side - it reacts to pushes and PRs, commits translations back, and needs no runner or secret. Reach for the CLI patterns below when you run localization inside your own pipeline.
Start with "Commit to main" if you're unsure. It's the simplest workflow and prevents merge conflicts entirely since there's no branch divergence.
Checking translation completeness#
The lingo check command verifies that all content is translated without generating new translations. It exits with a non-zero status code if any content is missing:
lingo checkUse this as a deployment gate to prevent shipping untranslated content. Install the CLI with npm install -g @lingo.dev/cli (Node 22+) and authenticate the runner with a LINGO_API_KEY environment variable.
name: Check translations
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install -g @lingo.dev/cli
- run: lingo check
env:
LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}Resolving merge conflicts#
Merge conflicts occur when the .lingo/lock.json file diverges between branches - typically when translations are updated independently in different branches.
Prevention#
Committing translations directly to main (instead of using feature branches for translations) eliminates lockfile conflicts entirely.
Resolution via merge#
Start the merge
git merge <branch-name>Delete the conflicting lockfile
rm .lingo/lock.jsonComplete the merge
git add .
git merge --continueRegenerate the lockfile
lingo pushRunning lingo push rebuilds .lingo/lock.json from the current state of your source files as part of the normal sync.
Resolution via rebase#
The same approach works with rebase - delete .lingo/lock.json during each conflict step, continue the rebase, then run lingo push at the end to regenerate the lockfile:
git rebase <branch-name>
# On each conflict: rm .lingo/lock.json && git add . && git rebase --continue
lingo push