Lingo.dev GitLab Integration
Lingo.dev GitLab CI/CD Integration is a secure, open-source CI/CD integration that automatically localizes new content and prevents incomplete translations from reaching production. It creates merge requests or commits directly to your branch, depending on your team's workflow requirements.
It also implements automatic conflict resolution through rebasing, so your translations stay synchronized with your code without manual intervention.
The integration supports multiple workflow scenarios:
- Direct commits to branches when content changes are pushed
- Merge requests targeting branches for translation updates
Upon completion this guide, you will:
- Set up automated localization triggered by code pushes;
- Configure secure authentication using repository variables;
- Choose between direct commits or merge request workflows;
- Understand how continuous localization fits into your existing process.
Let's begin!
Prerequisites
Repository Setup
Your repository must have Lingo.dev CLI configured with a valid i18n.json
file. If you haven't set this up yet, complete the CLI quickstart first.
Step 1. Authentication Setup
Lingo.dev GitLab Integration needs access to your translation engine and repository. Authentication happens through repository variables that keep your credentials secure.
Add Your API Key
Navigate to your repository Settings → CI/CD → Variables, then add your translation engine credentials:
For raw LLM API users:
- Variable name:
OPENAI_API_KEY
orANTHROPIC_API_KEY
- Variable value: Your API key from the respective provider
For Lingo.dev Engine users:
- Variable name:
LINGODOTDEV_API_KEY
- Variable value: Your project API key from lingo.dev/app
Add GitLab Access Token
Create a custom access token for repository operations:
- Go to Settings → Access tokens → Add new token
- Grant these scopes:
api
read_repository
write_repository
- Add the token as a repository variable:
- Variable name:
GL_TOKEN
- Variable value: Your GitLab access token
- Variable name:
Important: The default CI job token is not sufficient. You must create a custom access token as the default token lacks necessary permissions for git operations.
Note: For protected branches, make sure your variables are also marked as protected. Unprotected variables won't be accessible in protected branch pipelines.
Step 2. Create the Workflow
Create or update your .gitlab-ci.yml
file with this basic configuration:
lingodotdev:
image: lingodotdev/ci-action:latest
script:
- echo "Done"
This configuration uses the latest Docker image and runs the translation engine automatically.
Required Permissions
GitLab CI/CD requires access to repository variables and git operations:
Repository Variables:
LINGODOTDEV_API_KEY
— Required for Lingo.dev Engine usersOPENAI_API_KEY
orANTHROPIC_API_KEY
— Required for raw LLM API usersGL_TOKEN
— Required for git push operations and merge request creation
Access Token Scopes:
api
— Create and manage merge requestsread_repository
— Access repository contentwrite_repository
— Push commits and create branches
These permissions allow the integration to read your content, generate translations, and update your repository with the localized content.
Step 3. Choose Your Workflow Mode
Lingo.dev GitLab Integration supports two operational modes depending on your team's code review requirements.
Direct Commit Mode (Default)
The integration commits translations directly to your branch:
lingodotdev:
image: lingodotdev/ci-action:latest
script:
- echo "Done"
This mode works best for:
- Solo developers or small teams
- Feature branches that will be reviewed before merging
- Projects where translation updates don't require separate review
Merge Request Mode
The integration creates merge requests for translation updates:
lingodotdev:
image: lingodotdev/ci-action:latest
variables:
LINGODOTDEV_PULL_REQUEST: "true"
script:
- echo "Done"
Required Setup for Merge Request Mode
Repository Variables:
Both LINGODOTDEV_API_KEY
and GL_TOKEN
must be configured as repository variables.
Access Token Requirements:
Your GL_TOKEN
must include the api
scope to create and manage merge requests.
This mode works best for:
- Teams with strict code review requirements
- Projects where translation changes need separate approval
- Workflows that require explicit review of all changes
Step 4. Workflow Scenarios
Lingo.dev GitLab Integration adapts to different development workflows. Understanding these scenarios helps you choose the right configuration for your team.
Scenario 1: Feature Branch Updates (Direct Commits)
Trigger: Push to feature branches Action: Commits translation updates directly to the feature branch
lingodotdev:
image: lingodotdev/ci-action:latest
script:
- echo "Done"
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH = /^feat/
Flow: Content changes pushed to feature branch → Integration commits translations to the same branch
This keeps translation updates within the feature branch, ensuring translations are reviewed alongside the original changes.
Scenario 2: Merge Requests for Updates (Merge Request Mode)
Trigger: Push to any configured branch Action: Creates merge request with translation updates
lingodotdev:
image: lingodotdev/ci-action:latest
variables:
LINGODOTDEV_API_KEY: $MY_LINGODOTDEV_API_KEY # or OPENAI_API_KEY/ANTHROPIC_API_KEY
LINGODOTDEV_PULL_REQUEST: "true"
LINGODOTDEV_PULL_REQUEST_TITLE: "feat: update translations"
script:
- echo "Done"
Flow: Content changes pushed to branch → Integration creates merge request with translations
This maintains separate reviews for translation updates.
Advanced Configuration
Customize the integration behavior using additional variables:
Example with Lingo.dev Engine:
lingodotdev:
image: lingodotdev/ci-action:latest
variables:
LINGODOTDEV_API_KEY: $MY_LINGODOTDEV_API_KEY
GL_TOKEN: $MY_GL_TOKEN
LINGODOTDEV_PULL_REQUEST: "true"
LINGODOTDEV_PULL_REQUEST_TITLE: "feat: update translations"
LINGODOTDEV_COMMIT_MESSAGE: "feat: update translations via @lingodotdev"
LINGODOTDEV_WORKING_DIRECTORY: "apps/web"
LINGODOTDEV_PROCESS_OWN_COMMITS: "true"
script:
- echo "Done"
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH = /^feat/
Example with raw LLM API:
lingodotdev:
image: lingodotdev/ci-action:latest
variables:
OPENAI_API_KEY: $MY_OPENAI_API_KEY # or ANTHROPIC_API_KEY
GL_TOKEN: $MY_GL_TOKEN
LINGODOTDEV_PULL_REQUEST: "true"
LINGODOTDEV_PULL_REQUEST_TITLE: "feat: update translations"
LINGODOTDEV_COMMIT_MESSAGE: "feat: update translations via @lingodotdev"
LINGODOTDEV_WORKING_DIRECTORY: "apps/web"
LINGODOTDEV_PROCESS_OWN_COMMITS: "true"
script:
- echo "Done"
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH = /^feat/
Configuration options:
LINGODOTDEV_API_KEY
— Your Lingo.dev Engine API key, if you're using Lingo.dev EngineOPENAI_API_KEY
— Your OpenAI API key, if you're using raw LLM APIANTHROPIC_API_KEY
— Your Anthropic API key, if you're using raw LLM APILINGODOTDEV_PULL_REQUEST
— Create merge request instead of direct commit (default:false
)LINGODOTDEV_PULL_REQUEST_TITLE
— Custom merge request title (default:feat: update translations via @lingodotdev
)LINGODOTDEV_COMMIT_MESSAGE
— Custom commit message (default:feat: update translations via @lingodotdev
)LINGODOTDEV_WORKING_DIRECTORY
— Run the integration in a subdirectory (default:.
)LINGODOTDEV_PROCESS_OWN_COMMITS
— Process commits made by this integration (default:false
)
Troubleshooting
Common errors and their solutions:
Error | Solution |
---|---|
remote: HTTP Basic: Access denied | Add the GL_TOKEN variable in your CI/CD settings |
GitbeakerRequestError: Forbidden | Your GitLab token is missing the api scope |