Publishes one package release train to the Gitea npm registry under
River_of_Glory_Church, whose packages are publicly readable on purpose:
exactly the .tgz files the package-release gate proved, and nothing else.
Nothing is published by this change.
- scripts/publish-package-train.ts validates the whole local train before
any request (gate manifest hash, version, revision, unmodified source,
the nine packages, every artifact's size, SHA-256, integrity,
SHA256SUMS line, and inner package.json), then publishes in dependency
order with `npm publish <file.tgz>` under a staging tag. Each package
is reconciled first (absent: publish; same bytes: accept; other bytes:
hard stop, version burned), then read back: metadata (name, version,
integrity, dependency maps, normalized bin, tarball on the registry)
and the tarball itself, byte for byte, also anonymously. `latest` moves
only after all nine verify; reruns converge and never delete anything.
It writes a publication record. The token comes from
EKKLESIA_PACKAGES_PUBLISH_TOKEN only, through a temporary npm config
that refers to the variable.
- scripts/test-package-publication.sh proves it against a disposable
Gitea 1.27.2 with public owners, a publisher team and an outsider:
anonymous reads, refused unauthorized publishing, byte-identical round
trips, the registry's own 409, partial-train recovery, the burned
version hard stop, and dist-tag retry convergence.
- CI: package-release keeps its proven release and hands it on as an
artifact with its manifest hash; the new package-publication job
publishes exactly that artifact to the disposable Gitea. Artifact
actions v3 (node20): v4 refuses any server other than github.com.
- .github/workflows/publish-packages.yml publishes to the real registry
only by manual dispatch on main, after its own gate run, with the
secret in the publish step alone.
- docs: the public-read model, the workflow, the record, credentials,
immutability policy, provider moves, and the first-publication steps.
Co-Authored-By: Claude Opus 5.5 <[email protected]>