Skip to content

feat: read pnpm version from devEngines.packageManager#211

Merged
zkochan merged 2 commits intomasterfrom
dev-engines-pm
Mar 27, 2026
Merged

feat: read pnpm version from devEngines.packageManager#211
zkochan merged 2 commits intomasterfrom
dev-engines-pm

Conversation

@zkochan
Copy link
Copy Markdown
Member

@zkochan zkochan commented Mar 16, 2026

Summary

  • When no version is specified in the action config or the packageManager field of package.json, fall back to reading devEngines.packageManager from package.json
  • Supports the { "name": "pnpm", "version": "..." } syntax used by pnpm v11+

Test plan

  • Test with a repo that has devEngines.packageManager in package.json and no packageManager field
  • Test that packageManager field still takes precedence over devEngines.packageManager
  • Test that action config version still takes precedence over both

🤖 Generated with Claude Code

When no version is specified in the action config or the packageManager
field of package.json, fall back to devEngines.packageManager.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@zkochan zkochan force-pushed the dev-engines-pm branch 10 times, most recently from 9504ec4 to 949c415 Compare March 27, 2026 01:24
@zkochan zkochan marked this pull request as ready for review March 27, 2026 09:11
@zkochan zkochan requested a review from Copilot March 27, 2026 09:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the pnpm setup action to tolerate pnpm v11+ devEngines.packageManager configuration when determining whether to self-update pnpm, and adjusts bootstrapping to account for pnpm v11’s Node engine requirements.

Changes:

  • Auto-selects standalone (@pnpm/exe) bootstrap when the system node is older than the required major version.
  • Extends manifest parsing to consider devEngines.packageManager and updates the “no version specified” error message accordingly.
  • Pins bootstrap lockfiles to pnpm/@pnpm/exe 11.0.0-beta.3 and adds a CI workflow job covering devEngines.packageManager.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.

File Description
src/install-pnpm/run.ts Adds system-Node-based standalone selection and recognizes devEngines.packageManager during version resolution.
src/install-pnpm/bootstrap/pnpm-lock.json Updates bootstrap pnpm dependency to 11.0.0-beta.3 (engine >=22.13).
src/install-pnpm/bootstrap/exe-lock.json Updates bootstrap @pnpm/exe dependency to 11.0.0-beta.3 (plus new dependency tree).
.github/workflows/test.yaml Adds a workflow job to exercise devEngines.packageManager scenarios.

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

Comment on lines +8 to +14
"pnpm": "11.0.0-beta.3"
}
},
"node_modules/pnpm": {
"version": "10.32.1",
"resolved": "https://registry.npmjs.org/pnpm/-/pnpm-10.32.1.tgz",
"integrity": "sha512-pwaTjw6JrBRWtlY+q07fHR+vM2jRGR/FxZeQ6W3JGORFarLmfWE94QQ9LoyB+HMD5rQNT/7KnfFe8a1Wc0jyvg==",
"version": "11.0.0-beta.3",
"resolved": "https://registry.npmjs.org/pnpm/-/pnpm-11.0.0-beta.3.tgz",
"integrity": "sha512-6PrfRjycZV4vRX6ttG9oR6pOgbI2/OcF2QLOzHm35UcRuvtqP4zf3wQfAAPwEbeu1uAbpSg/Q5cL8h32tumy6Q==",
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

Bootstrap pnpm is being pinned to a pre-release (11.0.0-beta.3). This increases operational risk (unexpected breaking changes, yanked pre-releases) for every action run because the bootstrap version is always installed before any self-update/version selection. If possible, prefer a stable pnpm/@pnpm/exe version, or gate use of the v11 bootstrap to only when devEngines.packageManager is detected (keeping the stable bootstrap for the common path).

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/test.yaml Outdated
run: which pnpm; which pnpx

- name: 'Test: version'
run: pnpm --version
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

The new test_dev_engines job currently only prints pnpm --version and doesn’t assert that the version selected actually satisfies the devEngines.packageManager.version value (especially for the >=9.15.0 case). Adding an explicit assertion here would prevent regressions where the action installs/keeps the bootstrap pnpm version but ignores devEngines.packageManager.

Suggested change
run: pnpm --version
run: |
set -e
required='${{ matrix.version }}'
actual="$(pnpm --version)"
echo "pnpm version: ${actual}"
if [ "${required}" = ">=9.15.0" ]; then
min="9.15.0"
if [ "$(printf '%s\n' "${min}" "${actual}" | sort -V | head -n1)" != "${min}" ]; then
echo "Expected pnpm version >= ${min}, but got ${actual}"
exit 1
fi
else
if [ "${actual}" != "${required}" ]; then
echo "Expected pnpm version ${required}, but got ${actual}"
exit 1
fi
fi

Copilot uses AI. Check for mistakes.
Comment on lines +8 to 15
"@pnpm/exe": "11.0.0-beta.3"
}
},
"node_modules/@pnpm/exe": {
"version": "10.32.1",
"resolved": "https://registry.npmjs.org/@pnpm/exe/-/exe-10.32.1.tgz",
"integrity": "sha512-baEtwHeZwmZAdBuuDDL6tbdGg5KpxhPxr3QFfYTGXvY6ws+Z1bN0mQ7ZjcaXBSC1HuLpVXnZ6NsBiaZ2DMv4vg==",
"version": "11.0.0-beta.3",
"resolved": "https://registry.npmjs.org/@pnpm/exe/-/exe-11.0.0-beta.3.tgz",
"integrity": "sha512-yWNlHHdYmvf4c0MCkCzAa4csJDPdA+7yJCbXBUDXMbUu/0Zv/AxtO77q24MwlnBUC0dWeA+0F/pPmdkR9aTV2A==",
"hasInstallScript": true,
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

@pnpm/exe is also pinned to the pnpm v11 pre-release (11.0.0-beta.3). Since this is the fallback path for older system Node versions, any instability or packaging changes in the beta can impact a large set of users. Consider pinning to a stable release when available, or documenting why a beta is required.

Copilot uses AI. Check for mistakes.
Comment thread src/install-pnpm/run.ts Outdated
Comment on lines +18 to +21
// pnpm v11 requires Node >= 22; use standalone (exe) bootstrap which
// bundles its own Node.js when the system Node is too old
const systemNodeVersion = await getSystemNodeVersion()
const standalone = inputs.standalone || systemNodeVersion < 22
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

standalone is now auto-disabled when node --version reports major >= 22, which means the non-standalone bootstrap path will be used. However pnpm-lock.json was updated to pnpm v11 where the package bin points to bin/pnpm.mjs, while this installer still later references .../pnpm/bin/pnpm.cjs for the non-standalone bootstrap/symlink. This will break the action when standalone is false. Update the non-standalone bootstrap paths to match the pnpm v11 bin (or derive the bin entry dynamically) so Node>=22 runs correctly.

Copilot uses AI. Check for mistakes.
Comment thread src/install-pnpm/run.ts
Comment on lines +110 to +113
// pnpm will automatically download and switch to the right version
if (typeof packageManager === 'string' && packageManager.startsWith('pnpm@')) {
// Strip the "pnpm@" prefix and any "+sha..." hash suffix
return packageManager.replace('pnpm@', '').replace(/\+.*$/, '')
return undefined
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

readTargetVersion no longer returns the version from packageManager: "pnpm@..." and instead returns undefined. That regresses the documented behavior of omitting the version input to install the packageManager-specified pnpm version, and may lead to ERR_PNPM_BAD_PM_VERSION if the bootstrap pnpm version differs. Consider restoring parsing of packageManager (including stripping any +sha... suffix) to return a target version for self-update, and only falling back to devEngines.packageManager when packageManager is absent.

Copilot uses AI. Check for mistakes.
Comment thread src/install-pnpm/run.ts Outdated
Comment on lines +137 to +140
cp.stdout.on('data', (data: Buffer) => { output += data.toString() })
cp.on('close', () => {
const match = output.match(/^v(\d+)/)
resolve(match ? parseInt(match[1], 10) : 0)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

getSystemNodeVersion() only parses the major version and the standalone decision uses < 22, but the pinned pnpm bootstrap in pnpm-lock.json declares engines.node >= 22.13. With Node 22.0–22.12 this would incorrectly pick the non-standalone path and could fail at runtime. Parse the full Node semver (major/minor/patch) and compare against the actual minimum supported version (e.g. 22.13.0), or otherwise ensure the threshold matches the engine requirement.

Suggested change
cp.stdout.on('data', (data: Buffer) => { output += data.toString() })
cp.on('close', () => {
const match = output.match(/^v(\d+)/)
resolve(match ? parseInt(match[1], 10) : 0)
cp.stdout.on('data', (data: Buffer) => {
output += data.toString()
})
cp.on('close', () => {
const match = output.trim().match(/^v(\d+)\.(\d+)\.(\d+)/)
if (!match) {
resolve(0)
return
}
const major = parseInt(match[1], 10)
const minor = parseInt(match[2], 10)
// Align the effective ">= 22" threshold with pnpm's engines.node >= 22.13.0.
// Treat Node 22.0–22.12 as effectively below 22 so that a `< 22` check remains correct.
if (major === 22 && minor < 13) {
resolve(21)
return
}
resolve(major)

Copilot uses AI. Check for mistakes.
pnpm auto-switches to the right version when devEngines.packageManager
is set, so self-update is unnecessary. This also enables range support
(e.g. ">=9.15.0") which self-update doesn't handle.
@zkochan zkochan merged commit 994d756 into master Mar 27, 2026
40 of 41 checks passed
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.

2 participants