Visitar URL original
feat: read pnpm version from devEngines.packageManager by zkochan · Pull Request #211 · pnpm/action-setup · GitHub
Skip to content

feat: read pnpm version from devEngines.packageManager - #211

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

zkochan merged 2 commits into
masterfrom
dev-engines-pm

Conversation

@zkochan

@zkochan zkochan commented Mar 16, 2026

Copy link
Copy Markdown
Member

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 <noreply@anthropic.com>
@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

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

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==",

Copilot AI Mar 27, 2026

Copy link

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

unresolved comment is an unaddressed, valid concern

Comment thread .github/workflows/test.yaml Outdated
run: which pnpm; which pnpx

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

Copilot AI Mar 27, 2026

Copy link

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

image

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,

Copilot AI Mar 27, 2026

Copy link

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

unresolved comment is an unaddressed, valid concern

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

Copilot AI Mar 27, 2026

Copy link

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
}

Copilot AI Mar 27, 2026

Copy link

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)

Copilot AI Mar 27, 2026

Copy link

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
Comment thread src/install-pnpm/run.ts
// pnpm v11 requires Node >= 22.13; use standalone (exe) bootstrap which
// bundles its own Node.js when the system Node is too old
const systemNode = await getSystemNodeVersion()
const standalone = inputs.standalone || systemNode.major < 22 || (systemNode.major === 22 && systemNode.minor < 13)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

How about report a misconfiguration as an error instead of ignoring user input?

zkochan pushed a commit that referenced this pull request Aug 3, 2026
theinditector pushed a commit to IndicoDataSolutions/pnpm-action-setup that referenced this pull request Oct 28, 2026
* fix: update pnpm to v11.7.0 (pnpm#267)

* fix: update pnpm to v11.7.0

* fix: update bundle

* docs(README): point users to the successor pnpm/setup action (pnpm#282)

* docs(README): point users to the successor pnpm/setup action

The pnpm setup action has moved to `pnpm/setup`, which installs
pnpm v11+ as a self-contained native executable and can install a
JavaScript runtime (Node.js, Bun, or Deno) in the same step,
replacing `actions/setup-node`.

Add a notice at the top of the README, a migration section with a
before/after workflow example and an input/output mapping table,
and mention the successor in the Notes section. The rest of the
docs stay intact since `pnpm/action-setup` remains the way to
install pnpm v10 and older.

Signed-off-by: Kevin Cui <bh@bugs.cc>

* docs(README): address review feedback on migration section

Add an explicit version: 11 to the migration example and note when the
input can be omitted, since pnpm/setup requires pnpm v11+ and a repo
migrating from version: 10 may have no packageManager field or one that
pins v10.

Move the v2 upgrade warning below the page title so the two callouts
are no longer adjacent blockquotes (markdownlint MD028), keeping the
successor notice and the legacy warning as separate blocks.

Fix the comma splice and use "set up" as the verb in the Notes
section.

Signed-off-by: Kevin Cui <bh@bugs.cc>

---------

Signed-off-by: Kevin Cui <bh@bugs.cc>

* refactor: introduce restore keys for cache (pnpm#280)

* ci: use pnpm 11 for `pr-check` (pnpm#284)

Noticed while working on pnpm#283.

* fix: update pnpm to v11.19.0 (pnpm#283)

* fix: update pnpm to v11.19.0

Via `scripts/update-bootstrap.mjs 11.19.0`

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

* fixup! fix: update pnpm to v11.19.0

As it needs to be rebuilt on Linux.

---------

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

* docs: Update README to include devEngines.packageManager (pnpm#273)

Support added in pnpm#211 and pnpm#256

* feat: support pnpm v12 (pnpm#288)

* feat: support pnpm v12

Approve the pinned @pnpm/exe install script for npm 12, add pnpm 12 coverage across supported runner platforms, and clarify that action-setup remains supported alongside pnpm/setup.

* refactor: use pnpm 12 native bootstrap

Install the plain pnpm v12 package as the single native bootstrap, remove the legacy @pnpm/exe lockfile and runtime path, and retain the standalone input as a no-op for workflow compatibility.

* fix: keep bootstrap updates on pnpm 12

Handle npm's array-shaped view output and resolve only pnpm 12 distribution tags.

* fix: use native bootstrap only for pnpm 12

Route pnpm 12-only versions and ranges through the plain pnpm native package while preserving the existing Node and @pnpm/exe bootstrap paths for older releases.

* style: remove updater narrative comments

---------

Signed-off-by: Kevin Cui <bh@bugs.cc>
Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Kevin Cui <github@bugs.cc>
Co-authored-by: Sukka <isukkaw@gmail.com>
Co-authored-by: Jamie Tanna <github@jamietanna.co.uk>
Co-authored-by: Jamie Tanna <jamie@jamietanna.co.uk>
Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Eric Nemchik <eric@nemchik.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