screenshots: R2-hosted manifest becomes the baseline source of truth (morelli cutover)

The committed tests/screenshot-manifest.json is retired. CI now downloads
baselines/pcbjam/manifest.json (manifest v3, written only by the morelli
review app + its seed script) to the gitignored .baseline-manifest.json,
and everything downstream (pull, verify, compare) reads that copy:

- config.ts: MANIFEST_VERSION 3, MANIFEST_PATH .baseline-manifest.json,
  R2_BASELINES_MANIFEST_KEY; ManifestEntry grows opaque provenance
- r2-sync.ts: new --manifest mode (atomic fetch; no-creds skip DELETES a
  stale copy so the gate skips rather than using old baselines); --push
  gone (bytes enter the CAS only via morelli's promote)
- compare.ts: hard-skips when no manifest was fetched — a stale warm
  cache can never gate
- wasm-build.yml: fetch-manifest step before the baselines cache; cache
  key now hashes the fetched manifest; the gen-manifest --check lint gate
  goes with the committed manifest
- deleted: screenshot-manifest.json, promote.ts, changelog.ts,
  gen-manifest.ts, screenshot-changelog.yml, promote-screenshots skill
- docs (CLAUDE/README/TESTING/WHATWORKS/tools README): promote flow is
  now https://pcbjam-morelli-staging.pcbjam-staging.workers.dev

Validated locally against the real bucket: fetch-manifest (492), cold
pull 492 / warm pull cached=492, no-creds skip chain, compare gate skip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Istvan Matejcsok 2026-08-19 11:54:20 +02:00
commit ec7a1b0787
20 changed files with 239 additions and 4793 deletions

View file

@ -1,42 +0,0 @@
---
name: promote-screenshots
description: Promote a CI run's screenshot renders as the new baselines in the R2 bucket (pcbjam-ci-screenshots). Churn-free - only meaningfully-changed images upload; git gets only the tests/screenshot-manifest.json diff, never PNGs. Needs the read-write R2 keypair in tests/.env. Usage - "/promote-screenshots <ci-run-id> [--prune]". (scoped to pcbjam/ - covers the KiCad WASM e2e pipeline in tests/)
---
# promote-screenshots (pcbjam)
Bless a CI run's rendered screenshots as the new baselines. Baselines live in
the private R2 bucket `pcbjam-ci-screenshots` (prod Cloudflare account),
content-addressed as `sha256/<hex>.png`; the committed
`tests/screenshot-manifest.json` pins each `<engine>/<name>` to a hash. **Only
the manifest diff lands in git — never PNGs.**
## Prerequisites
- The READ-WRITE R2 keypair in the gitignored `tests/.env` (auto-loaded by the
tooling, shell env wins; format in `tests/tools/screenshots/README.md`,
values from the team vault). **Never print, echo, or commit these values.**
If `.env` is missing, ask the user to fill it — promote fails fast without it.
- The CI run id: `gh run list --workflow ci-ubicloud.yml` on PCBJam/pcbjam
(mind the active `gh` account — PCBJam repos need `matejcsok-pcb`).
## Steps
1. From `tests/`, dry-run first and show the user the plan:
`npm run screenshots:promote -- --run <ci-run-id> --dry-run`
2. Sanity-check it: a handful of UPDATE/ADD lines for an intentional UI change
is normal; hundreds of UPDATEs means environment drift — stop and confirm
with the user before applying.
3. Apply: same command without `--dry-run`. Add `--prune` only when the user
confirms screenshots were intentionally removed (prune edits the manifest;
R2 objects are never deleted — old commits still resolve).
4. `git status` must show ONLY `tests/screenshot-manifest.json` modified.
Commit that diff; on main it triggers the Discord baseline changelog.
## Never
- Never commit files under `tests/baseline-screenshots/` (the CI manifest
check fails the build if you do) or the `.env`.
- Never promote local (Mac) renders via `--from` — CI's Linux render is the
only source of truth.
- Never hand-edit hashes in the manifest; promote regenerates it.