Skip to content

fix(cli): support pnpm 12 multi-document lockfiles [RED-939] [ship] - #1476

Merged
sorccu merged 3 commits into
mainfrom
simo/red-939-pnpm12-multidoc-lockfile
Sep 8, 2026
Merged

sorccu merged 3 commits into
mainfrom
simo/red-939-pnpm12-multidoc-lockfile

Conversation

@sorccu

@sorccu sorccu commented Sep 8, 2026

Copy link
Copy Markdown
Member

Linear: RED-939

pnpm 12 writes pnpm-lock.yaml as two YAML documents when package.json pins a packageManager: a leading environment document that records pnpm's own dependencies, then the application document. Every pnpm lockfile consumer in the CLI parsed the file as a single document, which the yaml package rejects with Source contains multiple documents. On such a lockfile:

  • Playwright version detection silently fell back to node_modules instead of the lockfile.
  • Lockfile pruning was skipped with a "not pruned" note, and would also have failed on the regenerated lockfile.
  • Patched-dependency filtering after a prune was a silent no-op.
  • bundle.packages.embed failed with a fatal "Unsatisfied local prerequisites" diagnostic.

The same bug in the Terraform provider was fixed in checkly/terraform-provider-checkly#393 (v1.29.0).

Changes

  • New splitPnpmLockfileDocuments / joinPnpmLockfileDocuments helper that mirrors pnpm's own textual reader: a leading --- introduces an environment document up to the next ---; everything after it is the application document.
  • parsePnpmLockfileVersion, parsePnpmLockfilePackages, the pruner's parseLockfileSnapshot, and readLockfilePatchHashes now parse only the application document.
  • The post-prune lockfile rewrite goes through a new rewriteLockfileSection, which edits the application document and carries the environment document over verbatim so pnpm still finds it in the bundle. pnpm-workspace.yaml keeps using the single-document rewriteYamlSection, since a leading --- there is an ordinary document-start marker.

Affected Components

  • CLI
  • Test

Notes for the Reviewer

  • A lockfile generated by pnpm 12.3.4 is committed as a fixture and round-tripped byte for byte by the helper spec. Each consumer has a two-document spec case; all of them fail without the source change.
  • Verified end to end with checkly debug parse-project on a pnpm 12 workspace: the Playwright version resolves from the lockfile, the bundled lockfile is pruned and still starts with the environment document, and embedded packages materialize with no diagnostic.
  • The fixture directory is pinned -text in .gitattributes (like *.patch already is), because the byte-for-byte round-trip cannot hold on an autocrlf checkout on Windows.
  • Out of scope: the pruner relies on the PATH pnpm auto-switching to the pinned version rather than honouring packageManager itself.

🤖 Generated with Claude Code

sorccu and others added 3 commits September 8, 2026 20:53
pnpm 12 writes pnpm-lock.yaml as two YAML documents when package.json
pins a packageManager: a leading environment document that records
pnpm's own dependencies, then the application document. The `yaml`
package rejects multi-document input, so every consumer needs the
application document on its own.

Add splitPnpmLockfileDocuments and joinPnpmLockfileDocuments, which
mirror pnpm's own textual reader (leading `---` marks an environment
document up to the next `---`), with a spec and a lockfile generated by
pnpm 12.3.4 as a fixture.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pnpm 12 writes pnpm-lock.yaml as two YAML documents when package.json
pins a packageManager: an environment document for pnpm itself, then
the application document. Every consumer parsed the file as a single
document, which the `yaml` package rejects, so on such a lockfile
Playwright version detection silently fell back to node_modules,
lockfile pruning was skipped, patched-dependency filtering became a
no-op, and `bundle.packages.embed` failed with a fatal diagnostic.

Parse only the application document at each site, and keep the
environment document verbatim when the lockfile is rewritten after a
prune. pnpm-workspace.yaml keeps going through the single-document
rewrite, because a leading `---` there is an ordinary document-start
marker rather than a separate document.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…D-939]

The fixture is asserted to round-trip byte for byte through the
document splitter, which normalizes CRLF to LF. Git's autocrlf on the
Windows runner checked it out with CRLF, so the assertion could never
hold there. Pin the fixture directory with `-text`, as the repo already
does for patch files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@sorccu sorccu changed the title fix(cli): support pnpm 12 multi-document lockfiles [RED-939] fix(cli): support pnpm 12 multi-document lockfiles [RED-939] [ship] Sep 8, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Auto-approved: ship/show PR from a same-repo branch.

@sorccu
sorccu merged commit 42d0b4b into main Sep 8, 2026
18 checks passed
@sorccu
sorccu deleted the simo/red-939-pnpm12-multidoc-lockfile branch September 8, 2026 12:43
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.

1 participant