Skip to content

Commit a44d99e

Browse files
committed
feat: require Node 24 runtime and drop unsupported old platforms
All JS actions now run on Node 24. No working glibc-217 Node 24 build exists yet (nodejs/unofficial-builds#190 has not shipped one, and the Boost mirror build crashes silently on heavy child_process operations on kernels older than 5.3), so Node 24 patching in container-bootstrap is opt-in via a node24-url input (off by default) and the CI matrix floor is raised to gcc>=9 / clang>11 — GCC<=6 / Clang<=5 require a glibc too old for Node 24. The hook is ready to re-enable old platforms the day a known-good build can be supplied via node24-url.
1 parent 9bf3fbb commit a44d99e

17 files changed

Lines changed: 109 additions & 64 deletions

File tree

.github/workflows/ci-build.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ jobs:
4848
fi
4949
# Configure safe.directory for containers (root user vs workspace owner)
5050
git config --global --add safe.directory '*'
51-
# Patch Node.js for old containers with glibc-217 volume mounts
51+
# Patch Node.js for old containers with glibc-217 volume mounts.
52+
# Only node20 is patched: no working glibc-217 Node 24 build exists yet
53+
# (the Boost mirror binary crashes on heavy child_process operations on
54+
# old kernels), so containers that require Node 24 and a glibc older than
55+
# 2.28 (GCC <= 6 / Clang <= 5) are no longer supported. See
56+
# nodejs/unofficial-builds#190.
5257
if [ -d /node20217 ] && [ -w /node20217 ]; then
5358
if ! /__e/node20/bin/node --version 2>/dev/null; then
5459
apt-get update 2>/dev/null || true

.github/workflows/ci-matrix.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ jobs:
2323
with:
2424
standards: '>=14'
2525
compilers: |
26-
gcc >=4.8 <6 || >=9
27-
clang >=3.8 <6 || >11
26+
gcc >=9
27+
clang >11
2828
msvc >=14
2929
apple-clang *
3030
mingw *

b2-workflow/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ inputs:
355355
default: '0'
356356

357357
runs:
358-
using: 'node20'
358+
using: 'node24'
359359
main: 'dist/index.js'
360360
post-if: success()
361361
branding:

boost-clone/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ outputs:
218218
description: The absolute path to the boost source files.
219219

220220
runs:
221-
using: 'node20'
221+
using: 'node24'
222222
main: 'dist/index.js'
223223
post-if: success()
224224
branding:

cmake-workflow/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ inputs:
474474
default: ''
475475

476476
runs:
477-
using: 'node20'
477+
using: 'node24'
478478
main: 'dist/index.js'
479479
post-if: success()
480480
branding:

container-bootstrap/action.yml

Lines changed: 87 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ description: |
55
This composite action handles three scenarios that arise when running GitHub Actions
66
inside Docker containers:
77
8-
1. **Node.js glibc patching** — GitHub Actions ships its own Node.js 20 binary at
9-
`/__e/node20/bin/node`, but older containers (e.g., Ubuntu 18.04) have a glibc
10-
too old for that binary. This action detects the failure and replaces the binary with
11-
an unofficial glibc-217-compatible build.
8+
1. **Node.js glibc patching** — GitHub Actions ships its own Node.js binary (Node 20 at
9+
`/__e/node20/bin/node`, Node 24 at `/__e/node24/bin/node`), but older containers
10+
(e.g., Ubuntu 18.04) have a glibc too old for those binaries. This action detects the
11+
failure and replaces the Node 20 binary with the official unofficial-builds
12+
glibc-217 build. Node 24 patching is opt-in (see `node24-url`) and disabled by
13+
default, because no working glibc-217 Node 24 build exists yet — so containers that
14+
require Node 24 and a glibc older than 2.28 (GCC <= 6 / Clang <= 5) are unsupported.
1215
2. **nektos/act support** — When running locally with https://github.com/nektos/act[nektos/act],
1316
the `/__e/` mechanism does not exist. This action installs system Node.js as a fallback.
1417
3. **git safe.directory** — Containers run as root while the workspace may be owned by a
@@ -17,11 +20,14 @@ description: |
1720
This action must be the **first step** in a job, before `actions/checkout`. It requires
1821
no Node.js runtime because it is a composite action that uses only `bash` steps.
1922
20-
NOTE: Node 24 unofficial glibc-217 builds do not currently exist. When GitHub Actions
21-
migrates to Node 24, this action will need an updated build or a different strategy.
23+
NOTE: No working glibc-217 Node 24 build exists yet (nodejs/unofficial-builds#190 has not
24+
shipped one, and the Boost mirror build crashes on heavy child_process operations on old
25+
kernels), so Node 24 patching is opt-in and off by default. Containers needing Node 24 on
26+
a pre-2.28 glibc (GCC <= 6 / Clang <= 5) are unsupported until a known-good build can be
27+
passed via `node24-url`.
2228
2329
The xref:actions/cpp-matrix.adoc[] action automatically configures the volume mounts
24-
(`/node20217`) that this action writes to for old containers.
30+
(`/node20217` and `/node24`) that this action writes to for old containers.
2531
2632
== Usage
2733
@@ -73,6 +79,18 @@ inputs:
7379
Example: `https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.gz`
7480
required: false
7581
default: ''
82+
node24-url:
83+
description: |
84+
URL of a glibc-217-compatible Node.js 24 tarball to patch into `/node24` for old
85+
containers. Node 24 patching is OPT-IN and disabled by default, because no working
86+
glibc-217 Node 24 build exists yet: nodejs/unofficial-builds#190 has not shipped one,
87+
and the Boost archive mirror build crashes silently on heavy `child_process`
88+
operations (e.g. @actions/cache) on kernels older than 5.3. As a result, containers
89+
that require Node 24 and a glibc older than 2.28 (GCC <= 6 / Clang <= 5) are not
90+
supported. Set this to a known-good build to re-enable Node 24 patching once one
91+
exists. Example: `https://example.com/node-v24.x.y-linux-x64-glibc-217.tar.xz`
92+
required: false
93+
default: ''
7694
setup-safe-directory:
7795
description: |
7896
Whether to configure `git config --global --add safe.directory '*'`.
@@ -88,8 +106,11 @@ inputs:
88106

89107
outputs:
90108
node-patched:
91-
description: "'true' if a glibc-217-compatible Node.js was downloaded and installed, 'false' otherwise."
109+
description: "'true' if a glibc-217-compatible Node.js (20 and/or 24) was downloaded and installed, 'false' otherwise."
92110
value: ${{ steps.node-patch.outputs.node-patched }}
111+
node24-patched:
112+
description: "'true' if a glibc-217-compatible Node.js 24 was downloaded and installed into /node24, 'false' otherwise."
113+
value: ${{ steps.node-patch.outputs.node24-patched }}
93114
node-installed:
94115
description: "'true' if system Node.js was installed via apt-get (act workaround), 'false' otherwise."
95116
value: ${{ steps.act-node.outputs.node-installed }}
@@ -110,54 +131,73 @@ runs:
110131
run: |
111132
if [ '${{ inputs.trace-commands }}' = 'true' ]; then set -x; fi
112133
113-
# Default output
134+
# Default outputs
114135
echo 'node-patched=false' >> "$GITHUB_OUTPUT"
136+
echo 'node24-patched=false' >> "$GITHUB_OUTPUT"
137+
138+
# patch_node LABEL MOUNT URL
139+
#
140+
# Replaces the runner-provided Node.js binary at /__e/node<LABEL> (which old
141+
# containers cannot run because of a too-new glibc) with a glibc-217 build
142+
# extracted into MOUNT — the writable directory cpp-matrix bind-mounts over
143+
# /__e/node<LABEL> for old containers. A writable MOUNT is the signal that we
144+
# are in such a container; without it there is nothing to patch.
145+
# Prints nothing to GITHUB_OUTPUT; returns 0 only when a patch was applied.
146+
patch_node() {
147+
local LABEL="$1" MOUNT="$2" URL="$3"
148+
149+
if [ ! -d "$MOUNT" ] || [ ! -w "$MOUNT" ]; then
150+
return 1
151+
fi
115152
116-
# If the runner's Node.js path doesn't exist, we're not in a container — nothing to do
117-
if [ ! -e /__e/node20/bin/node ]; then
118-
exit 0
119-
fi
120-
121-
# Check if the runner's Node.js binary works
122-
if /__e/node20/bin/node --version 2>/dev/null; then
123-
echo "Node.js is functional: $(/__e/node20/bin/node --version)"
124-
exit 0
125-
fi
153+
# If the runner's binary already works, the container's glibc is new enough.
154+
if "/__e/node${LABEL}/bin/node" --version >/dev/null 2>&1; then
155+
echo "Node.js ${LABEL} is functional: $("/__e/node${LABEL}/bin/node" --version)"
156+
return 1
157+
fi
126158
127-
echo "Node.js binary at /__e/node20/bin/node is not functional (likely glibc incompatibility)"
159+
echo "Node.js ${LABEL} at /__e/node${LABEL}/bin/node is missing or not functional; patching from $URL"
128160
129-
# Check if /node20217 volume mount exists (set up by cpp-matrix)
130-
if [ ! -d /node20217 ] || [ ! -w /node20217 ]; then
131-
echo "::warning::/node20217 is not available or not writable. Ensure cpp-matrix volume mounts are configured for old containers."
132-
exit 0
133-
fi
161+
# curl is required; xz-utils is required for .tar.xz (Node 24) tarballs.
162+
if ! command -v curl >/dev/null 2>&1 || ! command -v xz >/dev/null 2>&1; then
163+
if command -v apt-get >/dev/null 2>&1; then
164+
apt-get -o Acquire::Retries=3 update && apt-get -o Acquire::Retries=3 install -y curl xz-utils
165+
else
166+
echo "::warning::curl/xz are unavailable and apt-get cannot install them. Cannot patch Node.js ${LABEL}."
167+
return 1
168+
fi
169+
fi
134170
135-
# Determine download URL
136-
VERSION='${{ inputs.node-version }}'
137-
URL='${{ inputs.node-url }}'
138-
if [ -z "$URL" ]; then
139-
URL="https://unofficial-builds.nodejs.org/download/release/v${VERSION}/node-v${VERSION}-linux-x64-glibc-217.tar.gz"
140-
fi
171+
local TMP="/tmp/node${LABEL}-glibc217.tar"
172+
curl -fsSL --retry 3 --retry-delay 5 "$URL" -o "$TMP"
173+
# GNU tar autodetects gzip/xz compression on extract.
174+
tar -xf "$TMP" --strip-components 1 -C "$MOUNT"
175+
rm -f "$TMP"
141176
142-
# Install curl if not available
143-
if ! command -v curl >/dev/null 2>&1; then
144-
if command -v apt-get >/dev/null 2>&1; then
145-
apt-get -o Acquire::Retries=3 update && apt-get -o Acquire::Retries=3 install -y curl
146-
else
147-
echo "::warning::curl is not available and apt-get is not available to install it. Cannot download Node.js."
148-
exit 0
177+
if "/__e/node${LABEL}/bin/node" --version >/dev/null 2>&1; then
178+
echo "Patched Node.js ${LABEL}: $("/__e/node${LABEL}/bin/node" --version)"
179+
return 0
149180
fi
181+
echo "::warning::Patched /__e/node${LABEL}/bin/node but it still does not run."
182+
return 1
183+
}
184+
185+
# Node 20 — official unofficial-builds glibc-217 tarball.
186+
NODE20_URL='${{ inputs.node-url }}'
187+
if [ -z "$NODE20_URL" ]; then
188+
NODE20_URL="https://unofficial-builds.nodejs.org/download/release/v${{ inputs.node-version }}/node-v${{ inputs.node-version }}-linux-x64-glibc-217.tar.gz"
189+
fi
190+
if patch_node 20 /node20217 "$NODE20_URL"; then
191+
echo 'node-patched=true' >> "$GITHUB_OUTPUT"
150192
fi
151193
152-
# Download and extract
153-
echo "Downloading Node.js from: $URL"
154-
curl -fsSL "$URL" -o /tmp/node-glibc217.tar.gz
155-
tar -xzf /tmp/node-glibc217.tar.gz --strip-components 1 -C /node20217
156-
rm -f /tmp/node-glibc217.tar.gz
157-
158-
# Verify
159-
echo "Patched Node.js version: $(/__e/node20/bin/node --version)"
160-
echo 'node-patched=true' >> "$GITHUB_OUTPUT"
194+
# Node 24 — opt-in only. No working glibc-217 Node 24 build exists yet, so this
195+
# is skipped unless the caller supplies a known-good `node24-url`.
196+
NODE24_URL='${{ inputs.node24-url }}'
197+
if [ -n "$NODE24_URL" ] && patch_node 24 /node24 "$NODE24_URL"; then
198+
echo 'node-patched=true' >> "$GITHUB_OUTPUT"
199+
echo 'node24-patched=true' >> "$GITHUB_OUTPUT"
200+
fi
161201
162202
- name: Install Node.js for act
163203
id: act-node

cpp-matrix/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,5 +1047,5 @@ outputs:
10471047
When no filters are defined, this output is `{}`.
10481048
10491049
runs:
1050-
using: 'node20'
1050+
using: 'node24'
10511051
main: 'dist/index.js'

create-changelog/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ inputs:
333333
default: most-changes-first
334334

335335
runs:
336-
using: 'node20'
336+
using: 'node24'
337337
main: 'dist/index.js'
338338
post-if: success()
339339
branding:

flamegraph/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ outputs:
113113
description: The absolute path to svg file.
114114

115115
runs:
116-
using: 'node20'
116+
using: 'node24'
117117
main: 'dist/index.js'
118118
post-if: success()
119119
branding:

package-install/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ outputs:
272272
description: vcpkg executable file
273273

274274
runs:
275-
using: 'node20'
275+
using: 'node24'
276276
main: 'dist/index.js'
277277
post-if: success()
278278
branding:

0 commit comments

Comments
 (0)