> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nt3.io/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub Integration

> Sync translations from Entri straight into a connected GitHub repository — commit or open a pull request, no CLI required.

The GitHub integration turns Entri into the source of truth that delivers translations to your codebase. Connect the Entri GitHub App once per organization, point each project at a repository and branch, then click **Sync now** — Entri exports your translations server-side, writes the files to the paths declared in the repo's `.nt3.yml`, and either commits to the branch or opens a pull request.

This removes the "a developer has to run the CLI" step. The same `.nt3.yml` that powers `nt3 pull` drives the server-side sync, so the files Entri writes are identical to what the CLI produces.

## How it works

<Steps>
  <Step title="Connect the GitHub App (once per organization)">
    In **Settings → Organization → GitHub**, an owner or admin clicks **Connect GitHub** and installs the Entri GitHub App on the repositories you choose. We recommend installing on **selected repositories** rather than all repos.
  </Step>

  <Step title="Configure a repository (per project)">
    In **Settings → Project → GitHub Sync**, pick one of the installed repositories, set the target branch (e.g. `main`), and choose a sync mode.
  </Step>

  <Step title="Sync">
    Click **Sync now**. Entri reads `.nt3.yml` from the chosen branch, exports each language × file pattern, and writes the result to GitHub.
  </Step>
</Steps>

## Sync modes

<CardGroup cols={2}>
  <Card title="Open a pull request" icon="code-pull-request">
    Entri pushes to a dedicated `nt3/sync-…` branch and opens a pull request against your target branch. Re-running **Sync now** updates the **same** pull request rather than opening a new one. Recommended for protected branches and review workflows.
  </Card>

  <Card title="Commit to branch" icon="code-commit">
    Entri commits the translations directly to the target branch. If the branch is protected and rejects the push, Entri reports a clear error asking you to switch to pull request mode.
  </Card>
</CardGroup>

## Configuration source of truth

Entri reads paths and formats from the **`.nt3.yml` on the connected branch** — exactly like the CLI. It does not duplicate path configuration in the UI.

```yaml .nt3.yml theme={null}
project_id: <your-project-id>
source_language: en
file_patterns:
  - path: locales/{lang}/messages.po
    format: po
  - path: src/i18n/{lang}.json
    format: json-nested
```

The `{lang}` placeholder is replaced with each language code. The source language comes from `.nt3.yml`; the target languages come from your project settings. If `source_language` in `.nt3.yml` disagrees with the project's source language, the sync fails with a **config drift** error rather than silently diverging.

## Behavior and limits

* **Additive / overwrite-only.** Entri creates or overwrites the managed translation files. It does **not** delete files from the repo, even if a language is removed. Deleting stale files is planned for a later release.
* **Commits appear as `nt3[bot]`** and are shown as **Unverified** in GitHub — this is normal for GitHub App tokens.
* **No empty syncs.** If nothing changed since the last sync, Entri reports **"Up to date — no changes"** and creates no commit or pull request.
* **Path safety.** Paths are validated before any write: absolute paths, `..` traversal, and anything under `.github/` are rejected.
* **Required App permissions (least privilege):** `Contents: Read & Write`, `Pull requests: Read & Write`, `Metadata: Read`. The App does **not** request `Workflows`, `Actions`, `Administration`, or `Secrets`.

## Permissions

| Action                                             | Required role       |
| -------------------------------------------------- | ------------------- |
| Connect / disconnect the GitHub App                | Owner or Admin      |
| Configure a project's repository, branch, and mode | Owner or Admin      |
| Trigger a sync (**Sync now**)                      | Developer or higher |

See [Roles & Permissions](/platform/team/roles-permissions) for the full role matrix.

## Troubleshooting

<AccordionGroup>
  <Accordion title="No valid .nt3.yml on the branch">
    Entri could not find or parse `.nt3.yml` on the configured branch. Add one (run `nt3 init` locally and commit it) and try again. The error message names the file, branch, and the invalid field.
  </Accordion>

  <Accordion title="GitHub connection expired — reconnect">
    The GitHub App was removed or suspended for your organization. Reconnect it from **Settings → Organization → GitHub**.
  </Accordion>

  <Accordion title="Branch is protected">
    In commit mode, a protected branch will reject a direct push. Switch the project to **pull request** mode.
  </Accordion>

  <Accordion title="The repository list is empty">
    The App is installed but no repositories were granted. Adjust the installation on GitHub to grant access to the repository you want to sync.
  </Accordion>
</AccordionGroup>
