Skip to main content

GitHub Sync

The GitHub Sync app keeps a TextSetu project and a GitHub repository in step: source strings flow into TextSetu, finished translations flow back to the repo as a pull request. Once connected, it can run automatically on every push, so localization becomes part of your normal development loop instead of a manual export/import chore.

The GitHub Sync app connected to a repository


How it works

TextSetu uses an asymmetric model, the same one used by most localization platforms:

  • Your repository owns the source. The source-language files in your repo are the single source of truth for what needs translating. Pull imports those keys into TextSetu.
  • TextSetu owns the translations. Translators work in TextSetu. Push writes the translated languages back to your repo as a pull request — your source files are never overwritten.

This split avoids edit conflicts: each side only writes what it owns.

ActionDirectionWhat movesResult
Pullrepo → TextSetusource-language keys onlykeys created/updated in TextSetu
PushTextSetu → repotranslated languages onlya pull request on your repo
Import existingrepo → TextSetusource and existing translations (one-time)keys + translations seeded

Why not two-way on everything? If both sides could overwrite the same file, a translator's edit and a developer's edit would collide. Keeping source in the repo and translations in TextSetu makes every sync a clean, one-directional move.


Prerequisites

  • A GitHub repository you can install a GitHub App on (org owner/admin on GitHub).
  • The Manage organization permission in TextSetu (to install the GitHub App at the org level) and Manage project (to connect a project).
  • Your translation files in a supported format — JSON, XLIFF, Android XML, Apple .strings, Gettext .po, YAML, and 30+ more.

The GitHub App is connected once at the organization level — manage the connected GitHub accounts from the app's org settings:

GitHub Sync organization settings showing connected GitHub accounts


Connecting a repository

New projects start with a short setup wizard that walks you through connecting and configuring in four steps, teaching what Pull and Push do as you go.

Step 1 — Connect the GitHub App

Install the TextSetu GitHub App on the repository, then choose the installation, repository, and base branch to sync with.

Setup wizard — connect the GitHub App and pick a repository and branch

  1. Click Install / configure GitHub App — this opens GitHub in a new tab. Grant the app access to the repositories you want to sync, then come back and click Refresh installations.
  2. Pick the installation (your GitHub org/account).
  3. Pick the repository.
  4. Pick the base branch (usually main) — this is the branch Pull reads from and Push targets.

Step 2 — Configure sync rules

A sync rule connects files in your repo to TextSetu. Each rule has two clearly labelled halves and a file format:

Setup wizard — a sync rule showing Pull source and Push target with live flow diagrams

  • File format — how these files are stored (e.g. JSON (Nested), Android XML).
  • Pull · source (en) — select your source file or folder. Use Browse… to pick it from the repo tree; TextSetu derives the pattern for you. On Pull, keys are imported from these files as your source language — only source keys, never translations.
  • Push · target (fr, de, …) — where translations are written. Use the {lang} token for the language code; one pattern covers every target language. On Push, TextSetu opens a pull request writing your translated languages; your source files are never touched.

Each half shows a small flow diagram built from your real paths and languages, so you can see exactly what the rule will move before you commit.

Browse… opens a picker of your repo's file tree so you can select the source file directly instead of typing a pattern:

Browsing the repository file tree to pick the source language file

Add another rule if your strings live in several places or formats. If a picked file's extension doesn't match the selected format, TextSetu shows a warning so you can fix the file or the format.

Patterns and tokens. The source pattern is a glob (e.g. locales/en/*.json). The translation pattern uses tokens that expand per language. See Sync rules & file patterns below for the full list.

If your repo already contains translations (not just source), turn on the one-time import existing translations option.

Setup wizard — the one-time import existing translations option

This seeds your project with everything already in the repo — your source and any fr, de, … files it finds — and auto-adds the discovered languages to the project. It runs once; after that, TextSetu owns the translations and ordinary Pulls import only source strings.

Step 4 — Finish

Review the summary and choose whether pushes to your branch should trigger a Pull automatically, then click Connect repository.

Setup wizard — review and the Auto-pull on push option

  • Auto-pull on push — when on, a push to your base branch on GitHub automatically triggers a Pull into TextSetu (see Automatic sync).

Once connected, the page switches to the management view.


Sync rules & file patterns

A rule's source pattern is a glob that selects the source-language files to read on Pull. The translation pattern is a template that, per target language, resolves to the file Push writes.

Available tokens in the translation pattern:

TokenExpands toExample (fr)
{lang}Language code as configuredfr, pt-BR
{locale}Language code with a hyphen regionpt-BR
{locale_underscore}Language code with an underscore regionpt_BR
{two_letters}Base two-letter codefr, pt
{android_code}Android resource qualifierfr, pt
{osx_locale}Apple-style localefr, pt-BR
{filename}Source file nameapp.json
{filename_no_ext}Source file name without extensionapp
{path}Source directorylocales/en

Examples

LayoutSource patternTranslation pattern
One folder per languagelocales/en/*.jsonlocales/{lang}/{filename}
Language in the file namemessages/en.jsonmessages/{lang}.json
Android resourcesapp/src/main/res/values/strings.xmlapp/src/main/res/values-{android_code}/strings.xml

Running a sync

From the connected project's Sync page you can run each action on demand:

The management view with Pull, Push, and Import actions and connection settings

  • Pull source — import the latest source-language keys from the repo.
  • Push translations — open a pull request writing your translated languages back.
  • Import existing — the one-time seed from Step 3; disabled once a managed sync branch exists.

Confirm before you sync

Before an action runs, TextSetu reads your repository and shows a confirmation with the same flow diagram and the exact list of files the action will read or write — so there are no surprises.

The pre-action confirmation for Pull showing the flow diagram and affected files

Push shows the same confirmation in the other direction — the languages and the files the pull request will write:

The pre-action confirmation for Push showing the target files

Review the files, then click Pull now / Push now / Import now.

Large repositories. If GitHub returns a partial file list for a very large repo, the confirmation notes that the preview may be incomplete — the sync itself still processes everything.


Automatic sync (webhooks)

With Auto-pull on push enabled, every push to your base branch triggers a Pull, so TextSetu always reflects the latest source strings. These automatic pulls are source-only and additive — they never delete keys or touch translations.

Protected branches. If your base branch is protected, TextSetu can't commit translations to it directly. Instead, Push routes into an auto-managed translation branch and opens a pull request from there. The branch is created on demand and cleared once its pull request is merged or deleted, so you review every change through GitHub's normal PR flow.


Connection settings

The management view exposes the ongoing sync behaviour:

  • Auto-pull on push — a push to the base branch auto-triggers a Pull into TextSetu.
  • Delete keys missing from repo (cleanup) — when a Pull runs, keys no longer present in the repo are removed from TextSetu. Off by default; automatic (webhook) pulls never clean up regardless of this setting.
  • Sync rules — edit the Pull source / Push target patterns and formats at any time.
  • Disconnect — remove the connection (your translations stay in TextSetu).

You can also pause a connection to temporarily stop syncing without disconnecting.


Sync history

The Recent sync runs table logs every Pull and Push:

The recent sync runs table with statuses and results

Each run shows its direction (pull/push), trigger (manual, webhook, or scheduled), status (queued → processing → completed/failed), a link to the commit or pull request, a summary of changes (keys added, values updated, translations imported), and any error message if it failed.


Permissions

ActionPermission
Install / manage the GitHub App at the orgManage organization
Connect a project, edit rules, run Pull/PushManage project
View sync status and historyRead project

Troubleshooting

"Pull existing still fetches only en." A plain Pull is source-only by design. To bring in translations already in the repo, use Import existing (Step 3) — it discovers repo languages and adds them to the project.

A file's format looks wrong. If a rule's file extension doesn't match its selected format (e.g. a .mjs file on a JSON rule), TextSetu shows a warning. Pick a matching file or change the format.

Push says "pull-only". The connection's direction is set to pull-only. Change the sync direction to allow pushes.

No target languages yet. Push needs target languages to write. They're added automatically by Import existing, or you can add them from the project's Languages tab.

A run failed. Open the run in the history table to see the error. Common causes are a pattern that matches no files, or a file TextSetu can't parse in the chosen format — the run fails cleanly and you can fix the rule and re-run.