feat: publish the exact @ekklesia package train to the npm registry (ADR 0053)
CI / verify (pull_request) Successful in 1m1s
CI / infrastructure-smoke (pull_request) Successful in 35s
CI / migration-smoke (pull_request) Successful in 1m53s
CI / package-release (pull_request) Failing after 43s
CI / package-publication (pull_request) Skipped
CI / image-build (pull_request) Successful in 29s
CI / deploy-smoke (split) (pull_request) Canceled after 0s
CI / deploy-smoke (same-origin) (pull_request) Canceled after 38s
CI / verify (pull_request) Successful in 1m1s
CI / infrastructure-smoke (pull_request) Successful in 35s
CI / migration-smoke (pull_request) Successful in 1m53s
CI / package-release (pull_request) Failing after 43s
CI / package-publication (pull_request) Skipped
CI / image-build (pull_request) Successful in 29s
CI / deploy-smoke (split) (pull_request) Canceled after 0s
CI / deploy-smoke (same-origin) (pull_request) Canceled after 38s
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]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
57df2e15f2
commit
d3c62e63bf
@@ -0,0 +1,25 @@
|
||||
# A disposable Gitea, the same version as the real one, whose npm registry the package publication
|
||||
# tests run against (scripts/test-package-publication.sh). Never the real registry: it starts empty,
|
||||
# keeps everything in the container, and is removed with its volumes when the test ends.
|
||||
services:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:1.27.2@sha256:d20286ca2b2e170fdf628e7231b8a31a3220ade39ff462b55041d43d1fc757dd
|
||||
environment:
|
||||
GITEA__security__INSTALL_LOCK: "true"
|
||||
GITEA__database__DB_TYPE: sqlite3
|
||||
# The URL clients reach it by: package metadata names tarballs under it.
|
||||
GITEA__server__ROOT_URL: ${GITEA_ROOT_URL:?GITEA_ROOT_URL is required}
|
||||
GITEA__server__HTTP_PORT: "3000"
|
||||
GITEA__server__OFFLINE_MODE: "true"
|
||||
GITEA__service__DISABLE_REGISTRATION: "true"
|
||||
GITEA__packages__ENABLED: "true"
|
||||
GITEA__actions__ENABLED: "false"
|
||||
GITEA__mailer__ENABLED: "false"
|
||||
GITEA__log__LEVEL: warn
|
||||
ports:
|
||||
- "127.0.0.1:${GITEA_PORT:?GITEA_PORT is required}:3000"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:3000/api/healthz"]
|
||||
interval: 2s
|
||||
timeout: 3s
|
||||
retries: 60
|
||||
Reference in New Issue
Block a user