diff --git a/.claude/skills/update-translations/SKILL.md b/.claude/skills/update-translations/SKILL.md new file mode 100644 index 00000000000..b056ca363c2 --- /dev/null +++ b/.claude/skills/update-translations/SKILL.md @@ -0,0 +1,235 @@ +--- +name: update-translations +description: > + Sync Transifex translations for the DHIS2 Android Capture App on BOTH the + develop and main branches in parallel, talking directly to the Transifex REST + API (no tx CLI). For each branch it spins up an isolated git worktree, pushes + the branch's sources to its own Transifex resources (develop--* / main--*), + pulls the translations for every language that has any key translated, applies + the KMP escaped-character fix, cleans up empty stubs, and opens a pull request. + Invoke for "update translations", "sync Transifex", "pull the latest + translations", or "push sources to Transifex". +--- + +# Update Translations (Transifex sync) + +Push sources and pull translations for **both** `develop` and `main`, each in its +own worktree, ending in a PR per branch. The two branches map to **separate** +Transifex resources — a `--branch develop` push only touches `develop--*`, a +`--branch main` push only touches `main--*` — so both runs are safe in parallel. + +Everything goes through one config-driven helper that talks to the Transifex v3 +REST API directly (no `tx` CLI, no `~/.transifexrc`): + +``` +.claude/skills/update-translations/scripts/transifex_sync.py \ + --branch +``` + +It parses `.tx/config` for the resource list, source files, `file_filter` +patterns, `lang_map` and `source_lang` — nothing about the modules is hardcoded, +so it stays correct as resources are added or removed. + +## Prerequisites (check first; stop and tell the user if any is missing) + +- **Python 3** (standard library only — no pip installs). +- **Transifex API token** in `local.properties` as `TX_TOKEN=...` (already there + alongside `SONAR_TOKEN` etc.). `local.properties` is gitignored, so it exists + only in the primary checkout — see the token step below for worktrees. The + helper also accepts `$TX_TOKEN` from the environment. +- **gh CLI** authenticated (`gh auth status`) for opening PRs. +- A clean primary working tree is NOT required — work happens in throwaway + worktrees on fresh branches, never disturbing the user's checkout. + +## Orchestration (you, the invoking agent) + +1. Resolve the stable paths, the token, and a datestamp up front (scripts can't + read the clock; you pass values in): + ```bash + REPO="$(git rev-parse --show-toplevel)" + SCRIPT="$REPO/.claude/skills/update-translations/scripts/transifex_sync.py" + DATE="$(date +%Y%m%d)" + git -C "$REPO" fetch origin + ``` +2. Create one worktree per branch on a fresh sync branch off the **remote** tip + (basing on `origin/` avoids the "branch already checked out" error and + guarantees the newest sources): + ```bash + git -C "$REPO" worktree add -b "develop-transifex-$DATE" "$REPO/../tx-sync-develop-$DATE" origin/develop + git -C "$REPO" worktree add -b "main-transifex-$DATE" "$REPO/../tx-sync-main-$DATE" origin/main + ``` + > The `develop-transifex-*` name intentionally matches the existing + > `fix-kmp-translations.yml` action, which then runs on that PR as a CI safety + > net. `main` has no such action, which is exactly why this skill applies the + > escaping fix itself for both branches. +3. Spawn **two `general-purpose` agents in parallel** (both Agent calls in one + message), one per branch. Give each: `$REPO` (so it can read the token — the + worktrees have no `local.properties`), its worktree path, its branch name, its + sync-branch name, and `$SCRIPT`. Pass the per-branch procedure below verbatim. +4. When both return, report both PR URLs and each `postpull` summary. Then remove + the worktrees (branches already live on origin): + ```bash + git -C "$REPO" worktree remove --force "$REPO/../tx-sync-develop-$DATE" + git -C "$REPO" worktree remove --force "$REPO/../tx-sync-main-$DATE" + ``` + +## Per-branch procedure (each worktree agent runs this from its worktree) + +Substitute `` (`develop`/`main`), `` +(`-transifex-`), `` (worktree path), `` (primary repo), +`