Docs sync → radieu/p24-infra-docs — Operations

Automation: .github/workflows/sync-docs-to-p24-infra-docs.yml Target repo: radieu/p24-infra-docs (private) Source of truth: radieu/p24-infra — docs/** on main Issue: Etap 2 of #2640

What it does

On every push to main in radieu/p24-infra that touches docs/**, a GitHub Action mirrors the entire docs/ tree into the standalone private repo radieu/p24-infra-docs and commits it there. rsync --delete makes the mirror exact — files removed from p24-infra/docs/ are removed from the mirror too. p24-infra-docs is a read-only downstream mirror: never edit docs there directly, edits are overwritten on the next sync. All doc changes go through p24-infra.

Why a separate repo (decisions closed 2026-07-03 on #2640)

#QuestionDecisionReason
1Sync mechanismGH Action auto-copy on merge to mainZero manual work; docs always current
2Submodule vs independentIndependent repo (no submodule)Workers want latest docs; pinning/submodule adds CI + git pain for no value
3AccessPrivateDocs carry internal topology, server IPs, workflow detail
4Versioningmain only, no releasesDocs have no release cycle; git log is enough history

Scope of the mirror

  • Mirrored: the whole docs/ tree (topic-indexed Quartz/Obsidian vault, docs/01-…–docs/18-… index pages plus the flat operational docs they link to).
  • NOT mirrored (stays in p24-infra): CLAUDE.md and the per-project ecosystem instructions — per-project agent instructions must live beside the code they govern (established on #2640, 2026-08-06); secrets/; .claude/task-playbooks/ (read by hooks/classifier locally); CHANGELOG.md (tied to the p24-infra history, not docs).

Credential

No static PAT is used (#6239). The workflow mints a short-lived (1h) GitHub App installation token at run time via actions/create-github-app-token@v3, scoped to just radieu/p24-infra-docs with contents: write:

- uses: actions/create-github-app-token@v3
  with:
    app-id: ${{ secrets.GH_APP_ID }}
    private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
    owner: radieu
    repositories: p24-infra-docs
    permission-contents: write

GH_APP_ID / GH_APP_PRIVATE_KEY are the existing GH Secrets for the p24-infra-admin GitHub App (App 2109526 / installation 142989418, account radieu, repository_selection: all) — already used by credential-rotation.yml, reregister-ionos-runners.yml, secrets-sync.yml, and others. Because the App’s installation covers every repo in the radieu account (including new ones created after install), no per-target-repo credential ever needs to be minted or stored — this same mechanism covers any future repo the App can already reach.

  • owner:/repositories: are required for cross-repo scoping — without them the token is restricted to the current repo (p24-infra) and 403s against p24-infra-docs (same gotcha documented in reregister-ionos-runners.yml / provision-new-vps.yml, 4221).
  • actions/checkout injects the token via http.extraheader and strips it in post-run cleanup, so it never lands in a remote URL or a persisted .git/config.
  • The token is minted fresh on every run and expires in 1h — nothing to rotate, nothing to store.

History — the PAT that was never needed

The workflow originally (Etap 2 of #2640 / #6234) speced a static fine-grained PAT (P24_INFRA_DOCS_PUSH_PAT) as the push credential, gated behind a first-step no-op guard until the secret existed. That PAT could only be minted by a human via the GitHub web UI (no API for minting a user PAT) — escalated as #6239. A live check (read-only, via the App’s own JWT) found the App already had the access needed, making the PAT unnecessary; #6239 fixed the workflow to use the App mechanism instead and was closed without ever minting the PAT. No P24_INFRA_DOCS_PUSH_PAT secret exists or is needed.

Manual trigger / verification

# Force a full re-mirror:
gh workflow run sync-docs-to-p24-infra-docs.yml --repo radieu/p24-infra
 
# Watch the run:
gh run list --repo radieu/p24-infra --workflow sync-docs-to-p24-infra-docs.yml --limit 3
 
# Confirm the mirror populated:
gh repo view radieu/p24-infra-docs --json pushedAt,defaultBranchRef

Failure handling

The workflow is a standard GH Action — a failed run surfaces in the Actions tab. Auth failures now point at the App mechanism, not a PAT: check that GH_APP_ID/GH_APP_PRIVATE_KEY are still valid and that the p24-infra-admin App installation still covers radieu/p24-infra-docs (Settings → Installed GitHub Apps on the target repo, or repository_selection: all on the installation).