fix(e2e): resolve packed installs from a committed lockfile - #378
Conversation
The packed nextjs e2e fixture (e2e/nextjs/packed/harness.ts) resolved transitive registry deps of the packed @Conciv tarballs live against the registry on every run. A third-party publish (@orpc/tanstack-query 1.15.0) turned CI red with zero repo changes. Mechanism: setupFixture() now copies a committed lockfile (e2e/nextjs/packed/fixture-lock.yaml) into the generated fixture root before `pnpm install --no-frozen-lockfile` (plain --frozen-lockfile is off the table since the @Conciv tarballs change content every commit and would hard-fail integrity checks). Verified via a scratch-dir pnpm spike: a plain install refreshes a changed file: tarball's hash without touching unrelated registry resolutions, and keeps a registry dep pinned to its lockfile-recorded version even when a newer version satisfying the same range has since been published — copying in a lockfile is enough to pin without --frozen-lockfile. Tarballs now pack into a stable `<root>/tgz/` directory instead of an independent mkdtemp, minimumReleaseAge is propagated from the root pnpm-workspace.yaml into the generated one (defense in depth), and assertLockNotDrifted() compares the produced lockfile's non-@Conciv package-catalog keys against the committed ones after install, throwing and naming the drifted packages if a plain install ever re-resolves one. Regenerate the committed lockfile via `pnpm --filter conciv-e2e-nextjs run update-packed-lockfile` (packed/update-lockfile.ts), which reuses setupFixture({fresh: true}) — one code path, not a parallel copy. CONCIV_PACKED_FRESH=1 (or setupFixture({fresh: true})) skips both the lockfile copy-in and the drift guard for a true consumer fresh-resolve. fixture-lock.yaml is machine-generated pnpm output; oxfmt now ignores it (oxfmt reflowed it, corrupting the packages:/snapshots: structure the drift guard parses). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 5 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
Comment |
Problem
The packed nextjs e2e (
e2e/nextjs/packed/harness.ts) installs its tmp fixture app with a live registry resolve — deliberately consumer-like, but it means a third-party publish can flip CI red with zero repo changes. That happened on 2026-08-09:@orpc/tanstack-query@1.15.0split the exact-peer-pinned orpc pair (fixed by #375) and cost hours of cross-run log archaeology to attribute.Fix
Deterministic-by-default, pnpm-native:
e2e/nextjs/packed/fixture-lock.yamlis committed and copied into the tmp workspace before install. Spike-proven semantics: plainpnpm installwith a lockfile present keeps lockfile-resolved registry versions even when newer versions satisfy the range, and refreshes only the changed local-tgz integrity. (--no-frozen-lockfileis required because the harness env setsCI=true, which auto-freezes, and the@concivtgz override paths differ per run.)<root>/tgz/dir instead of a random mkdtemp.pnpm --filter conciv-e2e-nextjs run update-packed-lockfile(reuses the same harness code path with a fresh resolve).minimumReleaseAge: 2880now propagates into the generated tmp workspace.CONCIV_PACKED_FRESH=1skips the lockfile for a true consumer fresh-resolve (future nightly).Verification
packed-closure.spec.ts: catalog-key extraction, drift guard passing clean, drift guard throwing with the drifted package named. 5/5 green.setupFixture()resolved@orpc/tanstack-query@1.14.7from the committed entry; doctoring the committed entry made the guard throw as designed.typecheck:affected36/36, e2e package build 37/37, fallow audit pass.🤖 Generated with Claude Code