---
title: "GitHub Actions"
subtitle: "AI translation with GitHub Actions and Lingo.dev CI/CD"
---
## What is GitHub Actions?
[GitHub Actions](https://docs.github.com/en/actions) is a CI/CD and automation platform built into GitHub. It lets users define workflows in YAML files to build, test, and deploy code or automate tasks triggered by repository events.
## What is Lingo.dev CI/CD?
[Lingo.dev CI/CD](/ci) is an AI-powered tool for localizing apps and content in CI/CD, ensuring translations never fall out of date. For GitHub, Lingo.dev provides a custom GitHub Action that simplifies integration.
## About this guide
This guide explains how to set up **Lingo.dev CI/CD** with the Lingo.dev GitHub Action and [Lingo.dev Engine](/app).
## Step 1. Set up Lingo.dev CLI
To begin, follow the [Quickstart](/cli/quick-start) for **Lingo.dev CLI**.
You should end up with:
- an API key for **Lingo.dev**
- an `i18n.json` file that configures the behavior of a translation pipeline
- the ability to translate content with `npx lingo.dev@latest run`
## Step 2. Configure a repository secret
1. Navigate to **Settings > Secrets and variables > Actions**.
2. Click **New repository secret**.
3. In the **Name** field, enter `LINGODOTDEV_API_KEY`.
4. In the **Secret** field, enter a Lingo.dev API key.
5. Click **Add secret**.
## Step 3. Choose a workflow
You can set up **Lingo.dev CI/CD** in different ways to support different workflows. These are some of the workflows that we recommend (and provide examples for):
- When content is merged into `main`, commit translations to `main`
- When content is merged into `main`, create a pull request from `main`
- When content is merged into a feature branch, commit translations to the branch
- When content is merged into a feature branch, create a pull request from the branch
But there is no "best" workflow. They all have trade-offs. If you're not sure where to begin, we recommend starting with with the first option. It's the simplest, most invisible workflow.
## Step 4. Set up the workflow
1. In the repo, create a `.github/workflows` directory:
```bash
mkdir -p .github/workflows
```
Be sure to include the `.` at the start of `.github`.
2. In the `.github/workflows` directory, create a YAML file:
```bash
touch .github/workflows/translate.yml
```
The name of the file is not important.
3. Copy one of the [example workflows](#workflow-examples) into the file.
4. If the workflow creates pull requests:
1. Navigate to **Settings > Actions > General**.
2. Enable **Allow GitHub Actions to create and approve pull requests**.
3. Click **Save**.
4. Commit and push the changes to the `main` branch:
```bash
git add .github/workflows/translate.yml
git commit -m "feat: GitHub action for Lingo.dev"
git push
```
## (Optional) Step 5. Customize the workflow
**Lingo.dev CI/CD** has default values that, in most cases, don't need to be customized. You can override them by passing inputs to the GitHub Action:
**Available inputs:**
- `version`: Lingo.dev CLI version (default: `"latest"`)
- `api-key`: Lingo.dev Platform API Key (required)
- `pull-request`: Create a pull request with changes (default: `false`)
- `commit-message`: Custom commit message (default: `"feat: update translations via @LingoDotDev"`)
- `pull-request-title`: Custom pull request title (default: `"feat: update translations via @LingoDotDev"`)
- `commit-author-name`: Git commit author name (default: `"Lingo.dev"`)
- `commit-author-email`: Git commit author email (default: `"support@lingo.dev"`)
- `working-directory`: Working directory (default: `"."`)
- `process-own-commits`: Process commits made by this action (default: `false`)
- `parallel`: Run in parallel mode (default: `false`)
- `gpg-sign`: Enable GPG commit signing (default: `false`). See [GPG commit signing](#gpg-commit-signing) below.
**Example with custom inputs:**
```yml
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
commit-message: "My custom commit message!"
parallel: true
```
## Example workflows
### Commit to main
When content is merged into `main`, commit translations to `main`.
```yml
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
```
[View on GitHub](https://github.com/lingodotdev/example-github-action-main-commit)
### Pull request from main
When content is merged into `main`, create a pull request from `main`.
```yml
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
pull-request: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
[View on GitHub](https://github.com/lingodotdev/example-github-action-main-pull-request)
### Commit to feature branch
When content is merged into a feature branch, commit translations to the branch.
```yml
name: Translate
on:
push:
branches-ignore: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
```
[View on Github](https://github.com/lingodotdev/example-github-action-feature-branch-commit)
### Pull request from feature branch
When content is merged into a feature branch, create a pull request from the branch.
```yml
name: Translate
on:
push:
branches-ignore: [main]
permissions:
contents: write
pull-requests: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
pull-request: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
[View on GitHub](https://github.com/lingodotdev/example-github-action-feature-branch-pull-request)
## GPG commit signing
If your repository requires signed commits (branch protection rules), add the GPG import step before the Lingo.dev action:
```yml
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
git_user_signingkey: true
git_commit_gpgsign: true
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
gpg-sign: true
```
Store your base64-encoded GPG private key as `GPG_PRIVATE_KEY` in repository secrets. If your key has no passphrase, omit the `passphrase` line.