{"id":51548864,"url":"https://github.com/doloc-io/doloc-action","last_synced_at":"2026-07-09T21:30:51.580Z","repository":{"id":363904590,"uuid":"1262218352","full_name":"doloc-io/doloc-action","owner":"doloc-io","description":"GitHub Action for automatic i18n translation with doloc. Supports XLIFF, JSON, Android XML, Angular, React Intl / FormatJS, and CI checks.","archived":false,"fork":false,"pushed_at":"2026-06-10T20:43:22.000Z","size":273,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-10T22:15:05.548Z","etag":null,"topics":["android","angular","doloc","formatjs","github-action","github-actions","i18n","json","l10n","localization","react-intl","translation","xliff"],"latest_commit_sha":null,"homepage":"https://doloc.io/getting-started/frameworks/github-actions/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doloc-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-07T18:09:23.000Z","updated_at":"2026-06-10T20:36:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/doloc-io/doloc-action","commit_stats":null,"previous_names":["doloc-io/doloc-action"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/doloc-io/doloc-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doloc-io%2Fdoloc-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doloc-io%2Fdoloc-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doloc-io%2Fdoloc-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doloc-io%2Fdoloc-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doloc-io","download_url":"https://codeload.github.com/doloc-io/doloc-action/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doloc-io%2Fdoloc-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35313755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","angular","doloc","formatjs","github-action","github-actions","i18n","json","l10n","localization","react-intl","translation","xliff"],"created_at":"2026-07-09T21:30:51.517Z","updated_at":"2026-07-09T21:30:51.572Z","avatar_url":"https://github.com/doloc-io.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# doloc i18n Translation Action\n\nTranslate your i18n files directly in GitHub Actions — no translation platform required.\n\nThis action updates or checks localization files with the [doloc](https://doloc.io?utm_source=github\u0026utm_medium=gh-action\u0026utm_campaign=readme) API. It supports the same developer-first workflow as the CLI/curl examples: keep source files in your repository, run doloc when strings change, and decide yourself whether to commit, inspect, artifact, or open a pull request with the resulting diff.\n\n## Quick start\n\n1. Create a doloc API token at [doloc.io/account](https://doloc.io/account?utm_source=github\u0026utm_medium=gh-action\u0026utm_campaign=readme).\n2. Add it to your repository secrets as `DOLOC_API_TOKEN`.\n3. Pick the workflow that matches your team:\n\n| Workflow | Best fit |\n| --- | --- |\n| Commit to feature branches | Same-repository branches where translation diffs should appear in the original PR. |\n| Check translations in PRs | Local-first workflows where CI catches stale translation files. |\n| Commit after merge | Repositories that update generated translations only on the default branch. |\n| Open a translation PR | Protected branches or teams that want generated translations reviewed separately. |\n\n## Commit to feature branches\n\nFor same-repository feature branches, this is often the leanest workflow: a developer changes source text, CI commits updated translation files back to the same branch, and the existing PR shows the complete diff.\n\n```yaml\nname: Update translations\n\non:\n  push:\n    branches-ignore:\n      - main\n    paths:\n      - src/lang/en.json\n      - .github/workflows/update-translations.yml\n\npermissions:\n  contents: write\n\njobs:\n  update-translations:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - id: doloc\n        uses: doloc-io/doloc-action@v1\n        with:\n          token: ${{ secrets.DOLOC_API_TOKEN }}\n          source: src/lang/en.json\n          targets: |\n            src/lang/de.json\n            src/lang/fr.json\n\n      - name: Commit translation updates\n        if: steps.doloc.outputs.changed == 'true'\n        uses: stefanzweifel/git-auto-commit-action@v7\n        with:\n          commit_message: Update translations\n          file_pattern: src/lang/de.json src/lang/fr.json\n```\n\nThe `paths` filter intentionally watches the source file, not the generated target files. This runs the translation only when source text changed. Note, that in any case there there will only a commit when translations actually changed, so no redundant commits are created.\n\nUse this only for trusted same-repository branches. For fork PRs, secrets are not available by default.\n\n## Check mode\n\nUse `mode: check` when translations should be updated locally but verified in CI. Check mode translates into memory, compares with committed target files, and fails if any target would change.\n\n```yaml\nname: Check translations\n\non:\n  pull_request:\n\npermissions:\n  contents: read\n\njobs:\n  check-translations:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: doloc-io/doloc-action@v1\n        with:\n          token: ${{ secrets.DOLOC_API_TOKEN }}\n          mode: check\n          source: src/lang/en.json\n          targets: |\n            src/lang/de.json\n            src/lang/fr.json\n```\n\n## Commit after merge\n\nIf you do not want CI to mutate feature branches, update translations on the default branch after source text changes are merged:\n\n```yaml\non:\n  push:\n    branches:\n      - main\n    paths:\n      - src/lang/en.json\n      - .github/workflows/update-translations.yml\n```\n\nUse the same doloc and `git-auto-commit-action` steps from [Commit to feature branches](#commit-to-feature-branches). This keeps feature PRs simpler, but translation updates appear in a follow-up commit on `main`.\n\n## XLIFF example\n\n```yaml\n- uses: doloc-io/doloc-action@v1\n  with:\n    token: ${{ secrets.DOLOC_API_TOKEN }}\n    targets: |\n      src/locale/messages.de.xlf\n      src/locale/messages.fr.xlf\n```\n\nFor single-file formats such as XLIFF, the target file itself contains the translatable units, so `source` is not needed. Make sure the target language is configured inside the XLIFF file.\n\n## React Intl / FormatJS JSON example\n\n```yaml\n- uses: doloc-io/doloc-action@v1\n  with:\n    token: ${{ secrets.DOLOC_API_TOKEN }}\n    source: src/lang/en.json\n    targets: |\n      src/lang/de.json\n      src/lang/fr.json\n```\n\n## Android XML example\n\n```yaml\n- uses: doloc-io/doloc-action@v1\n  with:\n    token: ${{ secrets.DOLOC_API_TOKEN }}\n    source: app/src/main/res/values/strings.xml\n    source-lang: en\n    targets: |\n      app/src/main/res/values-de/strings.xml:de\n      app/src/main/res/values-fr/strings.xml:fr\n```\n\n## Flutter ARB example\n\n```yaml\n- uses: doloc-io/doloc-action@v1\n  with:\n    token: ${{ secrets.DOLOC_API_TOKEN }}\n    source: lib/l10n/app_en.arb\n    targets: |\n      lib/l10n/app_de.arb\n      lib/l10n/app_fr.arb\n```\n\n\n## Target mappings\n\nUse one mapping per line:\n\n```yaml\ntargets: |\n  src/lang/de.json:de\n  src/lang/fr.json:fr\n```\n\nIf each target has a different source file, use `=\u003e`:\n\n```yaml\ntargets: |\n  src/lang/en.json =\u003e src/lang/de.json:de\n  src/lang/en-GB.json =\u003e src/lang/fr.json:fr\n```\n\nThe target language suffix (`:de`) is optional when the language can be inferred from the file name or is included in the file contents (e.g. XLIFF) or when you provide `target-lang` in single-target mode.\n\n## doloc API options\n\nUse the `options` input to pass doloc API query parameters. Add one option per line:\n\n```yaml\n- uses: doloc-io/doloc-action@v1\n  with:\n    token: ${{ secrets.DOLOC_API_TOKEN }}\n    source: src/lang/en.json\n    targets: |\n      src/lang/de.json:de\n      src/lang/fr.json:fr\n    options: |\n      untranslated=no-state,needs-translation\n```\n\nYou can also pass complex DNF option values exactly as you would in a curl query string. For example, this XLIFF 1.2 setting translates units that either have no state and still equal the source text, or have the `needs-translation` state:\n\n```yaml\n- uses: doloc-io/doloc-action@v1\n  with:\n    token: ${{ secrets.DOLOC_API_TOKEN }}\n    targets: |\n      src/locale/messages.de.xlf\n    options: |\n      untranslated=no-state_target-equals-source,needs-translation\n      newState=translated\n```\n\nSee the [doloc options reference](https://doloc.io/getting-started/options/?utm_source=github\u0026utm_medium=gh-action\u0026utm_campaign=readme) for supported query parameters and format-specific option links.\n\n## Open a translation PR\n\nYou can compose this action with a pull request action to open a PR with the translation updates. This is useful when direct bot commits are blocked by branch protection rules or when you want to review generated translations separately from source text changes.\n\n```yaml\nname: Update translations\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - src/lang/en.json\n      - .github/workflows/update-translations.yml\n\npermissions:\n  contents: write\n  pull-requests: write\n\njobs:\n  update-translations:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - id: doloc\n        uses: doloc-io/doloc-action@v1\n        with:\n          token: ${{ secrets.DOLOC_API_TOKEN }}\n          source: src/lang/en.json\n          targets: |\n            src/lang/de.json\n            src/lang/fr.json\n\n      - name: Create pull request\n        if: steps.doloc.outputs.changed == 'true'\n        uses: peter-evans/create-pull-request@v8\n        with:\n          commit-message: \"Update translations\"\n          title: \"Update translations\"\n          body: \"Updated localization files using doloc.\"\n          branch: doloc/update-translations\n          delete-branch: true\n          add-paths: |\n            src/lang/de.json\n            src/lang/fr.json\n```\n\nThe fixed `branch` value updates one reusable translation PR on later workflow runs. If you intentionally want a separate PR per run, add `branch-suffix: timestamp`, but prefer the fixed branch for routine translation updates.\n\n## Try it manually\n\nManual runs are useful for a first smoke test or an occasional release refresh. Add this trigger to any update workflow:\n\n```yaml\non:\n  workflow_dispatch:\n```\n\nFor normal automation, prefer `push` or `pull_request` triggers with path filters.\n\n## Inputs\n\n| Input | Required | Default | Description |\n| --- | --- | --- | --- |\n| `token` | Yes | | doloc API token. Store it as a secret such as `DOLOC_API_TOKEN`. |\n| `source` | No | | Default source localization file. Required for JSON, ARB and Android XML target files. Unused for XLIFF. |\n| `target` | No | | Single target localization file. |\n| `targets` | No | | Multiline target mapping. |\n| `source-lang` | No | | Source language, passed as `sourceLang` to the API. |\n| `target-lang` | No | | Target language for single-target mode. |\n| `mode` | No | `update` | `update` or `check`. |\n| `options` | No | | Additional doloc API query parameters, one per line. See [doloc options](https://doloc.io/getting-started/options/?utm_source=github\u0026utm_medium=gh-action\u0026utm_campaign=readme). |\n| `fail-on-change` | No | `true` in check mode, `false` in update mode | Fail if changes are produced or would be produced. |\n\nAt least one of `target` or `targets` is required.\n\n## Outputs\n\n| Output | Description |\n| --- | --- |\n| `changed` | `true` if any target file changed or would change. |\n| `changed-files` | Newline-separated list of changed files. |\n| `processed-files` | Number of processed target files. |\n\nThe action also writes a GitHub Actions job summary with processed files and change status.\n\n## Security notes\n\n- Store the API token in GitHub Actions secrets.\n- Use `permissions: contents: read` for update/check runs that only leave local working-tree changes.\n- Add `contents: write` and `pull-requests: write` only when composing with commit or PR actions.\n\n\n## Versioning\n\nUse the moving major tag for normal workflows:\n\n```yaml\nuses: doloc-io/doloc-action@v1\n```\n\nThis action follows semantic versioning, so `v1` will always point to the latest v1 release and does not introduce breaking changes. Pinning to a specific patch version is also possible, but usually not needed.\n\n## Troubleshooting\n\n### No doloc API token was provided\n\nAdd `token: ${{ secrets.DOLOC_API_TOKEN }}` and make sure the secret exists in the repository or organization.\n\n### Target file not found\n\nCreate the target file before running the action. For JSON, \n```json\n{\n}\n``` \nis usually enough for a new target file. For Android XML or XLIFF, create a valid empty or initial localization file.\n\n### Check mode failed\n\nRun the same mapping in update mode, commit the changed files, and re-run CI.\n\n### API authentication failed\n\nCreate a new token at [doloc.io/account](https://doloc.io/account?utm_source=github\u0026utm_medium=gh-action\u0026utm_campaign=readme) and update the `DOLOC_API_TOKEN` secret.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoloc-io%2Fdoloc-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoloc-io%2Fdoloc-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoloc-io%2Fdoloc-action/lists"}