Skip to content

fix(stryker-js-vitest-runner): release the bundled plugin-interface change from #262 - #269

Merged
ryanleecode merged 1 commit into
mainfrom
stryker/fix-release-tag-drift-2
Oct 10, 2026
Merged

ryanleecode merged 1 commit into
mainfrom
stryker/fix-release-tag-drift-2

Conversation

@systemfsoftware-maker

@systemfsoftware-maker systemfsoftware-maker commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Release on main is red again on 4bf5952 (#262's merge). Run 38023414725 refuses tag-integrity-mismatch for @systemfsoftware/stryker-js-vitest-runner@9.0.1. #262 changed no vitest-runner file, but the runner worker bundles @systemfsoftware/stryker-js-plugin-interface's dist into its own dist/main.mjs (the PLUG-1 worker-bundle rule). Plugin-interface is only a devDependency of the runner, so its change never moved the runner's version. The packed tarball changed under the same name@version its tag recorded.

This PR adds a patch intent for vitest-runner, so the version phase releases it as 9.0.2. The integrity check, the tags and .github/workflows/ are untouched.

Drift sweep (every publishable package)

I built every package tarball at 4bf5952 with nix build .#workspace-tarballs, the same input the derive phase uses. I hashed each one as the release tool does (sha512 over the .tgz) and compared it with the integrity in its last tag's annotation. 10 of 17 match. 7 drifted, and 6 of those already have a pending intent:

Package Last tag Files that differ What put the bytes in Release intent
stryker-js v18.1.0 21, incl. README.md, dist/config.mjs, dist/*.d.mts its own source (#260, #262 and earlier) major ×5, already on main
stryker-js-cli-contract v0.4.0 package.json, contract/stream.schema.json, dist/index.* #247 (package.json devDeps) and #262 (stream schema) patch (#265) + minor (#262), already on main
stryker-js-instrumenter v12.1.2 dist/index.mjs its own source (#262) major (plugins-name-the-ignore-rule), already on main
stryker-js-plugin-interface v15.0.0 dist/index.mjs, dist/index.d.mts its own source (#262) major ×2, already on main
stryker-js-typescript-checker v8.3.1 dist/main.mjs, dist/runtime.mjs its own source (#254, #255, #257). dist/main.mjs also bundles plugin-interface, which #262 changed again patch ×3, already on main
stryker-js-vitest-runner v9.0.1 dist/main.mjs bundled plugin-interface dist/index.mjs from #262: the ignore-rule id vocabulary (IgnoreRuleId, IgnoreStatusReason), SettledStatusSchema, and the checker's ignored-answer reason patch, added here
stryker-ignorer-effect-schema-declarations v0.2.1 README.md, dist/index.* its own source (#259) minor, already on main

vitest-runner integrity values:

  • recorded (tag @systemfsoftware/stryker-js-vitest-runner@v9.0.1): sha512-a0yptek9pPAQwLf2rnCy67ZSy8geb2+/A+Gh99PJxyyr2h5FEucARZIYHBV6H65OctJF40CZpshcJo6WnfKyXA==
  • current (4bf5952): sha512-DoZV//9RRXJVLqmytdcenPbG3sRG5+mADjpCL+egfU3ZKx4bUReX7ijOXjk9DkEtB7d608yV/Dt27RTjb/Z7sA==

At ec9ece0 (#265, last green Release) the runner's dist/main.mjs still matched its tag. The diff from there to 4bf5952 sits wholly inside the //#region ../stryker-js-plugin-interface/dist/index.mjs block.

Proof

I used the release tool's own plan from the same release-tools build CI uses (pnpm-release-management@b9b4a1d), with the tarballs built at 4bf5952:

  • origin/main: exit 1, refused: tag-integrity-mismatch, package: @systemfsoftware/stryker-js-vitest-runner@9.0.1, the same refusal as the Release run.
  • this head: exit 0, pending_intents=13 this_cycle=0 deferred=0 -> phase=version.

How an agent consumes this

When Release refuses tag-integrity-mismatch for <pkg>@<version>, do not edit the tag or the check. Build .#workspace-tarballs and hash every tarball against its last tag's annotation, because the tool stops at the first mismatch. For each drifted package with no pending intent, add a patch changeset. If the package's own source did not change, look in its dist for an inlined //#region ../<workspace-dep>/dist block. A bundled devDependency changes the dependent's bytes without moving its version.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…hange from #262

The runner worker inlines @systemfsoftware/stryker-js-plugin-interface's
dist (PLUG-1), so #262's plugin-interface change rewrote the packed
dist/main.mjs of vitest-runner 9.0.1 with no release intent, and the
Release derive phase refused tag-integrity-mismatch. Add a patch intent.

@ryanleecode ryanleecode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root verified: 10/10 green on d409d46, no open threads, no skips/disables.

@ryanleecode
ryanleecode merged commit be2f0c1 into main Oct 10, 2026
10 checks passed
@ryanleecode
ryanleecode deleted the stryker/fix-release-tag-drift-2 branch October 10, 2026 05:50
ryanleecode added a commit that referenced this pull request Oct 10, 2026
…ry check job (#279)

* ci(check): restore the base commit's Turbo cache first and report every check job

`check` restored `turbo-Linux-dist-<sha>` through prefix restore-keys, so a PR
got the newest entry its ref could read rather than its base commit's. #269
(one changeset file) restored an older main entry and re-ran 53 of 112 tasks;
turbo's own dry-run hashes are identical between that base and head, so the
key was never invalidated, the restored entry was simply another commit's.

- check restores `turbo-<os>-dist-<base>` in its own step (first parent, or
  merge-base with main on dispatch), and falls back to the prefix only on a
  miss; actions/cache searches the current ref before main, so one step with
  restore-keys would still prefer this ref's stale entry.
- Turbo writes run summaries (TURBO_RUN_SUMMARY); the cache is pruned to this
  run's task hashes and saved only when the Gate passed and missed a task.
- cache-sweep (main pushes only, the one job with actions: write) deletes
  turbo entries by cache id: main keeps its newest three, other refs one,
  closed pull requests none.
- .github/actions/job-report writes each job's summary (duration, Turbo
  cached/total, slowest missed tasks, restored key) and, on failure, an
  annotation titled with the reason code: GATE_OK, TURBO_TASK_FAILED,
  GATE_NON_TURBO_FAILED, CHECK_SETUP_FAILED, CANCELLED, SWEEP_OK/FAILED.
- workflow_dispatch input `cache: cold` skips the restore to measure cold.

Adds the CI wall-clock plan (docs/plans) this change is unit U1 of.

* ci(check): guard the Turbo save on this run's own key; sweep with gh cache

- The save guard compared only the fallback restore's exact hit, which is
  empty whenever the base entry restored, so a same-sha rerun tried to save
  over its own key. It now skips when either restore matched this run's key.
- cache-sweep lists and deletes through `gh cache list` / `gh cache delete
  <id>` (still by id) and checks out only the job-report action.
- job-report names its reason vocabulary itself and reports NO_REASON_CODE
  instead of an empty title when a caller passes none.

* fix(ci): read cancellation from job.status in the verdict env

cancelled() is valid only in if: conditionals, so the workflow failed to
compile on every push of this branch (actionlint: calling function
"cancelled" is not allowed here).

* test(ci): plant a dprint violation to exercise GATE_NON_TURBO_FAILED

* test(ci): plant a type error to exercise TURBO_TASK_FAILED

* test(ci): remove the planted CI failures

* ci(check): fail the verdict loudly on an unreadable Turbo summary; harden the sweep

- .github/scripts/turbo-summary.sh reads missed and failed tasks from Turbo's run
  summaries and exits 2 naming the first missing field. The verdict maps that to
  GATE_VERDICT_UNPARSEABLE with a next action and fails the job, instead of reading
  a format change as "nothing missed, nothing failed". turbo-summary.test.sh feeds it
  summaries missing fields and runs in check before the Gate.
- A lookup-only probe of this commit's own entry replaces the key comparisons: a
  re-run never re-tars and re-saves an entry that exists. A cache: cold dispatch
  never saves. The summary says "save: attempted" or "skipped (<why>)".
- cache-sweep: a failed delete is a SWEEP_DELETE_FAILED warning plus a count, and a
  failed PR-state lookup keeps that PR's entries; only a failed listing fails the job.
- The e2e comment claimed a cancelled job skips if: always() steps; a cancelled run
  ran them. It now says what timeout buys.

* ci(check): read Turbo summaries with scripts/turbo-summary.ts, tested with the repo scripts

#275 runs every scripts/*.test.ts in check, with Deno. The summary reader moves there as
scripts/turbo-summary.ts (run with node in the verdict) beside a Deno test that feeds it
summaries missing the exit code, the cache status, or the whole summary. The bash reader
and its own test step are gone.

* ci(check): run the verdict through scripts/turbo-summary.ts and its Deno test

The previous commit removed the bash reader without the workflow and script changes that
replace it.

* fix(e2e): keep day-old releases out of the fixture bake and bound each install

@effect/platform-node, platform-node-shared, opentelemetry and vitest 4.0.3
were published at 10:03 UTC with a peer effect@^4.0.3 that is not on the
registry. The bake resolves registry dependencies fresh, so npm resolved
forever and every e2e leg of run 38043976128 timed out in global setup.
Both bake installs now pass --min-release-age=1, and each runs under a
300 s timeout whose expiry names the fixture and step on stderr.

* fix(e2e): detect a bake install that ran over from elapsed time

The bake guest is node:24-alpine, whose timeout is busybox: a killed
install exits with its own signal status (143 or 137), never GNU's 124,
so the reason line never printed. The script now decides from elapsed
seconds, and timeout -k 10 kills an npm that ignores TERM.

---------

Co-authored-by: Ryan Lee <drdgvhbh@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants