Summary
Every commit and pull request in this repository fails test whenever any of the ten ports publishes a release, until someone commits a refreshed site/src/data/registry.json. The per-commit gate compares that committed file against live package registries, so its result depends on other repositories rather than on the commit under test. Separately, the shell deploy has been merging none of the ports' published version manifests.
Motivation
Also found
The shell deploy downloads manifest/<port>.json with 2>/dev/null || true, but the shell's IAM role has no read access to manifest/*. The last three successful deploys each logged merge-version-manifests: merged 0 published port fragment(s) (for example run 36317927860), while the manifests exist and are public, so ports' version lists and defaults never reach versions.json or the default-version store.
Proposal
Invariants, the non-negotiable part: a pull request's CI result depends only on the commit and its pinned inputs; a release reaches the site without a human commit; a port can publish only its own prefix, through a reviewed workflow. Everything below is non-binding intent, from smallest to largest.
Fix the manifest merge
Grant the shell role s3:GetObject (and, for the options below, put and delete) on manifest/* in the infrastructure Terraform, and let the copy fail loudly when a manifest exists but cannot be read.
Offline gate plus a scheduled refresh
The gate runs gen-registry.mjs --check --offline. An hourly workflow regenerates the registry online and opens or updates one refresh pull request, auto-merged when green, as Homebrew autobump and nodejs.org auto-merge do. The bot must open its pull request with a GitHub App installation token, because events created by GITHUB_TOKEN do not start workflow runs (docs). The probe records a tag only once the registry carries that version.
Registry computed at deploy time
The shell deploy regenerates the registry against the live APIs, falls back to the last published copy in the bucket, publishes the resolved file, and gains schedule and workflow_dispatch triggers. registry.json leaves git; the gate checks rendering against a fixture.
Dispatch-driven, manifest-free publishing
A workflow_dispatch here with inputs such as ports (all or a list), ref (tag, branch, SHA or latest), version, version-kind and is-default (up to 25 inputs). It fans out to each port's own docs workflow with a GitHub App installation token minted by actions/create-github-app-token, since GITHUB_TOKEN cannot reach another repository. Each port builds its tree and API model with its native toolchain and records its released version in its bucket manifest, and the shell composes install commands, version lists and API pages from the bucket, so no committed manifest remains. libtmux-ruby and libtmux-lua already accept these inputs (example).
Port roles can trust only this repository's reusable workflow rather than each caller: AWS IAM supports token.actions.githubusercontent.com:job_workflow_ref as a condition key (AWS docs, GitHub docs). A reusable workflow's uses: ref cannot be an expression (docs), so port pins are bumped by Renovate or Dependabot. The Terraform GitHub provider can own the environments, organization variables, the App's repository list and rulesets alongside the IAM changes.
Not doing
Changing docs.rs as the canonical Rust API reference, or the separate Python documentation site.
References
Summary
Every commit and pull request in this repository fails
testwhenever any of the ten ports publishes a release, until someone commits a refreshedsite/src/data/registry.json. The per-commit gate compares that committed file against live package registries, so its result depends on other repositories rather than on the commit under test. Separately, the shell deploy has been merging none of the ports' published version manifests.Motivation
scripts/test-all.shrunsnode scripts/gen-registry.mjs --checkonline inside thetestjob, andtest.ymlpassesGITHUB_TOKENso it reliably reaches the APIs.gen-registry.mjsdocuments--offlineas the mode "For CI jobs that must not depend on eight third-party services"; the gate does not use it.v0.0.0-alpha.17the release ran 15:11 to 15:31 UTC and NuGet published at 15:25 UTC, so a refresh committed in between went stale within minutes and Refresh the Rust registry entry and API model for alpha.14 #25 failed this step twice in an hour for ports it did not touch.registry.jsonexist only to refresh it, and refreshes ride along inside unrelated pull requests (for example Run the TypeScript workspace CLI with plain yarn dlx #23 and Refresh the Rust registry entry and API model for alpha.14 #25). Nothing else detects a release: no workflow runs on a schedule, and the shell deploy ships the committed file as is.Also found
The shell deploy downloads
manifest/<port>.jsonwith2>/dev/null || true, but the shell's IAM role has no read access tomanifest/*. The last three successful deploys each loggedmerge-version-manifests: merged 0 published port fragment(s)(for example run 36317927860), while the manifests exist and are public, so ports' version lists and defaults never reachversions.jsonor the default-version store.Proposal
Invariants, the non-negotiable part: a pull request's CI result depends only on the commit and its pinned inputs; a release reaches the site without a human commit; a port can publish only its own prefix, through a reviewed workflow. Everything below is non-binding intent, from smallest to largest.
Fix the manifest merge
Grant the shell role
s3:GetObject(and, for the options below, put and delete) onmanifest/*in the infrastructure Terraform, and let the copy fail loudly when a manifest exists but cannot be read.Offline gate plus a scheduled refresh
The gate runs
gen-registry.mjs --check --offline. An hourly workflow regenerates the registry online and opens or updates one refresh pull request, auto-merged when green, as Homebrew autobump and nodejs.org auto-merge do. The bot must open its pull request with a GitHub App installation token, because events created byGITHUB_TOKENdo not start workflow runs (docs). The probe records a tag only once the registry carries that version.Registry computed at deploy time
The shell deploy regenerates the registry against the live APIs, falls back to the last published copy in the bucket, publishes the resolved file, and gains
scheduleandworkflow_dispatchtriggers.registry.jsonleaves git; the gate checks rendering against a fixture.Dispatch-driven, manifest-free publishing
A
workflow_dispatchhere with inputs such asports(all or a list),ref(tag, branch, SHA orlatest),version,version-kindandis-default(up to 25 inputs). It fans out to each port's own docs workflow with a GitHub App installation token minted byactions/create-github-app-token, sinceGITHUB_TOKENcannot reach another repository. Each port builds its tree and API model with its native toolchain and records its released version in its bucket manifest, and the shell composes install commands, version lists and API pages from the bucket, so no committed manifest remains. libtmux-ruby and libtmux-lua already accept these inputs (example).Port roles can trust only this repository's reusable workflow rather than each caller: AWS IAM supports
token.actions.githubusercontent.com:job_workflow_refas a condition key (AWS docs, GitHub docs). A reusable workflow'suses:ref cannot be an expression (docs), so port pins are bumped by Renovate or Dependabot. The Terraform GitHub provider can own the environments, organization variables, the App's repository list and rulesets alongside the IAM changes.Not doing
Changing docs.rs as the canonical Rust API reference, or the separate Python documentation site.
References
docs-sitepublish trigger; libtmux-tsdocs.ymlstill carries the same one.reusable-deploy.yml: the deploy contract; it requires adistributionsecret it never uses and says rs, go and java never publish through it, which they do.