feat(ci): cache pharos-tokens fingerprint + activate TurboSnap#86
Merged
Conversation
|
Warning Testing pausedMonthly snapshot limit reached. Update your plan to get more snapshots and resume testing. |
Closes the long-standing reason TurboSnap was disabled (`@code-sherpas/pharos-tokens` ships its CSS through `node_modules/`, falling outside the git tree TurboSnap compares against, so a pharos-tokens release that changed pixels could not invalidate any snapshot — see the old comment in chromatic.yml). Adds three coordinated pieces: 1. `scripts/snapshot-pharos-tokens.sh` — hashes every file under `node_modules/@code-sherpas/pharos-tokens` (sorted, content-addressed, locale-independent) and writes `version=<x> / content_sha256=<y>` to a tracked `.pharos-tokens.fingerprint` file. Hashing the whole installed directory (not just `dist/styles.css`) covers any future JS module, .d.ts, or metadata pharos-tokens may ship — eliminating the residual risk of a non-CSS change slipping through. 2. `package.json` `postinstall` invokes the script. Every `pnpm install` updates the fingerprint locally; `git status` surfaces the drift the developer must commit. 3. `.github/workflows/ci.yml` `Verify pharos-tokens fingerprint is current` step runs immediately after `pnpm install --frozen-lockfile` and fails the build (with a precise remediation message) when the committed fingerprint disagrees with `node_modules/`. This is the gate that prevents stale-fingerprint Chromatic baselines from ever shipping. To be made a *required* status check via branch protection on `main`. 4. `.github/workflows/chromatic.yml` flips `onlyChanged: true` (TurboSnap on) and declares `.pharos-tokens.fingerprint` as a Chromatic `externals` glob. A pharos-tokens release that mutates a single byte under `dist/` changes the fingerprint, TurboSnap sees it in the git diff, and invalidates the whole baseline — same behaviour we get today with `onlyChanged: false`, but limited to bumps that actually matter, not every push. Expected outcome: 40–60% reduction in snapshot quota burn per Chromatic's published TurboSnap savings, with zero new risk of stale visual baselines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ccfd584 to
2bfd010
Compare
2 tasks
dgraciac
added a commit
that referenced
this pull request
May 12, 2026
PR #86 wired `bash scripts/snapshot-pharos-tokens.sh` into the `postinstall` lifecycle. That hook runs on **every** install, including consumer installs of `@code-sherpas/pharos-react`. The published tarball ships only `dist/` and `RULES.md` (see `files` in package.json), so `scripts/` is absent from the artifact — consumer installs (Alexandria, future consumers) would fail with `bash: scripts/snapshot-pharos-tokens.sh: No such file or directory`. `prepare` is the correct lifecycle. From the npm docs: > Runs on local `npm install` without any arguments. Runs BEFORE > the package is packed. Does NOT run when the package is installed > as a dependency. So: - Local dev: `pnpm install` triggers `prepare`, which now chains `husky` and the fingerprint script. Same DX as before. - CI: `pnpm install --frozen-lockfile` also triggers `prepare` (verified locally — script regenerates `.pharos-tokens.fingerprint` in CI exactly as needed for the verify-fingerprint step in `ci.yml`). - Publish: the release runner's `prepare` regenerates the fingerprint before packing; `files: ["dist", "RULES.md"]` excludes it from the tarball so consumers never see it. - Consumer install of pharos-react: `prepare` is silent, the script is never invoked, the install succeeds. The publish bug never reached npm (PR #86 has no changeset and `0.11.1` on npm is unchanged). Fixing main before the next release keeps consumers safe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Activates TurboSnap (`onlyChanged: true` in `chromaui/action`) by caching the content fingerprint of `@code-sherpas/pharos-tokens` in a git-tracked file. Closes the long-standing reason TurboSnap was disabled: pharos-tokens ships its CSS through `node_modules/`, which falls outside the git tree TurboSnap compares against, so a pharos-tokens release that changed pixels could not invalidate any snapshot (documented in the old comment in chromatic.yml, observed live when `error.fg` was darkened to pass WCAG AA 4.5:1).
Architecture
Four coordinated pieces:
`scripts/snapshot-pharos-tokens.sh` — hashes every file under `node_modules/@code-sherpas/pharos-tokens` (sorted, content-addressed, locale-independent). Writes `version= / content_sha256=` to `.pharos-tokens.fingerprint`. Hashing the whole installed package directory, not just `dist/styles.css`, eliminates the residual risk a non-CSS change (a future JS icon-registry, a `.d.ts` shipped with the runtime, a metadata field that affects rendering) slips through unnoticed.
`package.json` `postinstall` — runs the script after every `pnpm install`. Local developers get the fingerprint regenerated automatically; `git status` surfaces the drift to be committed.
`ci.yml` `Verify pharos-tokens fingerprint is current` step — runs right after `pnpm install --frozen-lockfile` (which already executes the postinstall) and fails the CI with a precise remediation message when the committed fingerprint disagrees with `node_modules/`. This is the gate that prevents stale-fingerprint Chromatic baselines from shipping. Should be made a required status check via branch protection on `main` (CTO action — separate from this PR; see PR description below for the exact `gh api` invocation).
`chromatic.yml` — flips `onlyChanged: true` and declares `.pharos-tokens.fingerprint` as a Chromatic `externals` glob. A pharos-tokens release that mutates any byte under `dist/` changes the fingerprint → TurboSnap sees the diff in the git tree → invalidates the whole baseline. Same correctness as today's `onlyChanged: false`, but limited to bumps that actually matter.
Expected impact
Chromatic publishes 40–60% reduction in snapshot consumption for typical workflows. For pharos-react specifically, the win compounds because:
What this does not do
Local verification
Required branch-protection follow-up
After this merges, the `lint + typecheck + build + test` CI job needs to remain a required status check on `main` (it already is — this PR adds a step inside it, not a new job). Nothing further required for the verify step itself.
Test plan
🤖 Generated with Claude Code