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 |
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 --frozen flag verifies that all content is translated without generating new translations. It exits with a non-zero status code if any content is missing:
npx lingo.dev@latest run --frozenUse this as a deployment gate to prevent shipping untranslated content.
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: 20
- run: npx lingo.dev@latest run --frozenResolving merge conflicts#
Merge conflicts occur when the i18n.lock 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 i18n.lockComplete the merge
git add .
git merge --continueRegenerate the lockfile
npx lingo.dev@latest lockfile --forceThis rebuilds the lockfile from the current state of your source files without triggering new translations.
Resolution via rebase#
The same approach works with rebase - delete i18n.lock during each conflict step, continue the rebase, then regenerate the lockfile at the end:
git rebase <branch-name>
# On each conflict: rm i18n.lock && git add . && git rebase --continue
npx lingo.dev@latest lockfile --force