Translate your source files with Private Translation Cloud (WPML) straight from CI — and get the results back as a self-updating pull request on every source push. PTC never touches your repo; the action runs the pinned ptc-cli in your pipeline and your own token opens the PR.
- GitHub: a composite Marketplace action —
uses: OnTheGoSystems/ptc-action@v1 - GitLab: a CI/CD Catalog component —
include: component: .../ptc-action/translate@1
The CLI is vendored and pinned at ptc-cli v1.0.0 — it is never downloaded from main at job time.
1. Get a token & config. In a checkout of your repo, run ptc init — it authenticates, detects your files, and writes .ptc-config.yml. Commit that file.
2. Add secrets. Repo → Settings → Secrets and variables → Actions:
PTC_API_TOKEN— your PTC project token (required).PTC_PR_TOKEN— (recommended) a PAT or GitHub App token so the translation PR triggers your other CI checks. A bareGITHUB_TOKEN-opened PR does not trigger downstream workflows.
3. Add the workflow — .github/workflows/translate.yml:
name: Translate
on:
push:
branches: [main]
paths: ['locales/en.json'] # trigger only on SOURCE changes → loop-safe
workflow_dispatch: {}
permissions:
contents: write
pull-requests: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: OnTheGoSystems/ptc-action@v1
with:
api-token: ${{ secrets.PTC_API_TOKEN }}
config-file: .ptc-config.yml
create-pr: true
pr-token: ${{ secrets.PTC_PR_TOKEN }}
⚠️ One-time setting forcreate-pr: enable Settings → Actions → General → "Allow GitHub Actions to create and approve pull requests". This is the #1 silent first-run failure.
Store PTC_API_TOKEN as a masked CI/CD variable, then:
include:
- component: $CI_SERVER_FQDN/OnTheGoSystems/ptc-action/translate@1
inputs:
config-file: .ptc-config.yml
open-mr: 'true'The component only runs on a push to your default branch and skips translation commits — no loops.
| Input | Required | Default | Description |
|---|---|---|---|
api-token |
✅ | — | PTC project token. Passed via the PTC_API_TOKEN env var, never argv. |
config-file |
'' |
Path to .ptc-config.yml. Takes precedence over source-locale/patterns. |
|
source-locale |
'' |
Source language code (with patterns). |
|
patterns |
'' |
Glob(s) with a {{lang}} slot. |
|
file-tag-name |
auto | PTC file tag (defaults to the git branch). | |
api-url |
https://app.ptc.wpml.org/api/v1/ |
Override for staging / self-hosted. | |
project-dir |
. |
Directory treated as project root. | |
create-pr |
false |
Open/update a PR with the translations. | |
pr-token |
${{ github.token }} |
Token that opens the PR (use a PAT/App token to trigger downstream CI). | |
pr-branch |
ptc/translations |
Stable branch — re-runs update the same PR. |
| Output | Description |
|---|---|
pr-number |
The PR number (when create-pr=true and there were changes). |
pr-url |
The PR URL. |
- Trigger on source paths only (
paths:/ default-branch rule) — a translation-only commit can never re-trigger the run. - Stable
ptc/translationsbranch — re-runs update ONE PR instead of spawning new ones. [skip translations]marker on translation commits as a second guard.- PR token is explicit so the translation PR actually runs your repo's own checks.
- The PTC token is read from an env var and
::add-mask::ed — it never appears inargvor logs. - The CLI is vendored + pinned; pin the action itself to a full SHA if your org requires it.