Skip to content

fix: also preserve relative symlinks in copy-artifacts.ts (release tarballs)#11408

Merged
zkochan merged 1 commit into
pnpm:mainfrom
comp615:fix/copy-artifacts-verbatim-symlinks
Apr 30, 2026
Merged

fix: also preserve relative symlinks in copy-artifacts.ts (release tarballs)#11408
zkochan merged 1 commit into
pnpm:mainfrom
comp615:fix/copy-artifacts-verbatim-symlinks

Conversation

@comp615

@comp615 comp615 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #11399 / #11398.

TL;DR

#11399 fixed the wrong file. The same one-line verbatimSymlinks: true fix needs to be applied to __utils__/scripts/src/copy-artifacts.ts to actually clean up the GitHub release tarballs.

Why #11399 wasn't enough

The pnpm release pipeline produces two distinct sets of artifacts that each have their own copy of dist/:

Artifact Built by fs.cpSync location
npm-published @pnpm/exe package pn buildbuild-artifacts.ts pnpm/artifacts/exe/scripts/build-artifacts.ts:48 ✅ fixed in #11399
GitHub release tarballs (pnpm-{darwin,linux}-{x64,arm64}.tar.gz) pn copy-artifacts (in release.yml) → copy-artifacts.ts __utils__/scripts/src/copy-artifacts.ts:51 ❌ still broken

Both files do roughly the same thing — copy pnpmDistDir into a per-target dist/ for archiving — but copy-artifacts.ts is what actually creates the .tar.gz and .zip archives uploaded to the GitHub release page.

Verification

After #11399 merged and v11.0.2 was cut, I re-ran the original reproducer:

$ curl -sL https://github.com/pnpm/pnpm/releases/download/v11.0.2/pnpm-darwin-arm64.tar.gz | tar -tvz | grep '^l'
lrwxrwxrwx  0 runner 1001  0 Apr 30 11:24 dist/node_modules/.bin/node-gyp    -> /home/runner/work/pnpm/pnpm/pnpm/dist/node_modules/node-gyp/bin/node-gyp.js
lrwxrwxrwx  0 runner 1001  0 Apr 30 11:24 dist/node_modules/.bin/node-which  -> /home/runner/work/pnpm/pnpm/pnpm/dist/node_modules/which/bin/which.js
lrwxrwxrwx  0 runner 1001  0 Apr 30 11:24 dist/node_modules/.bin/nopt        -> /home/runner/work/pnpm/pnpm/pnpm/dist/node_modules/nopt/bin/nopt.js
lrwxrwxrwx  0 runner 1001  0 Apr 30 11:24 dist/node_modules/.bin/semver      -> /home/runner/work/pnpm/pnpm/pnpm/dist/node_modules/semver/bin/semver.js

Same broken absolute symlinks as v11.0.0 / v11.0.1. Source maps timestamp confirms these are from the v11.0.2 build run.

The source code at the v11.0.2 tag has the build-artifacts.ts fix applied correctly — but the release tarballs come from copy-artifacts.ts, which still has the unfixed call.

Fix

-    fs.cpSync(pnpmDistDir, distDest, { recursive: true })
+    fs.cpSync(pnpmDistDir, distDest, { recursive: true, verbatimSymlinks: true })

Same rationale as #11399: Node's fs.cpSync defaults to verbatimSymlinks: false, which resolves relative symlinks into absolute paths at the source filesystem location. On the GitHub Actions runner this rewrites the .bin symlinks to /home/runner/work/pnpm/... targets that ship verbatim in the tarball.

Apologies

Sorry for the incomplete fix — I should have grepped for all fs.cpSync callers in the release pipeline before opening #11399, not just the one I'd already pinpointed in my issue. Confirmed via grep -r 'fs\.cpSync' that these are now the only two callers and both have verbatimSymlinks: true after this PR.

🤖 Generated with Amp

…rballs)

pnpm#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 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>
Copilot AI review requested due to automatic review settings April 30, 2026 15:50
@comp615 comp615 requested a review from zkochan as a code owner April 30, 2026 15:50
@welcome

welcome Bot commented Apr 30, 2026

Copy link
Copy Markdown

💖 Thanks for opening this pull request! 💖
Please be patient and we will get back to you as soon as we can.

Copilot AI 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.

Pull request overview

This PR fixes how the GitHub Release tarball artifacts are assembled by ensuring fs.cpSync preserves relative symlinks when copying pnpm/dist into the per-target artifact dist/ directory, preventing absolute /home/runner/... symlink targets from being baked into published archives.

Changes:

  • Update __utils__/scripts/src/copy-artifacts.ts to call fs.cpSync with { verbatimSymlinks: true }.
  • Add a Changesets entry documenting the fix and its relation to the earlier incomplete fix in #11399.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
__utils__/scripts/src/copy-artifacts.ts Preserves relative symlinks during the dist/ copy step used to build GitHub release archives.
.changeset/copy-artifacts-verbatim-symlinks.md Adds a patch-level Changesets note describing the release-tarball symlink preservation fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@zkochan zkochan merged commit b2c7489 into pnpm:main Apr 30, 2026
11 of 12 checks passed
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>
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.

3 participants