`jest` to ^30.4.2, `@types/jest` to ^30, `jest-junit` to ^17 and
`@types/supertest` to ^7. `ts-jest` stays at 29.4.12, whose peer range is
already `jest: ^29.0.0 || ^30.0.0`.
No test needed changing. The only content this touches is the header line
of the three snapshot files, which jest 30 rewrites from the `goo.gl`
shortlink to the documentation URL; all 44 snapshots and every assertion
are unchanged.
`jest-resolve` 30 depends on `unrs-resolver`, which has a postinstall, and
`strictDepBuilds` correctly failed the install rather than skipping it.
That postinstall only fetches a native binding when the platform one is
missing, and all 22 bindings are pinned in the lockfile, so it resolves and
exits — denied rather than allowed, the same treatment `core-js` gets. On a
platform with no pinned binding the failure moves to require time; denying
the script does not repair that case, which is why the comment says so. The
image never sees any of it: jest is a devDependency and the runtime stage
installs `--prod`.
`.gitignore` picks up both places a JUnit report lands. `jest-junit`
defaults to `junit.xml` in the working directory, which is what a local
`pnpm ci:test` produces; `test-reports/` exists only because the CI action
sets `JEST_JUNIT_OUTPUT_DIR`. Neither was ignored.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ticket
COMPASS-28 — Bump
spot's NodeJS minimum from 18 to 22What
jest@types/jestjest-junit@types/supertestts-jeststays at 29.4.12 — its peer range is alreadyjest: ^29.0.0 || ^30.0.0, so it does not need to move.Supersedes Dependabot #2623, #2603 and #2688.
No test needed changing
All 54 suites and 553 tests pass unmodified. The only content this touches is the header line of the three snapshot files, which jest 30 rewrites from the
goo.glshortlink to the documentation URL:One line per file, three files, and no change to any snapshot body — all 44 snapshots still match. Worth stating explicitly because a snapshot file appearing in a dependency-bump diff is normally the thing to be suspicious of.
The install failure worth reading
jest-resolve30 depends onunrs-resolver, which ships apostinstall.strictDepBuilds: truedid its job and failed the install rather than quietly skipping the script:That script is
napi-postinstall— a fallback for when the native binding did not arrive throughoptionalDependencies. All 22 bindings are pinned in the lockfile, includinglinux-x64-gnu(CI) and bothlinux-arm64-gnu/linux-arm64-musl(the emulated arm64 image build), so on every platform we build on the binding installs directly and the script has nothing left to do.So it is denied rather than allowed — the same treatment
core-jsalready gets inpnpm-workspace.yaml, and the option that does not execute a third-party install script. Verified that jest resolves and runs with the build denied. The image never sees any of this: jest is adevDependencyand the runtime stage installs--prod.If CI disagrees on some platform, the fix is
unrs-resolver: true, but that is a supply-chain decision and should not be made pre-emptively.test-reports/added to .gitignoreIt is jest's own output directory. A local sharded run — the form CI uses — leaves it in the repository root as untracked files, one XML per shard. It belongs in the PR that owns jest.
How this was verified
Locally on Node 22.23.2, all exit 0:
pnpm installpnpm buildpnpm testpnpm lint:checkpnpm build-docsdocker build+check-image-parityvalidate/ts-lint/checksum/--helpAlso ran the exact CI invocation, since the reporter and sharding are what a
jest-junitmajor could break:JEST_JUNIT_OUTPUT_NAME=... pnpm test --ci --reporters=default --reporters=jest-junit --shard=1/4Shard 1/4 ran 14 suites / 91 tests and produced valid JUnit XML (
tests=91 failures=0 errors=0), withJEST_JUNIT_UNIQUE_OUTPUT_NAMEstill appending a UUID — sotest-summary/action's./test-reports/**/*.xmlglob still matches.