Front the provisioned Node on the global PATH (setup-node executable parity)#5
Merged
Conversation
… auth re-export Previously the action provisioned Node into nub's cache but never added its bin dir to the global PATH, so bare node/npm/npx/corepack in later steps resolved to the runner's preinstalled Node rather than the specified version — diverging from actions/setup-node, whose toolcache bin dir IS PATH-fronted. - Front the nub-resolved Node bin dir onto $GITHUB_PATH. The dir is derived at runtime from `nub node which` (never a hardcoded cache path) and is correct on every OS by construction: dirname of the resolved node binary (POSIX bin/node, Windows node.exe at the version root). The stderr resolution reason is the OS-independent discriminator for host-fallback (skip fronting) vs a managed Node (front it). An explicit node-version/node-version-file is authoritative for the PATH front (matching setup-node); nub still runs the project pin at invocation time and warns on a mismatch. The bin dir is fronted ahead of nub's own bin so real npm/npx win. - node-version output is now empty on host fallback (nothing provisioned) instead of leaking the runner's host version, matching the documented contract. - Register the same three problem matchers setup-node ships (tsc, eslint-stylish, eslint-compact) so tsc/eslint output surfaces as inline annotations. - Re-export NODE_AUTH_TOKEN to the env when present (matching setup-node authutil), via the heredoc form and masked from logs. - Correct the .npmrc 'byte-for-byte' claim to 'functionally equivalent' in the action comment and README (line order differs; npm parses both identically). - Add a 3-OS differential smoke job asserting bare node/npm/npx resolve to the specified version inside the fronted dir (plus npm i -g reachability), against an actions/setup-node control.
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.
Why
setup-nubadvertises a drop-in foractions/setup-node, but it never put the provisioned Node's bin dir on the globalPATH.actions/setup-nodedoes (core.addPath(<toolcache>/node/<ver>/bin)), so barenode/npm/npx/corepackin downstream steps resolve to the specified version. Undersetup-nubthey resolved to the runner's preinstalled Node — non-deterministic across images and not the requested version. This closes that gap so a swap ofactions/setup-node@v4→nubjs/setup-nub@v0leaves later steps that call barenode/npmbehaving the same.What changed
$GITHUB_PATH. The dir is derived at runtime fromnub node which(never a hardcoded cache path) and is correct on every OS by construction —dirnameof the resolved node binary (POSIX<root>/bin/node; Windowsnode.exeat the version root, confirmed against nub's source). The bin dir is fronted ahead of nub's own bin so realnpm/npxwin over any nub PM shim.nub node whichprints the resolution reason on stderr;resolved from node on PATHmeans nub fell back to the runner's host Node (nothing provisioned) — in that case nothing is fronted (and thenode-versionoutput is empty, matching the documented contract, rather than leaking the host version).node-version/node-version-fileis authoritative for the PATH (matching setup-node): it is provisioned and fronted even when the project's own pin differs.nubitself still runs the project pin at invocation time and the action warns on a mismatch.NODE_AUTH_TOKENre-export. Mirrors setup-node's authutil: when present, re-exported to the env (heredoc form, masked from logs)..npmrc"byte-for-byte" claim corrected to "functionally equivalent" in the comment + README (line order differs; npm parses both identically).path-parityjob asserts barenode/npm/npxresolve to the specified version inside the fronted dir (plusnpm i -greachability and acorepackpresence probe), against anactions/setup-nodecontrol.Design notes
node/npm/npx, nothing nub-branded fronted), and consistent with nub's node-PATH-hijack contract. The version-resolving-shim alternative was considered; it only matters if the frontednodeshould re-resolve the pin dynamically mid-job, which setup-node parity does not require.resolved from node on PATH). It is a documented contract, but a nub-side test asserting that phrase would harden it; a structurednub node which --jsonsignal would remove the coupling entirely (follow-up).Verification
actionlintclean (only 4 pre-existingSC2193/SC2016template false-positives in unrelated jobs; zero new).shellcheckclean on the changedrun:blocks.nubacross 3 cases: explicitnode-versionfronts the specified version's bin + warns on pin mismatch; project-pin fronts the resolved pin; no-pin host-fallback correctly skips fronting and emits an emptynode-version.node.exe-at-version-root layout confirmed against nub source (crates/nub-core/src/node/discovery.rs,version_management/mod.rs), sodirnameis correct without OS branching.