fix(@pnpm/exe): preserve relative symlinks when packaging dist/#11399
Merged
Conversation
The standalone executable build copies dist/ via fs.cpSync(...) without verbatimSymlinks: true, which causes Node to resolve relative symlinks into absolute paths at the source filesystem location. On the GitHub Actions runner this rewrites .bin symlinks to /home/runner/work/pnpm/... targets that ship verbatim in the release tarballs. Adding verbatimSymlinks: true preserves the relative symlink targets so the archived links remain valid at any extraction location. Fixes pnpm#11398. 🤖 Generated with [Amp](https://ampcode.com) Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff Co-authored-by: Amp <amp@ampcode.com>
2 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes @pnpm/exe artifact packaging so symlinks under dist/node_modules/.bin/ remain relative when dist/ is copied into the package directory, preventing release tarballs from containing broken build-host absolute symlinks (per #11398).
Changes:
- Pass
verbatimSymlinks: truetofs.cpSyncin the exe artifact build script to preserve symlink targets verbatim. - Add a changeset to publish a patch release of
@pnpm/exedocumenting the fix.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pnpm/artifacts/exe/scripts/build-artifacts.ts | Preserves relative symlinks when copying dist/ into @pnpm/exe for packaging. |
| .changeset/exe-build-verbatim-symlinks.md | Adds a patch changeset describing the symlink preservation fix and its impact. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
zkochan
approved these changes
Apr 29, 2026
zkochan
approved these changes
Apr 29, 2026
Member
|
add unextractable to cspell.json |
Per pnpm#11399 (comment) 🤖 Generated with [Amp](https://ampcode.com) Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff Co-authored-by: Amp <amp@ampcode.com>
Contributor
Author
|
Done in 7152521 — added 🤖 |
|
Congrats on merging your first pull request! 🎉🎉🎉 |
zkochan
pushed a commit
that referenced
this pull request
Apr 30, 2026
* fix(@pnpm/exe): preserve relative symlinks when packaging dist/ The standalone executable build copies dist/ via fs.cpSync(...) without verbatimSymlinks: true, which causes Node to resolve relative symlinks into absolute paths at the source filesystem location. On the GitHub Actions runner this rewrites .bin symlinks to /home/runner/work/pnpm/... targets that ship verbatim in the release tarballs. Adding verbatimSymlinks: true preserves the relative symlink targets so the archived links remain valid at any extraction location. Fixes #11398. 🤖 Generated with [Amp](https://ampcode.com) Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff Co-authored-by: Amp <amp@ampcode.com> * chore: add 'unextractable' to cspell.json Per #11399 (comment) 🤖 Generated with [Amp](https://ampcode.com) Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com>
zkochan
pushed a commit
that referenced
this pull request
Apr 30, 2026
…rballs) (#11408) #11399 fixed the fs.cpSync call in pnpm/artifacts/exe/scripts/build-artifacts.ts, which controls the dist/ shipped inside the npm-published @pnpm/exe package. But the GitHub release tarballs (pnpm-{darwin,linux}-{x64,arm64}.tar.gz) are produced by a different script — __utils__/scripts/src/copy-artifacts.ts, run via 'pn copy-artifacts' in the release workflow. That script has the same fs.cpSync(...) call without verbatimSymlinks: true, so the broken absolute symlinks under dist/node_modules/.bin/ pointing at /home/runner/work/pnpm/ pnpm/... still made it into the v11.0.2 GitHub release tarballs. Apply the same one-line fix to that script so the next release ships clean relative symlinks. Follow-up to #11398. 🤖 Generated with [Amp](https://ampcode.com) Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff Co-authored-by: Amp <amp@ampcode.com>
zkochan
pushed a commit
that referenced
this pull request
Apr 30, 2026
…rballs) (#11408) #11399 fixed the fs.cpSync call in pnpm/artifacts/exe/scripts/build-artifacts.ts, which controls the dist/ shipped inside the npm-published @pnpm/exe package. But the GitHub release tarballs (pnpm-{darwin,linux}-{x64,arm64}.tar.gz) are produced by a different script — __utils__/scripts/src/copy-artifacts.ts, run via 'pn copy-artifacts' in the release workflow. That script has the same fs.cpSync(...) call without verbatimSymlinks: true, so the broken absolute symlinks under dist/node_modules/.bin/ pointing at /home/runner/work/pnpm/ pnpm/... still made it into the v11.0.2 GitHub release tarballs. Apply the same one-line fix to that script so the next release ships clean relative symlinks. Follow-up to #11398. 🤖 Generated with [Amp](https://ampcode.com) Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff Co-authored-by: Amp <amp@ampcode.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.
Closes #11398.
Problem
The v11 standalone executable release tarballs (
pnpm-{darwin,linux}-{x64,arm64}.tar.gz) ship 4 broken absolute symlinks underdist/node_modules/.bin/:The
/home/runner/work/pnpm/pnpm/...paths leak the GitHub Actions runner's filesystem layout into a public artifact, and the symlinks are dangling on every user's machine. Lenient extractors (get.pnpm.io/install.sh, npm, corepack, asdf, etc.) silently extract them as dangling — pnpm itself never traverses these paths at runtime, so the bug has been invisible. Strict extractors that validate symlink targets (hermit is the one that surfaced this) refuse to extract the tarball entirely.See #11398 for the full investigation and reproducer.
Root cause
pnpm/artifacts/exe/scripts/build-artifacts.tscopies the repo'sdist/into the@pnpm/exepackage directory with:Node's
fs.cpSyncdefaults toverbatimSymlinks: false, which resolves relative symlinks into absolute paths at the source filesystem location during the copy. So a relative link in the pnpm repo (dist/node_modules/.bin/node-gyp -> ../node-gyp/bin/node-gyp.js) gets rewritten to an absolute/home/runner/work/pnpm/pnpm/pnpm/dist/...link in the destination directory that subsequently gets archived. See nodejs/node#41693 for the underlying Node behavior.Fix
Add
verbatimSymlinks: trueto thefs.cpSyncoptions. This preserves relative symlinks verbatim so the archived links stay valid at any extraction location.Testing
The build script runs in CI on every release, so the next release will demonstrate the fix. Locally I can't easily exercise the full release pipeline, but the change is a one-line option flag well-documented in the Node.js docs.
🤖 Generated with Amp