|
| 1 | +# Getting started (end to end) |
| 2 | + |
| 3 | +Operator quick reference and end-to-end walkthrough from an empty translations |
| 4 | +repository to a fully operational Boost documentation translation pipeline. For |
| 5 | +per-workflow field detail see |
| 6 | +[README.md](../README.md); for design and return codes see |
| 7 | +[ARCHITECTURE.md](ARCHITECTURE.md); for HTTP and dispatch shapes see |
| 8 | +[endpoint-contract.md](endpoint-contract.md). If you pin automation to a semver tag, |
| 9 | +check [CHANGELOG.md](../CHANGELOG.md) before upgrading. |
| 10 | + |
| 11 | +Branch names and the Weblate path are defined in |
| 12 | +[`.github/workflows/assets/env.sh`](../.github/workflows/assets/env.sh): |
| 13 | +`MASTER_BRANCH`, `LOCAL_BRANCH_PREFIX`, `TRANSLATION_BRANCH_PREFIX`, |
| 14 | +`WEBLATE_ENDPOINT_PATH`. Examples below use current defaults (`master`, `local-`, |
| 15 | +`translation-`, `boost-endpoint/add-or-update/`). |
| 16 | + |
| 17 | +```mermaid |
| 18 | +flowchart TD |
| 19 | + config["0 Configure secrets and vars"] |
| 20 | + local["1 Optional local .env + GH_TOKEN"] |
| 21 | + add["2 add-submodules"] |
| 22 | + verifyAdd["Verify mirrors and super-repo"] |
| 23 | + start["3 start-translation"] |
| 24 | + verifyStart["Verify Weblate handoff"] |
| 25 | + sync["4 sync-translation ongoing"] |
| 26 | + tag["5 create-tag on merged PRs"] |
| 27 | + config --> local --> add --> verifyAdd --> start --> verifyStart --> sync |
| 28 | + verifyStart -.->|"translator merges PR"| tag |
| 29 | + sync -->|"daily cron or manual dispatch"| sync |
| 30 | +``` |
| 31 | + |
| 32 | +## Operator checklist |
| 33 | + |
| 34 | +| Step | When | Workflow | Trigger | Script / client | |
| 35 | +| ---- | ---- | -------- | ------- | ----------------- | |
| 36 | +| 0 | Always first | — | — | GitHub secrets/vars: `SYNC_TOKEN`, `WEBLATE_URL`, `WEBLATE_TOKEN`, `LANG_CODES`, optional `SUBMODULES_ORG` | |
| 37 | +| 1 | Optional | — | — | `cp .env.example .env` → `GH_TOKEN` | |
| 38 | +| 2 | Greenfield / new libs | `add-submodules.yml` | `event_type: add-submodules` | `scripts/trigger-add-submodules.sh` | |
| 39 | +| 3 | After mirrors exist | `start-translation.yml` | `event_type: start-translation` | `scripts/trigger-start-translation.sh` | |
| 40 | +| 4 | Ongoing | `sync-translation.yml` | `event_type: sync-translation` or daily cron | curl example (no script) | |
| 41 | +| 5 | Automatic | mirror `create-tag.yml` | PR merge in mirror | none | |
| 42 | + |
| 43 | +- **Dispatch order:** on a fresh repo, run step 2 before step 3. Detail in [§3](#3-start-translation--sync-mirrors-and-notify-weblate) and [`.github/workflows/assets/translation.sh`](../.github/workflows/assets/translation.sh). |
| 44 | +- **Exit codes:** per-submodule **0 / 1 / 2** collapse rules — [ARCHITECTURE §6 — Shell return codes](ARCHITECTURE.md#6-shell-return-codes) only. |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +## 0. Prerequisites — GitHub secrets and variables |
| 49 | + |
| 50 | +Configure these on the translations repository **before** dispatching any workflow: |
| 51 | +**Settings → Secrets and variables → Actions**. |
| 52 | + |
| 53 | +| Kind | Name | Where documented | |
| 54 | +| -------- | ---------------- | ---------------- | |
| 55 | +| Secret | `SYNC_TOKEN` | [README § Required secrets](../README.md#required-secrets) | |
| 56 | +| Secret | `WEBLATE_URL` | [README § Required secrets](../README.md#required-secrets) | |
| 57 | +| Secret | `WEBLATE_TOKEN` | [README § Required secrets](../README.md#required-secrets) | |
| 58 | +| Variable | `LANG_CODES` | [README § Repository variables](../README.md#repository-variables) | |
| 59 | +| Variable | `SUBMODULES_ORG` | [README § Repository variables](../README.md#repository-variables) | |
| 60 | + |
| 61 | +`SYNC_TOKEN`, `WEBLATE_URL`, and `WEBLATE_TOKEN` are required secrets; |
| 62 | +`LANG_CODES` and optional `SUBMODULES_ORG` are repository variables. See the |
| 63 | +linked README sections for scope, format, and which workflows consume each value. |
| 64 | + |
| 65 | +--- |
| 66 | + |
| 67 | +## 1. Local trigger setup (optional) |
| 68 | + |
| 69 | +To fire dispatches from a clone of this repo instead of the GitHub API or UI: |
| 70 | + |
| 71 | +```bash |
| 72 | +cp .env.example .env # set GH_TOKEN (GITHUB_TOKEN is also accepted) |
| 73 | +``` |
| 74 | + |
| 75 | +- **`GH_TOKEN`** is **client-side only** — permission to call |
| 76 | + `POST /repos/{owner}/{repo}/dispatches`. Workflows still use the GitHub |
| 77 | + **secrets** from step 0 on the server. |
| 78 | +- Requires **curl** and **jq** or Python 3. |
| 79 | + |
| 80 | +See [README § Scripts](../README.md#scripts-local-repository_dispatch) for script |
| 81 | +details. |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | +## 2. `add-submodules` — create mirrors and register submodules |
| 86 | + |
| 87 | +**When:** greenfield setup or adding new library mirrors. |
| 88 | + |
| 89 | +| Item | Value | |
| 90 | +| -------- | --------------------------------------------------------------------- | |
| 91 | +| Workflow | [`.github/workflows/add-submodules.yml`](../.github/workflows/add-submodules.yml) | |
| 92 | +| Script | `scripts/trigger-add-submodules.sh` | |
| 93 | +| Trigger | `repository_dispatch` with `event_type: add-submodules` | |
| 94 | + |
| 95 | +### Trigger (JSON) |
| 96 | + |
| 97 | +POST to `https://api.github.com/repos/{owner}/{repo}/dispatches`: |
| 98 | + |
| 99 | +```json |
| 100 | +{ |
| 101 | + "event_type": "add-submodules", |
| 102 | + "client_payload": { "version": "boost-1.90.0" } |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +Optional `client_payload` fields: `submodules`, `lang_codes`. See |
| 107 | +[README § add-submodules](../README.md#add-submodulesyml--create-library-mirrors-and-register-submodules). |
| 108 | + |
| 109 | +### Script |
| 110 | + |
| 111 | +```bash |
| 112 | +scripts/trigger-add-submodules.sh \ |
| 113 | + --repo OWNER/boost-docs-translation \ |
| 114 | + --version boost-1.90.0 \ |
| 115 | + --submodules 'unordered, json' \ |
| 116 | + --lang-codes zh_Hans |
| 117 | +``` |
| 118 | + |
| 119 | +- Omit **`--lang-codes`** to use repository variable **`LANG_CODES`**. |
| 120 | +- Omit **`--submodules`** to use the script default **`DEFAULT_SUBMODULES`** |
| 121 | + (`unordered, json` at |
| 122 | + [trigger-add-submodules.sh:40](../scripts/trigger-add-submodules.sh)) — **not** |
| 123 | + auto-discovery from **`boostorg/boost`**. The script substitutes that default |
| 124 | + before building the payload |
| 125 | + ([line 160](../scripts/trigger-add-submodules.sh)), so `client_payload.submodules` |
| 126 | + is never omitted. Full discovery runs only when the workflow receives a dispatch |
| 127 | + **without** a `submodules` field (raw API / GitHub UI). |
| 128 | + |
| 129 | +### Expected outcome |
| 130 | + |
| 131 | +For each library in the resolved list: |
| 132 | + |
| 133 | +- A new mirror repo under **`MODULE_ORG`** (from **`SUBMODULES_ORG`** or this |
| 134 | + repo's owner) containing doc-only content on **`MASTER_BRANCH`** (`master`). |
| 135 | +- **`${LOCAL_BRANCH_PREFIX}{lang_code}`** branches (e.g. `local-zh_Hans`) on each |
| 136 | + mirror, with **`create-tag.yml`** copied from |
| 137 | + [`.github/workflows/assets/`](../.github/workflows/assets/). |
| 138 | +- Submodule entries in this super-repo under **`libs/<name>`** on **`MASTER_BRANCH`** |
| 139 | + and each **`${LOCAL_BRANCH_PREFIX}{lang_code}`** branch. |
| 140 | + |
| 141 | +Existing mirrors are skipped (idempotent). |
| 142 | + |
| 143 | +### Verify |
| 144 | + |
| 145 | +1. **Mirror repos** — on GitHub, confirm `{MODULE_ORG}/{lib}` exists with branches |
| 146 | + **`MASTER_BRANCH`** and **`${LOCAL_BRANCH_PREFIX}{lang}`** (e.g. `master`, |
| 147 | + `local-zh_Hans`); confirm `.github/workflows/create-tag.yml` is present on the |
| 148 | + mirror. |
| 149 | +2. **Super-repo** — on **`MASTER_BRANCH`**, confirm `.gitmodules` lists each |
| 150 | + `libs/<lib>` URL pointing at `{MODULE_ORG}/{lib}`; run |
| 151 | + `git submodule status` on `master` and each `local-{lang}` branch — SHAs should |
| 152 | + be non-empty. |
| 153 | +3. **Actions** — the workflow job exits **0**; the trigger script prints HTTP **204** |
| 154 | + on success. For partial submodule failures and skip semantics, see |
| 155 | + [ARCHITECTURE §6 — Shell return codes](ARCHITECTURE.md#6-shell-return-codes). |
| 156 | + |
| 157 | +--- |
| 158 | + |
| 159 | +## 3. `start-translation` — sync mirrors and notify Weblate |
| 160 | + |
| 161 | +**When:** after mirrors exist under **`MODULE_ORG`** and **`.gitmodules`** is |
| 162 | +populated on **`MASTER_BRANCH`**. |
| 163 | + |
| 164 | +| Item | Value | |
| 165 | +| -------- | ----------------------------------------------------------------------- | |
| 166 | +| Workflow | [`.github/workflows/start-translation.yml`](../.github/workflows/start-translation.yml) | |
| 167 | +| Script | `scripts/trigger-start-translation.sh` | |
| 168 | +| Trigger | `repository_dispatch` with `event_type: start-translation` | |
| 169 | + |
| 170 | +**Dispatch order:** do **not** skip step 2 on a fresh repo. **`start-translation`** |
| 171 | +reads **this repo's `.gitmodules`** and does **not** create org mirrors; a missing |
| 172 | +mirror is a **fatal** error (`Run add-submodules first.` — see |
| 173 | +[start-translation.yml](../.github/workflows/start-translation.yml) header and |
| 174 | +[translation.sh](../.github/workflows/assets/translation.sh)). |
| 175 | + |
| 176 | +### Trigger (JSON) |
| 177 | + |
| 178 | +```json |
| 179 | +{ |
| 180 | + "event_type": "start-translation", |
| 181 | + "client_payload": { "version": "boost-1.90.0" } |
| 182 | +} |
| 183 | +``` |
| 184 | + |
| 185 | +Optional `client_payload` fields: `lang_codes`, `extensions`. See |
| 186 | +[README § start-translation](../README.md#start-translationyml--sync-existing-mirrors-and-notify-weblate). |
| 187 | + |
| 188 | +### Script |
| 189 | + |
| 190 | +```bash |
| 191 | +scripts/trigger-start-translation.sh \ |
| 192 | + --repo OWNER/boost-docs-translation \ |
| 193 | + --version boost-1.90.0 \ |
| 194 | + --lang-codes zh_Hans \ |
| 195 | + --extensions '.adoc, .qbk' |
| 196 | +``` |
| 197 | + |
| 198 | +- Requires secrets **`WEBLATE_URL`** and **`WEBLATE_TOKEN`**. Omit |
| 199 | + **`--lang-codes`** to use repository variable **`LANG_CODES`**. |
| 200 | + |
| 201 | +### Expected outcome |
| 202 | + |
| 203 | +For each language and each submodule listed in this repo's `.gitmodules`: |
| 204 | + |
| 205 | +1. Mirror **`MASTER_BRANCH`** refreshed from upstream **`boostorg`** (doc-only |
| 206 | + prune). |
| 207 | +2. Mirror **`${LOCAL_BRANCH_PREFIX}{lang}`** created or merged from |
| 208 | + **`MASTER_BRANCH`** when there is no open PR whose head starts with |
| 209 | + **`${TRANSLATION_BRANCH_PREFIX}{lang}-`** (in-flight Weblate work is preserved). |
| 210 | +3. Super-repo submodule pointers updated on **`MASTER_BRANCH`** and each |
| 211 | + **`${LOCAL_BRANCH_PREFIX}{lang}`** branch. |
| 212 | +4. **POST** to **`{WEBLATE_URL}/${WEBLATE_ENDPOINT_PATH}`** with |
| 213 | + `add_or_update` mapping language codes to updated submodule names. Omitted when |
| 214 | + nothing changed. See |
| 215 | + [endpoint-contract § Outbound Weblate](endpoint-contract.md). |
| 216 | + |
| 217 | +Weblate typically responds with HTTP **202** (async accepted); **200** is also |
| 218 | +accepted. |
| 219 | + |
| 220 | +### Verify |
| 221 | + |
| 222 | +1. **Actions** — in the `start-local` job logs, confirm the Weblate POST returned |
| 223 | + **202** or **200** and the response body is printed. |
| 224 | +2. **Weblate** — confirm projects/components exist for the `organization`, each |
| 225 | + `lang_code`, and submodule names sent in the `add_or_update` payload (field |
| 226 | + semantics in [endpoint-contract.md](endpoint-contract.md)). |
| 227 | +3. **Super-repo** — on each **`${LOCAL_BRANCH_PREFIX}{lang}`** branch, submodule |
| 228 | + SHAs should match the corresponding mirror **`${LOCAL_BRANCH_PREFIX}{lang}`** |
| 229 | + branch tips. |
| 230 | + |
| 231 | +--- |
| 232 | + |
| 233 | +## 4. `sync-translation` — ongoing pointer roll-up |
| 234 | + |
| 235 | +**When:** after **`${LOCAL_BRANCH_PREFIX}*`** branches exist in the super-repo. |
| 236 | +Runs automatically **daily at 00:00 UTC** (`0 0 * * *`) or on manual dispatch. |
| 237 | + |
| 238 | +| Item | Value | |
| 239 | +| -------- | --------------------------------------------------------------------- | |
| 240 | +| Workflow | [`.github/workflows/sync-translation.yml`](../.github/workflows/sync-translation.yml) | |
| 241 | +| Script | **None** — use the dispatches API, GitHub UI, or the curl example below | |
| 242 | +| Trigger | `repository_dispatch` with `event_type: sync-translation` (no `client_payload`) | |
| 243 | + |
| 244 | +### Trigger (JSON) |
| 245 | + |
| 246 | +```json |
| 247 | +{ "event_type": "sync-translation" } |
| 248 | +``` |
| 249 | + |
| 250 | +See [README § sync-translation](../README.md#sync-translationyml--advance-submodule-pointers-on-local_branch_prefix-branches) |
| 251 | +and [endpoint-contract § sync-translation](endpoint-contract.md). |
| 252 | + |
| 253 | +### Script (curl) |
| 254 | + |
| 255 | +```bash |
| 256 | +curl -sS -o /dev/null -w '%{http_code}\n' \ |
| 257 | + -X POST -H "Authorization: Bearer $GH_TOKEN" \ |
| 258 | + -H "Accept: application/vnd.github+json" \ |
| 259 | + -H "X-GitHub-Api-Version: 2022-11-28" \ |
| 260 | + -H "Content-Type: application/json" \ |
| 261 | + -d '{"event_type":"sync-translation"}' \ |
| 262 | + "https://api.github.com/repos/OWNER/REPO/dispatches" |
| 263 | +``` |
| 264 | + |
| 265 | +Expect HTTP **204** on success. |
| 266 | + |
| 267 | +### Expected outcome |
| 268 | + |
| 269 | +For each remote **`${LOCAL_BRANCH_PREFIX}*`** branch in the super-repo: checkout |
| 270 | +with submodules, set each submodule's tracking branch to that name, run |
| 271 | +`git submodule update --remote`, commit if pointers changed, and force-push. |
| 272 | + |
| 273 | +Requires secret **`SYNC_TOKEN`** only. Relies on **`.gitmodules`** URLs established |
| 274 | +by steps 2–3. |
| 275 | + |
| 276 | +### Verify |
| 277 | + |
| 278 | +After translator merges land in mirror repos, either wait for the daily cron or |
| 279 | +trigger manually. Confirm super-repo **`${LOCAL_BRANCH_PREFIX}{lang}`** branch |
| 280 | +submodule SHAs advance to match each mirror's **`${LOCAL_BRANCH_PREFIX}{lang}`** |
| 281 | +tip. |
| 282 | + |
| 283 | +--- |
| 284 | + |
| 285 | +## 5. `create-tag` — tags on merged Weblate PRs (automatic) |
| 286 | + |
| 287 | +This step is **not** a dispatch you run during bootstrap. It completes the |
| 288 | +operational picture once translators begin work in Weblate. |
| 289 | + |
| 290 | +**When:** a Weblate PR merges in a **mirror** repo — head branch |
| 291 | +**`${TRANSLATION_BRANCH_PREFIX}{lang}-{version}`** (e.g. |
| 292 | +`translation-zh_Hans-boost-1.90.0`) into base |
| 293 | +**`${LOCAL_BRANCH_PREFIX}{lang}`** (e.g. `local-zh_Hans`). |
| 294 | + |
| 295 | +**What:** the mirror workflow **`create-tag.yml`** (installed during step 2) runs on |
| 296 | +the PR `closed` event and creates tag **`{version}-{repo}-{lang_code}`** (e.g. |
| 297 | +`boost-1.90.0-algorithm-zh_Hans`) if it does not already exist. |
| 298 | + |
| 299 | +### Verify |
| 300 | + |
| 301 | +1. **Mirror repo** — after a Weblate PR merges into **`${LOCAL_BRANCH_PREFIX}{lang}`**, |
| 302 | + confirm the tag appears under **Tags** (or `git tag -l` on the mirror). |
| 303 | +2. **Actions** — confirm the `create-tag` workflow job ran on the PR `closed` event |
| 304 | + and exited **0**. |
| 305 | + |
| 306 | +Tag format and namespace distinction from orchestration semver: |
| 307 | +[`.github/workflows/assets/README.md`](../.github/workflows/assets/README.md). |
| 308 | + |
| 309 | +--- |
| 310 | + |
| 311 | +## 6. Interpreting results |
| 312 | + |
| 313 | +Workflow jobs collapse per-submodule return codes **0 / 1 / 2** into step exit |
| 314 | +**0 or non-zero**; code **`2` is never propagated** to the GitHub Actions step exit |
| 315 | +code. The local trigger scripts use a simpler **0 / 1** contract (success vs any |
| 316 | +error). |
| 317 | + |
| 318 | +Full detail: **[ARCHITECTURE.md §6 — Shell return codes](ARCHITECTURE.md#6-shell-return-codes)**. |
| 319 | + |
| 320 | +### Quick decision guide |
| 321 | + |
| 322 | +| Situation | Run | |
| 323 | +| ----------------------------------------------- | ------------------------------------------------ | |
| 324 | +| New repo or new library mirrors | `add-submodules` → `start-translation` | |
| 325 | +| New Boost release on existing mirrors | `start-translation` | |
| 326 | +| Advance super-repo pointers after translator merges | `sync-translation` (or wait for daily cron) | |
0 commit comments