Skip to content

Architecture

Each product keeps its documentation in its own repository (a Spoke). The Hub repository owns the Astro Starlight portal, Spoke registry, build pipeline, and staging deployment.

Spoke documentation is never committed into the Hub. The Hub fetches configured docs/ trees at exact SHAs during CI, validates them, then builds.

Enabled Spokes live in config/spokes.json. Each entry defines:

  • id — unique route under /products/<id>/
  • repository — GitHub owner/repo
  • branch — trusted branch used for rebuilds (MVP: main)
  • docsPath — directory to extract (MVP: docs)
  • enabled — whether the Hub includes it in every build
  1. Trigger via repository_dispatch from a Spoke or manual workflow_dispatch.
  2. Validate the triggering repository against the registry.
  3. Resolve exact SHAs for all enabled Spokes.
  4. Clean previously generated product content.
  5. Fetch and extract only each Spoke’s configured docs directory.
  6. Validate content, assets, links, routes, and security rules.
  7. Write build-manifest.json with every Spoke SHA.
  8. Run bun run build with broken-link validation.
  9. Deploy the complete portal to staging (Cloudflare Pages).
  • The Hub and approved Spokes hold the App Client ID and private key as Actions credentials. The App is installed only on approved repositories.
  • Each Spoke mints a short-lived installation token scoped to the Hub with Contents: Write, solely to send repository_dispatch.
  • The Hub mints a separate short-lived installation token scoped to enabled Spokes with Contents: Read, solely to fetch documentation.
  • Hub workflows never write to Spoke repositories.
  • Workflows use minimum contents: read / pull-requests: read unless deploying Pages.
  • Fork PRs never receive dispatch or Spoke-read secrets.
  • Spoke PR checks and dispatch workflows live in the Spoke (a few product repos; no Hub-hosted contract package). Hub fetch-spokes.mjs validates fetched docs before staging deploy and is the publish gate.