detached 33a243c

externals.md RawHistoryFolder

Node.js externals

The host provides Node.js to jobs outside the image. A runner upgrade or a new Node.js version needs no image rebuild.

Builds

The builds are the ones of actions/runner. Each archive is pinned with its SHA-256 in internal/externals/table.go.

Name Node.js Source Architectures
node20 20.20.2 nodejs.org/dist/v20.20.2/node-v20.20.2-linux-<arch>.tar.gz x64, arm64
node24 24.21.0 nodejs.org/dist/v24.21.0/node-v24.21.0-linux-<arch>.tar.gz x64, arm64
node20_alpine 20.20.2 github.com/actions/alpine_nodejs release v20.20.2 x64
node24_alpine 24.21.0 github.com/actions/alpine_nodejs release v24.21.0 x64

Which Node.js an action uses

  • As on github.com, actions with using: node12, node16 or node20 run on node24.
  • FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 and ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION have no effect.
  • "Complete job" prints a warning that lists the actions forced from Node.js 20 to 24.

Download

  • ermite-runner run and sandbox-check fetch missing builds at start, in the background, into $ERMITE_RUNNER_STATE_DIR/externals/<name>-<version>-<arch>/.
  • Start waits for them for at most 2 minutes.
  • The SHA-256 of the .tar.gz is checked before anything is unpacked. Redirects must stay on https.
  • Extraction refuses:
    • absolute names and ..;
    • devices and fifos;
    • symbolic links that are absolute or leave the tree;
    • entries below a link;
    • hard links to anything but an unpacked file;
    • archives over 200,000 entries or 2 GiB.
  • Each build is unpacked in a temporary directory and renamed into place. A directory under its final name is complete.
  • At every start, everything in externals/ that is not a pinned build is removed.

In the sandbox

Read-only, as on GitHub: /home/runner/externals/node20/bin/node, node24/bin/node and the alpine ones.

Mode How
container Read-only bind mounts of the host directories
vm One read-only ext4 disk, built from the set (cache/extdisk-<key>.ext4). Old disks are removed an hour after the last build

The set is read at every job start. A download that finishes later is used by the next job.

When a build is unavailable

Causes: offline, HTTP error, wrong checksum, unsafe archive, or no build for the architecture.

  • The runner still runs and logs why.
  • The sandbox gets a stub bin/node and a file UNAVAILABLE with the reason.
  • A job that needs the tool fails with a message such as node24 (Node.js 24.21.0) is not available on this runner: ....
  • Failures that may pass (network error, HTTP status) are retried every 5 minutes until the runner stops.
  • Other failures (wrong checksum, unsafe archive, no build for the architecture) are not retried before the next start.

Turn off

ERMITE_RUNNER_NODE=0 turns the externals off. Nothing is downloaded or attached.

source
1# Node.js externals
2
3The host provides Node.js to jobs outside the image. A runner upgrade or a new Node.js version needs no image rebuild.
4
5## Builds
6
7The builds are the ones of `actions/runner`. Each archive is pinned with its SHA-256 in `internal/externals/table.go`.
8
9| Name | Node.js | Source | Architectures |
10| --- | --- | --- | --- |
11| `node20` | 20.20.2 | `nodejs.org/dist/v20.20.2/node-v20.20.2-linux-<arch>.tar.gz` | x64, arm64 |
12| `node24` | 24.21.0 | `nodejs.org/dist/v24.21.0/node-v24.21.0-linux-<arch>.tar.gz` | x64, arm64 |
13| `node20_alpine` | 20.20.2 | `github.com/actions/alpine_nodejs` release `v20.20.2` | x64 |
14| `node24_alpine` | 24.21.0 | `github.com/actions/alpine_nodejs` release `v24.21.0` | x64 |
15
16## Which Node.js an action uses
17
18- As on github.com, actions with `using: node12`, `node16` or `node20` run on `node24`.
19- `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24` and `ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION` have no effect.
20- "Complete job" prints a warning that lists the actions forced from Node.js 20 to 24.
21
22## Download
23
24- `ermite-runner run` and `sandbox-check` fetch missing builds at start, in the background, into `$ERMITE_RUNNER_STATE_DIR/externals/<name>-<version>-<arch>/`.
25- Start waits for them for at most 2 minutes.
26- The SHA-256 of the `.tar.gz` is checked **before** anything is unpacked. Redirects must stay on https.
27- Extraction refuses:
28  - absolute names and `..`;
29  - devices and fifos;
30  - symbolic links that are absolute or leave the tree;
31  - entries below a link;
32  - hard links to anything but an unpacked file;
33  - archives over 200,000 entries or 2 GiB.
34- Each build is unpacked in a temporary directory and renamed into place. A directory under its final name is complete.
35- At every start, everything in `externals/` that is not a pinned build is removed.
36
37## In the sandbox
38
39Read-only, as on GitHub: `/home/runner/externals/node20/bin/node`, `node24/bin/node` and the alpine ones.
40
41| Mode | How |
42| --- | --- |
43| `container` | Read-only bind mounts of the host directories |
44| `vm` | One read-only ext4 disk, built from the set (`cache/extdisk-<key>.ext4`). Old disks are removed an hour after the last build |
45
46The set is read at every job start. A download that finishes later is used by the next job.
47
48## When a build is unavailable
49
50Causes: offline, HTTP error, wrong checksum, unsafe archive, or no build for the architecture.
51
52- The runner still runs and logs why.
53- The sandbox gets a stub `bin/node` and a file `UNAVAILABLE` with the reason.
54- A job that needs the tool fails with a message such as `node24 (Node.js 24.21.0) is not available on this runner: ...`.
55- Failures that may pass (network error, HTTP status) are retried every 5 minutes until the runner stops.
56- Other failures (wrong checksum, unsafe archive, no build for the architecture) are not retried before the next start.
57
58## Turn off
59
60`ERMITE_RUNNER_NODE=0` turns the externals off. Nothing is downloaded or attached.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 4

Tags 11

↑↓ moveenter openesc close