Skip to content

Commit 5c39e00

Browse files
committed
ci: harden pnpm setup node selection
1 parent 47eb4ca commit 5c39e00

2 files changed

Lines changed: 69 additions & 14 deletions

File tree

.github/actions/setup-node-env/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ runs:
4040
id: pnpm-cache
4141
uses: ./.github/actions/setup-pnpm-store-cache
4242
with:
43+
node-version: ${{ inputs.node-version }}
4344
pnpm-version: ${{ inputs.pnpm-version }}
4445
cache-key-suffix: ${{ inputs.cache-key-suffix }}
4546

.github/actions/setup-pnpm-store-cache/action.yml

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ inputs:
55
description: pnpm version to activate via corepack.
66
required: false
77
default: "11.0.8"
8+
node-version:
9+
description: Expected Node.js version already installed by actions/setup-node.
10+
required: false
11+
default: "24.x"
812
cache-key-suffix:
913
description: Suffix appended to the cache key.
1014
required: false
@@ -41,32 +45,82 @@ runs:
4145
env:
4246
COREPACK_ENABLE_DOWNLOAD_PROMPT: "0"
4347
PNPM_VERSION: ${{ inputs.pnpm-version }}
48+
REQUESTED_NODE_VERSION: ${{ inputs.node-version }}
4449
run: |
4550
set -euo pipefail
4651
if [[ ! "$PNPM_VERSION" =~ ^[0-9]+(\.[0-9]+){1,2}([.-][0-9A-Za-z.-]+)?$ ]]; then
4752
echo "::error::Invalid pnpm-version input: '$PNPM_VERSION'"
4853
exit 2
4954
fi
50-
if [[ -n "${RUNNER_TOOL_CACHE:-}" && -n "${NODE_VERSION:-}" ]]; then
51-
requested_node="${NODE_VERSION#v}"
52-
node_tool_root="${RUNNER_TOOL_CACHE}/node"
53-
node_bin=""
54-
if [[ "$requested_node" == *x ]]; then
55-
requested_major="${requested_node%%.*}"
56-
node_bin="$(
57-
find "$node_tool_root" -path "*/bin/node" -type f 2>/dev/null |
58-
awk -F/ -v major="$requested_major" '$(NF-2) ~ ("^" major "\\.") { print }' |
59-
sort -r |
60-
head -n 1
61-
)"
62-
elif [[ -d "${node_tool_root}/${requested_node}" ]]; then
63-
node_bin="$(find "${node_tool_root}/${requested_node}" -path "*/bin/node" -type f 2>/dev/null | head -n 1)"
55+
56+
requested_node="${REQUESTED_NODE_VERSION:-${NODE_VERSION:-}}"
57+
requested_node="${requested_node#v}"
58+
59+
node_version_matches() {
60+
local actual="$1"
61+
local requested="$2"
62+
if [[ -z "$requested" ]]; then
63+
return 0
6464
fi
65+
case "$requested" in
66+
*x)
67+
[[ "${actual%%.*}" == "${requested%%.*}" ]]
68+
;;
69+
*.*.*)
70+
[[ "$actual" == "$requested" ]]
71+
;;
72+
*.*)
73+
[[ "$actual" == "$requested".* ]]
74+
;;
75+
*)
76+
[[ "${actual%%.*}" == "$requested" ]]
77+
;;
78+
esac
79+
}
80+
81+
active_node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
82+
if ! node_version_matches "$active_node_version" "$requested_node"; then
83+
node_roots=()
84+
for root in \
85+
"${RUNNER_TOOL_CACHE:-}" \
86+
"${AGENT_TOOLSDIRECTORY:-}" \
87+
"${ACTIONS_RUNNER_TOOL_CACHE:-}" \
88+
"/opt/hostedtoolcache" \
89+
"/home/runner/_work/_tool" \
90+
"/Users/runner/hostedtoolcache" \
91+
"/c/hostedtoolcache/windows"
92+
do
93+
if [[ -d "$root/node" ]]; then
94+
node_roots+=("$root/node")
95+
elif [[ "$(basename "$root")" == "node" && -d "$root" ]]; then
96+
node_roots+=("$root")
97+
fi
98+
done
99+
100+
node_bin=""
101+
for node_root in "${node_roots[@]}"; do
102+
while IFS= read -r candidate; do
103+
candidate_version="$("$candidate" -p 'process.versions.node' 2>/dev/null || true)"
104+
if node_version_matches "$candidate_version" "$requested_node"; then
105+
node_bin="$candidate"
106+
break 2
107+
fi
108+
done < <(find "$node_root" \( -name node -o -name node.exe \) -type f 2>/dev/null | sort -r)
109+
done
110+
65111
if [[ -n "$node_bin" ]]; then
112+
echo "Using Node $("$node_bin" -p 'process.versions.node') from $node_bin"
66113
export PATH="$(dirname "$node_bin"):$PATH"
67114
hash -r
68115
fi
69116
fi
117+
118+
active_node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
119+
if ! node_version_matches "$active_node_version" "$requested_node"; then
120+
echo "::error::Expected Node '${requested_node}', but active node is '${active_node_version:-missing}' at $(command -v node || true)"
121+
exit 1
122+
fi
123+
70124
node -v
71125
command -v node
72126
command -v corepack

0 commit comments

Comments
 (0)