Skip to content

Commit b687bf9

Browse files
authored
ci: cache resolved Node.js version in CI (#7536)
Use actions/cache to store the exact Node.js version resolved by setup-node, avoiding redundant HTTP manifest lookups across many parallel jobs per run. The cache key rotates every 20 minutes so new patches are picked up regularly. On cache hit, the exact version is passed to setup-node with check-latest disabled. On miss, check-latest resolves the latest patch and persists it for subsequent runs.
1 parent ec08cdd commit b687bf9

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

.github/actions/node/action.yml

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,54 @@ inputs:
88
runs:
99
using: composite
1010
steps:
11-
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
12-
with:
13-
node-version: ${{
11+
# Resolve the version from the input alias so we can use it in cache keys.
12+
- name: Resolve Node.js version
13+
id: node-version
14+
env:
15+
NODE_VERSION: ${{
1416
inputs.version == 'eol' && '16' ||
1517
inputs.version == 'oldest' && '18' ||
1618
inputs.version == 'maintenance' && '20' ||
1719
inputs.version == 'active' && '22' ||
1820
inputs.version == 'latest' && (env.LATEST_VERSION || '24') ||
1921
inputs.version }}
20-
check-latest: true
22+
shell: bash
23+
run: echo "version=$NODE_VERSION" >> "$GITHUB_OUTPUT"
24+
25+
# Cache a tiny file containing the exact Node.js version resolved by a previous run.
26+
# Key rotates every 20 minutes (epoch / 1200) so patches are picked up regularly.
27+
# On cache hit, we pass the exact version to setup-node and skip the HTTP manifest lookup.
28+
- name: Compute cache key
29+
id: cache-key
30+
shell: bash
31+
run: echo "block=$(( $(date -u +%s) / 1200 ))" >> "$GITHUB_OUTPUT"
32+
- uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
33+
id: node-version-cache
34+
with:
35+
path: /tmp/.node-resolved-version
36+
key: node-resolved-${{ runner.os }}-${{ runner.arch }}-v${{ steps.node-version.outputs.version }}-${{ steps.cache-key.outputs.block }}
37+
restore-keys: node-resolved-${{ runner.os }}-${{ runner.arch }}-v${{ steps.node-version.outputs.version }}-
38+
- name: Read cached version
39+
id: cached
40+
shell: bash
41+
run: |
42+
if [ -f /tmp/.node-resolved-version ]; then
43+
echo "version=$(cat /tmp/.node-resolved-version)" >> "$GITHUB_OUTPUT"
44+
fi
45+
46+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
47+
with:
48+
# Use the exact cached version when available, otherwise fall back to the requested version.
49+
node-version: ${{ steps.cached.outputs.version || steps.node-version.outputs.version }}
50+
# Resolve the latest patch on master when no cached version exists.
51+
check-latest: ${{ steps.cached.outputs.version == '' }}
2152
registry-url: ${{ inputs.registry-url || 'https://registry.npmjs.org' }}
53+
54+
# Persist the resolved version so subsequent runs within this 20-minute window can reuse it.
55+
- name: Save resolved version
56+
if: steps.node-version-cache.outputs.cache-hit != 'true'
57+
shell: bash
58+
run: node -v | tr -d 'v' > /tmp/.node-resolved-version
2259
# Avoid GitHub REST API tag lookups (api.github.com/.../git/refs/tags) which can hit installation rate limits
2360
# in large orgs / high-parallelism workflows. Instead, use a direct release asset URL.
2461
#

0 commit comments

Comments
 (0)