Commit Graph
100 Commits
Author SHA1 Message Date
Jordan Harband 4049296ca8 [Fix] nvm_die_on_prefix: never let a project .npmrc choose which npmrc file --delete-prefix edits
`nvm use --delete-prefix`, which nvm itself recommends when it finds a `prefix` or `globalconfig` setting, ran `npm config delete` from the current directory.
For a project `.npmrc`, it ran a bare `npm config delete prefix`/`globalconfig`, so npm loaded that untrusted file first, and its `userconfig`, `globalconfig`, or `location=global` keys picked which file npm rewrote, deleted, or chmodded to 0666 - eg, `~/.bashrc` or `~/.aws/credentials`.
The builtin and user branches pinned `--userconfig`, but still loaded the project file, so a project `location=global` plus an indented ` globalconfig=` (which nvm's check does not match) redirected those writes the same way.
`npm config delete` never edits the project file anyway, so that branch could not do what it claimed.

For the project npmrc, no longer run npm at all: with `--delete-prefix`, warn that project npmrc files are not modified and must be edited by hand, and continue, as before.
For the builtin, global, and user npmrc files, pass `--prefix` set to the version directory, so npm does not walk up from the current directory to load the project npmrc, and its global config resolves to that version's `etc/npmrc`.

Discovered by Anthropic's OSS Scanner, as vulnerability ANT-2026-WYRTKBQ5.
2026-10-16 20:08:01 -07:00
Jordan Harband 1f99e4c20b [Fix] nvm_download_artifact: only put an archive in the cache once its checksum has passed
`nvm install --offline` installs whatever archive sits at the cache path without checking it again, which is only safe if everything nvm writes there has been verified.
When a download failed its checksum, `nvm_download_artifact` removed only the empty `files` directory and left the rejected archive in `$NVM_DIR/.cache`, so a later `nvm install --offline` would install the very tarball the online install had just refused.
An interrupted download was also left at the final cache name.

Download to a temporary `.unverified` name instead, run the 404 and checksum checks on that file, and move it to the cache path only once the checksum has passed.
Every failure path, including a checksum mismatch or a missing expected checksum, now removes the temporary file and the version's cache directory, so `--offline` no longer finds the version at all.
The README's offline section now says that only verified downloads are cached and that `--offline` trusts the cache as-is.

Discovered by Anthropic's OSS Scanner, as vulnerability ANT-2026-7NCT51FE.
2026-10-16 22:02:45 -07:00
Jordan Harband aa0572b7c4 [Fix] nvm_normalize_lts, nvm_ls_remote_index_tab: keep untrusted text out of shell arithmetic and LTS aliases
`nvm_normalize_lts` matched `lts/-N` with a glob that only pins the first digit after `lts/-`, then evaluated the rest inside `$((N+1))`.
bash and zsh evaluate a variable's contents as an arithmetic expression there, including command substitutions in array subscripts, so a name like `lts/-10*path[$(cmd)1]` ran `cmd`.
Such a name reaches this function from `nvm alias`, `nvm use`, `nvm install`, and `.nvmrc`, and also from LTS alias files written from a mirror's `index.tab`, which are resolved whenever `lts/*` or that codename is used.
The version column of a mirror's `index.tab` was used verbatim: printed by `nvm ls-remote` and `nvm version-remote`, matched against patterns, and stored as the target of `lts/*` codename aliases.
A hostile or compromised mirror could thus persist such a payload into `$NVM_DIR/alias/lts/`, where it is replayed later by `nvm alias` and alias resolution without the mirror being involved, and could put terminal escape sequences on the user's screen.

`nvm_normalize_lts` now takes everything after `lts/-` with parameter expansion and passes the name through unchanged unless it is all digits, before any arithmetic happens.
`lts/-1` through `lts/-N`, and the error when there are not that many LTS lines, behave as before; malformed offsets like `lts/-1x` or `lts/-10+1` are now returned unchanged in every shell, instead of erroring in dash or being evaluated in bash and zsh.
This also drops the `$?` check after the arithmetic, which could never fire.

`nvm_ls_remote_index_tab` now skips the header and keeps only rows whose version is `vX.Y.Z`, optionally followed by a `-` prerelease suffix of letters, digits, `.` and `-`, before anything is printed, stored, or matched.
The check runs on the raw column, before the `iojs-` prefix is added.
Every row of the current nodejs.org, nodejs.org nightly, and iojs.org index files passes, including `rc`, `nightly`, and `v8-canary` versions.

Discovered by Anthropic's OSS Scanner, as vulnerabilities ANT-2026-0GXXE91V and ANT-2026-31ZIEY85.
2026-10-16 21:35:44 -07:00
Jordan Harband 00cc205d6f [Fix] nvm install: don't leave NVM_NO_PROGRESS set in the caller's shell
`nvm install` passed the progress setting to `nvm_install_binary` and `nvm_install_source` as a prefix assignment,
which bash 3.2 in POSIX mode (macOS's `sh`) keeps after a function call returns,
so one install left `NVM_NO_PROGRESS=0` set,
and every later `nvm install --no-progress` was ignored.

Set it as a local instead.
2026-11-03 16:46:55 -06:00
Jordan Harband 17270cd532 [Perf] nvm_print_implicit_alias: classify implicit aliases in one awk pass
To resolve `stable` and `unstable`,
`nvm_print_implicit_alias` started an awk process per installed minor version,
plus another per pre-1.0 one to check its parity.
Classify the whole list in a single awk pass instead,
and skip it when there is nothing to classify.
The results are unchanged.

Refs #3416. Refs #3811.
2026-11-03 14:42:50 -06:00
Jordan Harband 93da6595ce [Fix] nvm_is_version_or_alias: reject uppercase LTS names in every locale
bash 3.2, macOS's `/bin/sh`, matches a bracket range like `[a-z]` by collation order in a UTF-8 locale,
which interleaves upper- and lowercase letters,
so `lts/Iron` from a symlinked `.nvmrc` was accepted there.

Match with `[:lower:]` instead.
2026-11-02 15:58:23 -06:00
Jordan Harband 67268ebcb6 [Fix] nvm_process_nvmrc: don't show the content of a symlinked .nvmrc
`.nvmrc` is found and read through symlinks,
so a repository that commits `.nvmrc` as a symlink to a path outside itself
(eg, `../../.npmrc`)
made a plain `nvm use`, `nvm install`, or `nvm which`
(or `nvm-exec`, or the README's auto-switching shell hook)
print that file:
the invalid `.nvmrc` message shows everything that was parsed,
even with `--silent`,
and a one-line file was taken as the version,
which is printed in the "Found" message and in later errors.

A symlinked `.nvmrc` is still followed,
so linking to another version file
(eg, `.node-version`, or a parent directory's `.nvmrc`)
keeps working,
but its content is never shown,
and it is valid only if it names a version or an existing alias,
via a new `nvm_is_version_or_alias` helper.
2026-11-02 11:34:39 -06:00
Jordan Harband 3f8411e58d [Fix] nvm_write_nvmrc: don't write through a symlinked .nvmrc
`nvm use --save` and `nvm install --save` wrote the version to `$PWD/.nvmrc` with `tee`,
which follows a symlink,
so a repository that commits `.nvmrc` as a symlink to a path outside itself made `--save` truncate any file the user can write
(eg, a shell startup file or `~/.ssh/authorized_keys`)
and replace it with the version string,
or create the target of a dangling link.
The link itself was left in place, so `git status` stayed clean.

`nvm_write_nvmrc` now refuses, with a warning, when `.nvmrc` in the current directory is a symlink,
dangling or not.
2026-11-02 11:27:17 -06:00
Jordan Harband 03f74a8666 [Fix] nvm_ls: match NVM_DIR literally
`nvm_ls` strips `$NVM_DIR` and the io.js version dir from each installed version's path with sed,
but put both into the regex as-is,
so an `NVM_DIR` containing a backslash, `[`, or `*` listed no installed versions,
and one containing `#` made sed fail.

Escape both before use, as `SEARCH_PATTERN` already is.
2026-11-02 13:53:00 -06:00
Jordan Harband 799de1d2dc [actions] TOC: use node/install instead of setup-node
`lts/*` is now node 26, which is not in the runner's tool cache,
so `setup-node` downloads it from a GitHub release asset host that the harden-runner allowlist blocks.
`node/install` installs node with nvm from nodejs.org, like the other workflows.
2026-11-02 13:42:07 -06:00
Jordan Harband 16df5aa69a [Fix] nvm_filter_installed_versions, nvm_filter_lts_versions, nvm_record_lts_status, nvm_get_default_packages: keep backslashes in NVM_DIR paths
These passed a path under `$NVM_DIR` to awk with `-v`,
which processes backslash escapes,
so with a backslash in `NVM_DIR` awk opened the wrong file:
the LTS status record read as empty,
so `nvm_filter_installed_versions` treated every version as non-LTS
and `nvm_filter_lts_versions` matched none,
`nvm_record_lts_status` could not merge an index without LTS versions into the record,
and `nvm_get_default_packages` named the wrong file in its error.

The LTS functions now pass the path through the environment,
like `nvm_strip_path` and `nvm_replace_literal`;
`nvm_get_default_packages` uses awk's `FILENAME`, which is taken literally.
2026-11-02 12:30:15 -06:00
Jordan Harband 5e38bc0cae [Tests] pin --lts and node installs to end-of-life lines, so a new node release can't break them
Tests: xenial / xenial (dash) (push) Failing after 32s
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Failing after 17m17s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Failing after 32s
Tests: fast / fast (sh, gawk) (push) Failing after 33s
Tests: fast / fast (bash, mawk) (push) Failing after 1m32s
Tests: installation_node / installation_node (dash, without curl) (push) Failing after 1m51s
Tests: installation_node / installation_node (sh, without curl) (push) Failing after 33s
urchin tests / tests (sh, sourcing) (push) Failing after 32s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (3) (push) Failing after 26m11s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (8) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, v0.39.4, 1 shlvl) (push) Failing after 1m33s
Tests: nvm install with set -e / test (no nvmrc, v0.39.5, 1 shlvl) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, v0.39.6, 2 shlvls) (push) Failing after 14s
Tests: nvm install with set -e / test (no nvmrc, v0.40.3, 1 shlvl) (push) Failing after 13s
Tests: nvm install with set -e / test (no nvmrc, v0.40.4, 1 shlvl) (push) Failing after 14s
Tests: nvm install with set -e / test (no nvmrc, v0.40.4, 2 shlvls) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.39.3, 1 shlvl) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.40.1, 2 shlvls) (push) Failing after 12s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.23) (push) Canceled after 0s
Tests: fast / fast (macOS, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Failing after 32s
Tests: alpine / fast x64 (alpine 3, bash) (push) Failing after 33s
Tests: alpine / fast x64 (alpine 3, sh) (push) Failing after 1m34s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Failing after 1m35s
Tests: fast / fast (zsh, gawk) (push) Failing after 3h1m5s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Failing after 1m33s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Successful in 9m35s
urchin tests / tests (bash, install_script) (push) Failing after 34s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9) (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Failing after 32s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Skipped
Tests: nvm install with set -e / test (no nvmrc, v0.39.6, 1 shlvl) (push) Failing after 5m8s
Tests: nvm install with set -e / test (no nvmrc, v0.40.5, 1 shlvl) (push) Failing after 5m46s
Tests: nvm install with set -e / test (no nvmrc, v0.40.8, 2 shlvls) (push) Failing after 16s
Tests: nvm install with set -e / test (nvmrc, v0.40.1, 1 shlvl) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.40.3, 1 shlvl) (push) Failing after 17s
Tests: nvm install with set -e / test (nvmrc, v0.40.5, 1 shlvl) (push) Failing after 17s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.17) (push) Canceled after 0s
Tests: fast / fast (macOS, bash) (push) Canceled after 0s
Tests: fast / fast (macOS, dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Failing after 1m33s
Tests: linting / doctoc (push) Successful in 10m52s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Failing after 4m16s
Tests: release process / release (push) Successful in 1m49s
Tests: fast / fast (dash, gawk) (push) Failing after 33s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Failing after 6m56s
Tests: installation_node / installation_node (sh) (push) Failing after 32s
Tests: xenial / all xenial tests (push) Skipped
urchin tests / tests (dash, sourcing) (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Failing after 2m33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (17) (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (2) (push) Failing after 35s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5) (push) Failing after 32s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, HEAD, 2 shlvls) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, v0.39.3, 2 shlvls) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, v0.39.7, 2 shlvls) (push) Failing after 21s
Tests: nvm install with set -e / test (nvmrc, v0.39.4, 1 shlvl) (push) Failing after 16s
Tests: nvm install with set -e / test (nvmrc, v0.39.6, 2 shlvls) (push) Failing after 12s
Tests: nvm install with set -e / test (no nvmrc, v0.40.7, 2 shlvls) (push) Failing after 14s
Tests: nvm install with set -e / finisher (push) Skipped
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.17) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Successful in 7m34s
Tests: linting / all linting (push) Skipped
Tests: nvm install with set -e / matrix (push) Successful in 8s
Tests: alpine / fast x64 (alpine 3, dash) (push) Failing after 33s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Failing after 32s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Failing after 1m32s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Failing after 32s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Failing after 33s
Tests: fast / fast (bash, gawk) (push) Failing after 32s
Tests: installation_node / installation_node (zsh) (push) Failing after 34s
urchin tests / tests (zsh, sourcing) (push) Failing after 2m58s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Successful in 8m51s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (1) (push) Failing after 1m34s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (16) (push) Failing after 38s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (18) (push) Failing after 34s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (19) (push) Failing after 34s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20) (push) Successful in 1m17s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (26) (push) Failing after 34s
Tests: nvm install with set -e / test (nvmrc, HEAD, 1 shlvl) (push) Failing after 16s
Tests: nvm install with set -e / test (no nvmrc, v0.40.5, 2 shlvls) (push) Failing after 3m26s
Tests: nvm install with set -e / test (nvmrc, v0.39.7, 1 shlvl) (push) Failing after 12s
Tests: nvm install with set -e / test (nvmrc, v0.40.2, 2 shlvls) (push) Failing after 15s
Tests: nvm install with set -e / test (nvmrc, v0.40.8, 2 shlvls) (push) Failing after 7m7s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.23) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, dash) (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Failing after 33s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Failing after 1m32s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Failing after 32s
Tests: fast / fast (zsh, mawk) (push) Failing after 19m17s
urchin tests / tests (dash, slow) (push) Failing after 32s
urchin tests / tests (sh, slow) (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (10) (push) Failing after 34s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (13) (push) Failing after 39s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Successful in 1m17s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (22) (push) Successful in 1m4s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (25) (push) Failing after 16m52s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4) (push) Successful in 3m6s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Successful in 6m0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Successful in 1m39s
Tests: nvm install with set -e / test (no nvmrc, v0.39.4, 2 shlvls) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, v0.40.0, 1 shlvl) (push) Failing after 15s
Tests: nvm install with set -e / test (no nvmrc, v0.40.0, 2 shlvls) (push) Failing after 16s
Tests: nvm install with set -e / test (no nvmrc, v0.40.2, 1 shlvl) (push) Failing after 14s
Tests: nvm install with set -e / test (no nvmrc, v0.40.2, 2 shlvls) (push) Failing after 12s
Tests: nvm install with set -e / test (nvmrc, HEAD, 2 shlvls) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.39.6, 1 shlvl) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.39.5, 1 shlvl) (push) Failing after 15s
Tests: nvm install with set -e / test (nvmrc, v0.39.7, 2 shlvls) (push) Failing after 12s
Tests: nvm install with set -e / test (nvmrc, v0.40.3, 2 shlvls) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.40.4, 1 shlvl) (push) Failing after 10m31s
Tests: nvm install with set -e / test (nvmrc, v0.40.4, 2 shlvls) (push) Failing after 24s
Tests: nvm install with set -e / test (nvmrc, v0.40.6, 1 shlvl) (push) Failing after 21s
Tests: nvm install with set -e / test (nvmrc, v0.40.8, 1 shlvl) (push) Failing after 19s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.17) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, bash) (push) Canceled after 0s
Tests: linting / eclint (push) Failing after 2m50s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Failing after 33s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Failing after 6m46s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Failing after 2m5s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Failing after 34s
Tests: fast / fast (dash, mawk) (push) Failing after 32s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Failing after 29s
Tests: installation_node / installation_node (dash) (push) Failing after 22m18s
Tests: xenial / xenial (bash) (push) Failing after 33s
Tests: xenial / xenial (sh) (push) Failing after 32s
Tests: xenial / xenial (zsh) (push) Failing after 1m40s
urchin tests / all test suites, all shells (push) Skipped
Tests: `nvm install-latest-npm` / nvm install-latest-npm (11) (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Successful in 1m27s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (23) (push) Failing after 17m1s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (7) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, HEAD, 1 shlvl) (push) Failing after 1m32s
Tests: nvm install with set -e / test (no nvmrc, v0.39.3, 1 shlvl) (push) Failing after 33s
Tests: nvm install with set -e / test (no nvmrc, v0.40.1, 2 shlvls) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.40.2, 1 shlvl) (push) Failing after 14s
Tests: nvm install with set -e / test (nvmrc, v0.40.5, 2 shlvls) (push) Failing after 21s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.23) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Failing after 7m7s
Tests: linting / check_exec (push) Successful in 7m53s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Failing after 5m47s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Failing after 17m39s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Failing after 16m49s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Failing after 15m49s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Failing after 1m33s
Tests: installation_node / installation_node (bash) (push) Failing after 15m50s
Tests: installation_node / all installation_node tests (push) Skipped
urchin tests / tests (bash, installation_iojs) (push) Failing after 4m55s
urchin tests / tests (bash, sourcing) (push) Failing after 1m32s
urchin tests / tests (dash, installation_iojs) (push) Failing after 1m54s
urchin tests / tests (sh, installation_iojs) (push) Failing after 32s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (12) (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Failing after 1m33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Failing after 32s
Tests: nvm install with set -e / test (no nvmrc, v0.39.7, 1 shlvl) (push) Failing after 7m2s
Tests: nvm install with set -e / test (no nvmrc, v0.40.8, 1 shlvl) (push) Failing after 13s
Tests: nvm install with set -e / test (nvmrc, v0.39.3, 2 shlvls) (push) Failing after 16s
Tests: nvm install with set -e / test (nvmrc, v0.39.5, 2 shlvls) (push) Failing after 12s
Tests: nvm install with set -e / test (no nvmrc, v0.40.3, 2 shlvls) (push) Failing after 16s
Tests: nvm install with set -e / test (nvmrc, v0.40.7, 2 shlvls) (push) Failing after 23s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.17) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Failing after 32s
Tests: shellcheck / shellcheck (push) Skipped
Tests: fast / fast (sh, mawk) (push) Failing after 7m3s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Failing after 6m54s
Tests: installation_node / installation_node (zsh, without curl) (push) Failing after 33s
urchin tests / tests (bash, slow) (push) Failing after 31m56s
urchin tests / tests (zsh, installation_iojs) (push) Failing after 32s
urchin tests / tests (zsh, slow) (push) Failing after 39m44s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Failing after 17m6s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (24) (push) Successful in 7m40s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Failing after 37s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6) (push) Failing after 33s
Tests: nvm install with set -e / test (no nvmrc, v0.40.1, 1 shlvl) (push) Failing after 14s
Tests: nvm install with set -e / test (no nvmrc, v0.40.6, 2 shlvls) (push) Failing after 13s
Tests: nvm install with set -e / test (no nvmrc, v0.40.6, 1 shlvl) (push) Failing after 7m5s
Tests: nvm install with set -e / test (no nvmrc, v0.40.7, 1 shlvl) (push) Failing after 14s
Tests: nvm install with set -e / test (nvmrc, v0.40.0, 1 shlvl) (push) Successful in 14s
Tests: nvm install with set -e / test (nvmrc, v0.40.7, 1 shlvl) (push) Failing after 19s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.17) (push) Canceled after 0s
Tests: fast / fast (macOS, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: linting / test_naming (push) Successful in 16s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Failing after 33s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Failing after 33s
Tests: installation_iojs / all installation_iojs tests (push) Skipped
Tests: installation_node / installation_node (bash, without curl) (push) Failing after 22m35s
update readme TOC / update readme TOC (push) Failing after 33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14) (push) Failing after 32s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (15) (push) Failing after 1m33s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Successful in 1m10s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Successful in 2m39s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Failing after 3m0s
Tests: nvm install with set -e / test (no nvmrc, v0.39.5, 2 shlvls) (push) Failing after 7m18s
Tests: nvm install with set -e / test (nvmrc, v0.39.4, 2 shlvls) (push) Failing after 14s
Tests: nvm install with set -e / test (nvmrc, v0.40.0, 2 shlvls) (push) Successful in 16s
Tests: nvm install with set -e / test (nvmrc, v0.40.6, 2 shlvls) (push) Failing after 20s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.17) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, sh) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
`nvm install --lts` and `nvm install node` resolve to whatever is newest on nodejs.org,
so a partial release
(eg, v26.13.0, published to `index.tab` before its `SHASUMS256.txt`)
these tests fail without any change to nvm.
`nvm exec --lts` and `nvm run --lts` now run against v18.20.8,
with `lts/*` pointed at `lts/hydrogen` after setup's installs (which rewrite the LTS aliases),
and restored in teardown.
The `set -E` test now installs `9`,
which still resolves remotely,
since the ERR trap handling it covers is in `nvm()` itself.

See https://github.com/nodejs/node/issues/67087
2026-10-28 10:37:00 -07:00
Jordan Harband 3fda4d5542 [New] select versions by category: alpha, lts, non-lts, iojs; exclude alphas by default
Node 27 and later publish Alpha prereleases, like `v27.0.0-alpha.1.0.0`, in the main `index.tab`,
so `nvm install node` or `nvm install 27` would otherwise pick one.
Every version is in exactly one category: `alpha` and `lts` or `non-lts` (by index.tab's LTS column) on the node mirror, and `iojs` on the io.js mirror.
Commands select from every category but `alpha`, unless `$NVM_ONLY` lists others,
and every command that selects or lists versions takes `--only=<categories>` to override both;
an exact alpha needs `alpha` selected, like any other.
An LTS selection, like `--lts` or an `lts/` version, can't combine with an `--only=` that excludes `lts`.
Telling installed `lts` and `non-lts` versions apart uses the recorded LTS status, and fails rather than guess without it.
`nvm alias` also stores `--only=`, so `nvm alias default --only=alpha node` makes the latest installed alpha the default, including in a new shell.
2026-10-21 14:09:18 -07:00
Jordan Harband 11df5ed6f1 [Perf] nvm_is_installed_exact_version: also take the fast path for an exact prerelease
An installed prerelease, like `v24.0.0-rc.1`, now resolves to itself without the `nvm_ls` pipeline, as releases already do.
2026-10-21 13:09:25 -07:00
Jordan Harband fe2900d176 [New] nvm alias: store --lts and --lts=<name>
`nvm alias default --lts node` writes `--lts node` to the alias file,
so it resolves to the latest installed LTS version, using each version's recorded LTS status;
`--lts=<name>` limits it to one LTS line.
The flags of the outermost alias apply when one alias points at another,
an alias with a flag this version of nvm doesn't recognize resolves to nothing, rather than ignoring the flag,
and `nvm uninstall` also removes aliases with flags that point at the uninstalled version.
A new shell never downloads index.tab, so it explains a default alias that needs LTS status that isn't recorded yet.
2026-10-21 12:57:19 -07:00
Jordan Harband e5f1288b40 [New] record every node version's LTS status
Each download of node's `index.tab` now merges every version's LTS codename, or `-`, into `$NVM_DIR/.lts-status`,
keeping versions that download doesn't list,
so the status of an installed version is known, and refreshed on every remote connection.
Only an index that includes LTS versions can start the record, so a nightly or release candidate mirror can't,
and `nvm_ensure_lts_status` downloads it once for versions installed before it was recorded.
`update_test_mocks.sh` writes the record of its `index.tab` mock to `nodejs.org-dist-lts-status.txt`.
2026-10-21 12:52:04 -07:00
Jordan Harband 4007c0d062 [Tests] bash_completion: don't let zsh's compinit wait for an answer
On runners where zsh considers a completion directory insecure,
`compinit` asks whether to use it, and on the test's terminal waited for an answer forever,
which hung every Ubuntu `fast` job.
The test now sets `ZSH_DISABLE_COMPFIX`, which `bash_completion` already honors, and gives zsh no stdin.
2026-10-26 11:11:53 -07:00
Jordan Harband 139ed9ccc6 [Fix] nvm: ignore option variables set by the caller
In dash, and in bash for a variable assigned in the command's own prefix (like `PATTERN=x nvm ls`), `local` keeps the outer value,
so a variable a subcommand only sets conditionally, like `PATTERN`, `NVM_LTS`, `LTS`, or `VERSION`, could come from the caller,
replacing the version argument, applying an LTS filter that was never requested,
or making `nvm use`, without a version or an .nvmrc, use the caller's `VERSION`.
Each such local is now initialized where it is declared.
2026-10-21 12:48:18 -07:00
Jordan Harband 6a085bc8b4 [Fix] nvm reinstall-packages: don't print VERSION='' in zsh
`nvm` already declares `VERSION` local, and declaring an existing local again makes zsh print it.
2026-10-21 12:47:13 -07:00
Jordan Harband fe017ae9bd [Fix] nvm_alias, nvm_ls_remote_index_tab, nvm use: return the exit code of a failed check
`if ! cmd; then return $?` returns the status of the negation, which is 0,
so an uppercase LTS name, or an unusable installed version, was reported but still exited successfully.
2026-10-21 12:46:19 -07:00
Jordan Harband fd23eb2037 [Fix] nvm_print_versions: don't mark N/A as installed
With nothing installed, `nvm_ls` prints `N/A`, which then counted as an installed version,
so `nvm ls` and an unmatched `nvm ls-remote` printed `N/A *`.
2026-10-21 13:52:16 -07:00
Jordan Harband 6cef0edd18 [Fix] nvm_ls: no blank line before system when nothing is installed
`nvm ls` then printed an empty row ahead of the system version.
2026-10-21 12:44:44 -07:00
Jordan Harband d65637f2e8 [Fix] nvm_print_versions: widen the version column for long versions
Versions longer than 15 characters, like nightlies and release candidates,
overflowed the fixed-width column, so `nvm ls` and `nvm ls-remote` misaligned them;
the column now also fits the `->` before the current version.
2026-10-21 12:44:19 -07:00
Jordan Harband f58d43f4d5 [Fix] nvm_ls: match a prerelease only up to a .
A prerelease pattern matched any installed version containing it,
so `nvm use v24.0.0-rc.1` could pick `v24.0.0-rc.10`,
and a partial prerelease like `v24.0.0-rc` matched nothing.
An installed exact prerelease now resolves to itself,
and a partial one matches only versions that continue with a `.`.
2026-10-21 12:43:37 -07:00
Jordan Harband aed19eb997 [Fix] nvm_ls: list every installed prerelease, in semver order
`sort -u` keyed only on X.Y.Z treated prereleases of a release, and the release itself, as duplicates,
so `nvm ls` hid all but one of them, and which one survived depended on directory order.
`nvm_sort_versions` orders them by semver precedence instead,
so `v24.0.0-rc.2` sorts before `v24.0.0-rc.10`, and both before `v24.0.0`.
2026-10-21 12:40:42 -07:00
Jordan Harband 79214249bb [Fix] nvm uninstall: only remove aliases that point at the uninstalled version
Matching alias files by substring also removed aliases to longer versions,
so uninstalling v20.1.1 deleted an alias to v20.1.10.
Each alias's target is now read the way `nvm_alias` reads it, ignoring comments,
and in zsh an empty alias directory no longer errors with "no matches found".
2026-10-21 12:39:28 -07:00
Jordan Harband 43a2abbfd5 [Fix] nvm_ls_cached: only match whole version numbers
An unanchored `grep` let a pattern match any cached version containing it,
so `nvm install --offline 20.1.1` could install a cached v20.1.10,
and `nvm install --offline iojs`, whose pattern is empty, matched every cached node version.
2026-10-21 12:39:00 -07:00
Jordan Harband e7363fa669 [actions] tests-alpine: time out jobs well before GitHub's 6-hour limit
A hung `fast` job, like the busybox `sh` lanes in `nvm debug`, otherwise ran for 6 hours before being cancelled.
`fast` jobs take a few minutes and `musl-binary` jobs under one, so they now time out after 15 and 10.
2026-10-25 11:43:54 -07:00
Jordan Harband 898124fd60 [Fix] nvm debug: don't let the shell read stdin when asked for its version
busybox's shells have no `--version`, and start an interactive shell instead,
so with `$SHELL` set to busybox `sh` on a terminal, `nvm debug` waited for input forever,
which hung the alpine `sh` CI lanes in the "mirror URL credentials are masked in output" test.
Like the other busybox tools, its version now comes from `--help`,
and every shell is given no stdin to read.
2026-10-25 11:42:45 -07:00
Jordan Harband e780535240 [Fix] nvm_download: with GNU Wget, follow only same-origin redirects when sending $NVM_AUTH_HEADER
curl 7.58.0 and later drop a custom Authorization header when a redirect leads to another host,
but wget sends `--header` along to every redirect target,
so on a machine without curl,
a mirror that redirected elsewhere handed the credential to that other host.

When a header is sent with GNU Wget,
run it with `--max-redirect=0`.
When it then exits with 8
(an HTTP error, which includes a redirect it did not follow),
read the `Location` with one more request,
and re-request it only if it keeps the same scheme,
host, and port, up to 20 times.
A redirect to another origin,
including a downgrade to `http`,
fails with exit code 8 and an error that names the URL nvm requested and suggests curl.
`--max-redirect` is not a BusyBox wget option,
so other wgets are invoked as before;
the README says so

Discovered by Anthropic's OSS Scanner, as ANT-2026-PKUZHTT3; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband e3aa232901 [Fix] nvm_download: only send $NVM_AUTH_HEADER to URLs under a mirror it applies to
The header was added to every download,
whatever the host.
With only `$NVM_NODEJS_ORG_MIRROR` set,
a private mirror's credential therefore also went to the default `https://iojs.org/dist`
(eg, from `nvm ls-remote`),
and with only `$NVM_IOJS_ORG_MIRROR` set,
to `https://nodejs.org/dist`;
it also went to `npmjs.org` when installing an old npm.

Add `nvm_auth_header_applies_to`,
which uses `nvm_get_mirror` and accepts a URL only when it is under a mirror,
compared literally,
with a `/` after the mirror's prefix.
When exactly one of the two mirror variables is set,
the header belongs to that mirror alone;
when both or neither are set,
both mirrors
(including the defaults, when neither is)
still receive it,
so the documented example keeps working.
An invalid mirror matches nothing,
and no empty `Authorization:` header is sent when sanitizing leaves nothing

Discovered by Anthropic's OSS Scanner, as ANT-2026-YPW87EDH; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 6bbbf3e8d3 [Tests] nvm_download: point the httpbin Authorization check at a configured mirror
The httpbin check sends `$NVM_AUTH_HEADER` to `http://127.0.0.1/bearer` without configuring a mirror.
Set `$NVM_NODEJS_ORG_MIRROR` to that host,
as a real user of the header would,
so the check keeps exercising the header once it is only sent to URLs under a mirror

Discovered by Anthropic's OSS Scanner, as ANT-2026-YPW87EDH; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 00217de1e1 [Fix] install.sh: don't let a git repository in the current directory affect git ls-remote
`install_nvm_from_git` checked whether `$NVM_INSTALL_VERSION` is a ref with a bare `git ls-remote`,
which discovers and loads the config of whatever repository contains the current directory.
That repository's `url.*.insteadOf` and `core.sshCommand` could then redirect or hijack the check,
unlike every other git command in the function,
which already passes `--git-dir="$INSTALL_DIR"/.git`.
Pass `--git-dir` here too;
`ls-remote` works even when that directory does not exist yet,
as on a fresh install

Discovered by Anthropic's OSS Scanner, as ANT-2026-JS4YHKRK; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 0333df56ca [Robustness] install.sh, nvm uninstall: pass the version to grep with -e
`install_nvm_from_git` passed `$NVM_INSTALL_VERSION` to grep as a bare argument,
and `nvm uninstall` did the same with the resolved version when looking for aliases that point to it,
so a value starting with `-` would have been parsed as grep options rather than as the pattern.
Neither value crosses a trust boundary
(the first is the user's own environment variable, and the second is an already-installed version, which never starts with `-`),
but every grep that receives a version should put it after `-e`,
which POSIX specifies and which nvm.sh already uses elsewhere

Discovered by Anthropic's OSS Scanner, alongside vulnerability ANT-2026-EN9DM7WC; this change is not itself a vulnerability fix.
2026-10-23 08:53:59 -07:00
Jordan Harband cbd8f8e920 [Fix] nvm_remote_versions: only consult io.js's version list for majors 1 through 3
io.js only released v1 through v3,
but its version list was downloaded and searched for every pattern,
including ones like `0.12` or `20` that can only ever match node versions.
Besides the needless index.tab download on every such `nvm install`,
io.js's "no match" status was returned even when node had matches,
so `nvm ls-remote 20` printed node's versions and then exited 3.
Patterns whose major is 0 or 4+ now only consult node's list,
so `nvm ls-remote` exits 0 for them when node has matching versions.
The listed and resolved versions are unchanged

Discovered by Anthropic's OSS Scanner, as ANT-2026-AKH0HYWD; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 59e008fd62 [Fix] nvm_remote_versions: place io.js versions by major version, not at the literal v4.0.0
io.js versions were inserted into node's version list immediately before the `v4.0.0` line.
Whenever node's filtered list did not contain that exact line,
every io.js version was appended after all node versions,
including newer ones,
so `nvm_remote_version`'s `tail -1` could pick an io.js version over the latest matching node version.
Node's list is sorted,
so it is now split at the first version with a nonzero major,
which keeps io.js versions between node v0.x and node v4+ regardless of which node versions the pattern matched

Discovered by Anthropic's OSS Scanner, as ANT-2026-AKH0HYWD; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 35d6e5a000 [Fix] nvm.sh: detect NVM_DIR without $0/$_; fall back to the default install location instead of the working directory
When `nvm.sh` is sourced with `NVM_DIR` unset,
it derived `NVM_DIR` from the sourced file in bash
(via `BASH_SOURCE`),
and otherwise from `dirname "${_:-$0}"`.
In shells that do not set `BASH_SOURCE`
(dash, sh, ksh, and zsh under `emulate sh` or without `FUNCTION_ARGZERO`),
`$0` is the shell's or the calling script's name and `$_` is whatever was inherited,
so `NVM_DIR` became an unrelated directory:
for `sh -c '. ~/.nvm/nvm.sh'`,
as run by `system(3)` or `popen(3)`,
that is the working directory,
whose `alias/default` and `versions/` nvm then used,
and from which `nvm cache clear` and friends would operate.

Detection now uses only reliable sources:
`BASH_SOURCE` in bash,
`${(%):-%x}` in zsh
(which names the sourced file regardless of options),
and `${.sh.file}` in ksh93
(probed in a subshell first, since other shells with `KSH_VERSION` reject the syntax)
A detected source that is not a regular file
(eg, `/dev/fd/63` from `. <(…)`)
is ignored.
Otherwise, nvm uses the default install location that `install.sh` uses
(`$XDG_CONFIG_HOME/nvm`, else `~/.nvm`)
when it contains `nvm.sh`, and if not,
it prints an error asking for `NVM_DIR` to be set and returns 1,
instead of guessing.
Setups that export `NVM_DIR` before sourcing `nvm.sh`,
as `install.sh` and the README do, are unaffected

Discovered by Anthropic's OSS Scanner, as ANT-2026-8RIT0MGO; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband c07e8722a1 [Tests] nvm_get_arch_unofficial: set NVM_DIR when sourcing nvm.sh in the chroots
The chroot checks source `nvm.sh` from `/bin/sh` without `NVM_DIR`,
so nvm has to guess it:
today from `dirname "$0"`,
which is `/bin` here.
That guess is incidental to what the test checks
(architecture detection),
so set `NVM_DIR` explicitly to the directory the chroot's `nvm.sh` lives in,
as the README instructs

Discovered by Anthropic's OSS Scanner, as ANT-2026-8RIT0MGO; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 3649f2b9a7 [meta] Makefile: default NVM_DIR to the checkout when it is not set
The test suites source `nvm.sh` without setting `NVM_DIR` unless the caller exports it, which locally
(where `NVM_*` variables are unset first)
and in the `urchin tests` workflow it is not.
bash and zsh then detect the checkout from the sourced file,
but sh and dash have no way to locate a sourced file,
so they fell back to `dirname "$0"`,
which happened to be the test's own directory.

The `test-<shell>` targets now export `NVM_DIR` as the checkout when it is still unset,
so every shell runs the suites against the same `NVM_DIR`,
and an explicitly provided `NVM_DIR` is kept

Discovered by Anthropic's OSS Scanner, as ANT-2026-8RIT0MGO; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 8610e1578d [Fix] nvm_process_nvmrc_content: reject control characters
An `.nvmrc` line containing a control character
(eg, an escape, a bell, or a carriage return in the middle of the version)
was accepted as-is,
so the raw bytes were passed along as the version and printed verbatim in the "Found '…' with version <…>" and "N/A: version … is not yet installed" messages,
garbling the terminal output.

Any line that still contains a control character other than a tab,
after comments and leading and trailing white space are removed,
now makes the file invalid.
CRLF line endings keep working,
since the trailing carriage return is trimmed as white space before the check.
The "non-commented content parsed" part of the invalid `.nvmrc` message now shows each control character
(other than tabs and newlines) as `?`,
so it prints as plain text

Discovered by Anthropic's OSS Scanner, as ANT-2026-R3FR49Z7; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 4a1f7d2875 [Fix] nvm_download_artifact, nvm debug: mask credentials in mirror URLs when printing them
`nvm_get_mirror` accepts `user:password@` in `$NVM_NODEJS_ORG_MIRROR` and `$NVM_IOJS_ORG_MIRROR`,
but `nvm_download_artifact` printed the full tarball URL in its "Downloading",
"download from ... failed",
and "HTTP 404 at URL" messages,
and `nvm debug` printed both mirror variables as-is,
so the credentials showed up in terminal output and build logs.

Add `nvm_sanitize_url`,
which replaces the userinfo part of any URL with `***@`,
and use it in those messages.
The download itself still uses the full URL,
so authenticating to the mirror keeps working.
The README now notes that `$NVM_AUTH_HEADER` is the recommended way to authenticate to a mirror

Discovered by Anthropic's OSS Scanner, as ANT-2026-X03SZ7C6; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:59 -07:00
Jordan Harband 37c578d973 [Fix] nvm_install_binary, nvm_install_source: only use a tarball that nvm_download_artifact put in the cache
`nvm_install_binary` and `nvm_install_source` took the tarball path from the last line of `nvm_download_artifact`'s output via `| tail -1`.
That pipeline's exit status is `tail`'s,
so a failed download went unnoticed,
and the downloader's own stdout was not separated from the path:
anything it printed
(eg, from a curl `write-out` setting)
could be the last line.
If that line happened to name an existing file relative to the current directory,
it was extracted and installed as if it were the downloaded tarball,
instead of the install failing.

`nvm_download_artifact` now sends the downloader's output to stderr,
so its stdout is only ever the tarball path.
Both install functions capture its output directly and honor its exit status,
and accept the result only if it is an existing file inside nvm's cache directory,
via a new `nvm_is_cached_artifact` helper

Discovered by Anthropic's OSS Scanner, as ANT-2026-DESJ2ESZ; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:58 -07:00
Jordan Harband c8a2a81f92 [Fix] nvm_download, nvm_get_latest, install.sh: pass -q to curl first, so .curlrc is ignored again
curl only skips reading `.curlrc` when `-q` is its very first argument;
anywhere else, the config file has already been read by the time `-q` is seen.
a4f89c62 added `-q` to every curl call so that a user's `.curlrc` would not affect nvm,
but 6a3b1dd2 (v0.33.2)
put `--compressed` in front of it everywhere.
bd090ef7 (v0.40.0)
moved it back to the front in `nvm.sh`'s `nvm_download`,
and then 6d870d18 (v0.40.5) began building those arguments with `set --`,
prepending `--compressed` after `-q`,
so whenever curl supports compression, `-q` was second again.
`nvm_get_latest` and `install.sh`'s `nvm_download` have passed
`--compressed` before `-q` since v0.33.2.

Pass `-q` first in all three places.
Settings in a user's `.curlrc`
(such as a proxy, CA bundle, or `write-out`)
no longer apply to nvm's own curl calls,
as was intended,
and as in v0.40.0 through v0.40.4 for `nvm_download`;
the corresponding environment variables
(eg, `https_proxy`, `CURL_CA_BUNDLE`) still apply.

The existing `nvm_get_latest` test pinned the old argument order,
so its expectation is updated

Discovered by Anthropic's OSS Scanner, as ANT-2026-DESJ2ESZ; the scanner reported it as a vulnerability, but it is not one.
2026-10-23 08:53:58 -07:00
Jordan Harband 013b291d36 [meta] release-notes.sh: replace control characters in commit subjects
Commit subjects were printed as-is,
so escape sequences, carriage returns,
and other control characters in a subject reached the terminal during `make release-notes` and `make release`,
where they could hide or rewrite lines of the notes being reviewed,
and were then written verbatim into the bump commit and the release tag.
A tab in a subject also corrupted the tab-separated intermediate file.

Subjects are now filtered as they are read from `git log`,
replacing C0 controls, DEL,
and UTF-8-encoded C1 controls with `?`.
They are replaced rather than removed so that the bytes on either side cannot join into a new control character,
and so the change stays visible in the notes.
The section `grep` now matches bytes,
because in a UTF-8 locale GNU grep stops printing matches at a line that is not valid UTF-8,
which silently dropped bullets.
Lowercasing a subject to find its category now works on bytes too,
because in a UTF-8 locale BSD `tr` stops at a byte that is not valid UTF-8.

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-INF3JLG6; the scanner correctly classified it as not a vulnerability.
2026-10-23 08:53:58 -07:00
Jordan Harband d639676bb0 [Fix] nvm_is_version_installed: fail when nvm_version_path fails
Since 072622c7, `nvm_version_path` rejects a version with a `..` path component, printing nothing and returning 3.

`nvm_is_version_installed` ignored that status and appended `/bin/node` to the empty output,
so for such a version (eg, `v/../x` in an `.nvmrc`)
it checked `/bin/node`,
and reported the version as installed whenever a system node lived there.
`nvm use` then put `/bin` in place of the active version on `PATH`,
and `nvm which` printed `/bin/node`.

Propagate `nvm_version_path`'s failure,
so such a version is never installed

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-O1QONH45; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband 39fca6c905 [Fix] nvm use, nvm-exec: stop option parsing at --
`nvm use` treated `--` as a no-op and kept parsing options after it,
so `nvm use -- -w` enabled `--save`,
fell back to `.nvmrc`,
and rewrote it with the resolved version;
`--delete-prefix` and unknown `--*` arguments after
`--` were likewise acted on or silently dropped.

Now the argument after `--` is taken as the version and option parsing stops there;
a lone `--` still falls back to `.nvmrc`.
`nvm-exec` now passes `NODE_VERSION` after `--`,
so its value is always treated as a version and never as an option

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-4RO8S9N0; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband 020503b536 [Fix] nvm install: validate an inherited NVM_MAKE_JOBS like -j
A job count given with `-j` is checked by `nvm_get_make_jobs`,
which rejects anything but a natural number and falls back to the detected core count.
A non-empty `NVM_MAKE_JOBS` already in the environment skipped that check entirely,
and was passed as-is to `make -j`,
where a value like `V=1` or `-f/dev/null` is taken as a separate `make` argument.
Now an inherited value that is not a natural number gets the same error and fallback as an invalid `-j`;
a valid one is still used,
and an empty one still triggers detection silently

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-SYLQD6PZ; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband 813b5f6dcc [Fix] nvm_is_natural_num: reject anything but digits
`[ "$1" -eq "$1" ]` accepts more than a natural number:
a leading `+`, and leading or trailing whitespace,
and in ksh it evaluates its operands as arithmetic expressions,
so words like `install` and expressions like `1+1` or `V=1` pass too.
Values with any non-digit character are now rejected before that test.

The sunos and aix branches of `nvm_get_make_jobs` count cores with `wc -l`,
which on those platforms pads the count with whitespace,
so that count is now stripped of whitespace before it is checked

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-SYLQD6PZ; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband 8df635740e [Fix] nvm_remote_version: match the requested version as a whole version component
The check that the resolved version actually matches the request used an unanchored substring match on the raw pattern,
so `nvm install 20` could accept `v10.20.0` when a remote list's row was selected by a `v20` in its LTS column and no 20.x rows were present.

Match the `v`-prefixed pattern followed by a non-digit against the version instead,
the same way `nvm_ls_remote_index_tab` normalizes it,
so `20` no longer matches `v10.20.0` or `v200.0.0`,
while regex-style requests like `4.*` and `v[68]`,
and a trailing dot like `8.`, keep working.
This also fixes `iojs-1` and `iojs-3`,
which previously resolved to N/A because `iojs-3` is not a substring of `iojs-v3.3.1`.

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-7GFFYVJP; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband cac4c8d7e0 [Fix] install.sh: a failed script-method download no longer clobbers the install or reports success
With the script install method,
`install_nvm_as_script` downloaded `nvm.sh`,
`nvm-exec`, and `bash_completion` directly over the installed files.
A dropped connection with curl left a truncated `nvm.sh`,
and any wget failure (even just being offline)
left all three files empty.
Its failure was also ignored by `nvm_do_install`,
which went on to edit the profile,
source the broken `nvm.sh`,
print the success message, and exit 0.

Now each file is downloaded to a temporary `.download` name,
every download is waited on
(by PID, rather than returning while other downloads may still be writing),
and the files are moved into place only once all of them have succeeded;
on failure,
the partial downloads are removed and the existing install is left untouched.
`nvm_do_install` now exits with
`install_nvm_as_script`'s failure status,
matching the git install method

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-8TH8YGY5; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband 66228bd1fa [Fix] nvm_ls: match the version pattern literally
nvm_ls escaped only `.` and `#` before using the pattern
(which may come from a `.nvmrc`)
as a sed address,
so any other regex characters in it were interpreted:
`v2[0-9]` matched installed versions,
`[` made sed fail with an error,
and nested bounded repetitions like `\(v\{1,300\}\)\{1,300\}`
made sed take a very long time and a lot of memory to compile,
stalling `nvm use` and shell startup.
Escape every BRE metacharacter,
including the backslash,
so the pattern is always matched as literal text

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-HZAFTTUK; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband b076039a60 [Tests] nvm install v1 works: get the version from nvm_remote_version, not the ls-remote display
The test took the last `nvm ls-remote` line and trimmed its whitespace, which kept the markers `ls-remote` adds once that version is installed (a trailing ` *`) or current (a leading `->`), so it passed eg `iojs-v1.8.4 *` to `nvm run` as the version.
That only resolved because `nvm_ls` interpreted ` *` as a regex; ask `nvm_remote_version` for the version instead.

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-HZAFTTUK; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband 6b9650c47f [Fix] bash_completion: list alias and version names without expanding them
`__nvm_generate_completion` passed its word list to `compgen -W`,
which runs every word through shell expansion.
Since that list includes alias file names and installed version directory names,
pressing Tab after `nvm use`, `nvm alias`, etc,
ran any command substitution in those names,
expanded variables in them, and globbed `*` against the current directory.
Now the list is split with globbing disabled,
and each word is matched against the current word as a literal prefix,
so names are offered exactly as written

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-QDARMGPO; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan Harband d8b39c746e [Fix] nvm_sanitize_auth_header: strip newlines, so wrapped base64 credentials work
`sed` works one line at a time,
so the allowlist never removed newlines inside `NVM_AUTH_HEADER`.
A `Basic` credential built with GNU `base64`,
which wraps its output at 76 columns,
therefore reached the downloader split across several lines,
and authentication failed (wget rejects such a header outright).

Filter with `tr -cd` instead,
using the same set of allowed characters,
so CR and LF are deleted like any other disallowed character and a wrapped credential is joined back into one line

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-W1E9TAK3; the scanner correctly classified it as not a vulnerability.
2026-10-22 20:10:42 -07:00
Jordan HarbandandElan Ruusamäe b1b3a0038c [Fix] nvm_cd: bypass a user-defined cd function
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests: xenial / xenial (dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-13) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
Tests: fast / fast (macOS, zsh) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.23) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: fast / fast (macOS, bash) (push) Canceled after 0s
Tests: fast / fast (macOS, dash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.17) (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests: nvm install with set -e / finisher (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-12) (push) Canceled after 0s
Tests: nvm install with set -e / matrix (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, dash) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, bash) (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-13) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-13) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.17) (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
latest-npm.yml / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-13) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
Tests: fast / fast (macOS, sh) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, sh) (push) Canceled after 0s
Tests: fast / fast (WSL Ubuntu-24.04, zsh) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.17) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
`\cd` only bypasses aliases, so a user-defined `cd` function (eg, cdhist's) still ran,
and broke `NVM_DIR` auto-detection when it rejected zsh's `-q`.

Use `command cd`, which skips functions in POSIX shells.
zsh's `command` runs `/usr/bin/cd` instead of the builtin,
so use `builtin cd` there, as `nvm_echo` does for `printf`.
`nvm_die_on_prefix` also now uses `nvm_cd` instead of a bare `cd`.

Fixes #3835. See #3836.

Co-authored-by: Elan Ruusamäe <glen@delfi.ee>
2026-10-09 21:16:17 -07:00
Jordan Harband 5c05fb659c [actions] cache container images, verified against digests looked up live
Each container job now looks up the image's index, manifest,
and config digests from the registry,
keys an `actions/cache` entry on the config digest,
and only uses a cached image if its ID matches one of those digests;
otherwise it is discarded and the image is pulled (with retries) instead.
A poisoned or stale cache entry can therefore never be used,
and a cache hit needs only a couple of small manifest requests,
so this scales regardless of pull rate limits.
2026-10-09 14:14:20 -07:00
Jordan Harband 37be73f11d [actions] pull container images through Google's Docker Hub mirror
DockerHub's anonymous pull rate limit applies per IP for hours,
so retrying cannot ride it out on shared runners;
`mirror.gcr.io` serves the same official images without that limit,
as the io.js source-install job already does.
2026-10-09 14:04:54 -07:00
Jordan Harband 077156e88f [actions] never let an apt install wait on a prompt
Moving WSL package installs out of `setup-wsl`'s `additional-packages` lost its non-interactive setup:
on Ubuntu 18.04, upgrading `libssl1.1` asks whether to restart services,
and the job waited on that dialog until it was cancelled.
Set `DEBIAN_FRONTEND=noninteractive`,
keep existing config files without asking, and give apt no stdin.
2026-10-08 11:10:27 -07:00
Jordan Harband 50e73c4cd5 [actions] retry apt package installs through Ubuntu mirror outages
Mirror outages have outlasted the existing retries,
which covered only `apt-get update` (and not the WSL `additional-packages` install).
Installs now go through `.github/scripts/apt-install.sh`,
which retries each request within apt and retries the whole update+install with backoff for about 10 minutes.
2026-10-07 15:10:36 -07:00
Jordan Harband 46ca42f939 [Tests] nvm install --reinstall-packages-from: mock the remote version instead of fetching it 2026-10-05 10:52:19 -07:00
Jordan Harband 52a1e55574 [actions] run the fast suite on macOS and WSL too
macOS covers a case-insensitive filesystem and bash 3.2
(`/bin/sh`, `/bin/bash`);
WSL covers Windows.
Both run it as the Linux jobs do:
without a system node, with a PTY,
and on WSL as a non-root user with passwordless sudo.
2026-09-30 16:12:14 +09:00
Jordan Harband 79bc9b90dd [Tests] make the fast suite pass on macOS
- `nvm_get_arch`: the unmocked smartos cases fall through to the host, so only run them on x86_64
- `nvm_get_arch_unofficial`: the chroot checks need x86_64 glibc Linux
- `nvm_install_no_progress_bar`: derive the tarball slug and checksum tool instead of assuming linux-x64 and `sha256sum`
2026-09-30 16:09:09 +09:00
Jordan Harband e2f57b733f [Fix] nvm alias: do not drop output from background jobs on bash 3.2
bash 3.2 (macOS `/bin/bash` and `/bin/sh`) exec-optimizes a trailing `command` call inside a function run as a background job,
which silently drops the output of nested command substitutions;
in `nvm alias` that lost installed-alias colors and some default aliases,
Running each job in an explicit subshell avoids it.
2026-09-30 15:56:49 +09:00
Jordan Harband 0add6b8555 [Fix] nvm: do not change or export the caller's IFS
`IFS=... nvm "$@"` is a prefix assignment to a function call, which bash's POSIX mode (macOS `/bin/sh`) keeps after the call returns, and exports.
2026-09-30 15:50:38 +09:00
Jordan Harband 3bfc2b4a9a [actions] rename windows-npm workflow to windows-nvm, since it tests nvm install 2026-09-30 15:25:38 +09:00
Jordan Harband 04ac3f2a83 [Fix] nvm install: do not remove the caller's TMPDIR after a failed download
`nvm_install_binary` and `nvm_install_source` declared `local TMPDIR` without initializing it, and remove it with `rm -rf` on failure. dash's `local` keeps the caller's value, as does bash's when `TMPDIR` is passed as a prefix assignment (`TMPDIR=… nvm install`), so a failed download removed the caller's temp directory; on macOS, `tar` instead blocked reading the archive from the terminal.
2026-10-05 10:02:48 -07:00
Jordan Harband 04fbd9570c [New] add nvm_has_italics, to detect terminal italics support via terminfo 2026-09-29 17:08:36 +09:00
Jordan Harband 09822033d2 [Fix] nvm exec/nvm run: do not treat filenames with digits as versions
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests: xenial / xenial (dash) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.23) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-13) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-24.04) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests: nvm install with set -e / finisher (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-12) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
Tests: nvm install with set -e / matrix (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.17) (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.17) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-13) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-12) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-13) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
latest-npm.yml / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-12) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.17) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-13) (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-12) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.23) (push) Canceled after 0s
`nvm_is_valid_version` accepted strings like `123.js`, `v1.js`, and `1.2.3.4.5.6.js`, because `nvm_version_greater_than_or_equal_to` exits as soon as the first number is greater than zero, without looking at the rest.
So `nvm run 123.js` failed with `N/A: version "v123.js" is not yet installed` instead of running the file.

It now checks the shape first: one to three dot-separated numbers, optionally with a trailing dot, and a prerelease suffix (rc, nightly, v8-canary, test builds) only after a full `x.y.z`.
A suffix with a dot followed by a non-digit, like a file extension, is rejected, so names like `1.2.3-foo.js` are treated as files too.
Every version listed in the nodejs.org and iojs.org `index.tab` files is still accepted, so shell startup keeps using a `default` alias that resolves to an installed prerelease.

Names that are also valid versions, like `123` or `v1`, are still treated as versions; `nvm run current 123` runs such a file.

Refs #1166. See #3931.
2026-09-28 15:05:28 +09:00
Jordan Harband a885b885fe v0.40.8
Tests: xenial / xenial (dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.17) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-13) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.17) (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.17) (push) Canceled after 0s
Tests: nvm install with set -e / finisher (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-12) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests: nvm install with set -e / matrix (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.17) (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-12) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-13) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-12) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-12) (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-13) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
latest-npm.yml / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-12) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.23) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.23) (push) Canceled after 0s
Bug Fixes

 - `nvm_alias`, `nvm_version_path`: reject `..` path components
 - `nvm_get_make_jobs`: count cores on platforms the `case` does not name
 - `nvm-exec`: improve the no-version failure message
 - `nvm use`: do not clobber `man`'s default search path (#3890)
 - `nvm_err`, `nvm_err_with_colors`: do not fail when stderr is closed (#3907)
 - `nvm_hash_reset`: only run `hash -r` where the shell supports it
 - `nvm_alias`: unset zsh's `extendedglob` while reading an alias file (#3891)
 - zsh: restore `nomatch` and `markdirs` rather than clobbering them
 - `nvm --help`: render the set-colors legend in color (#3915)
 - `nvm unload`: drop the undefined `nvm_format_help_message_colors`
 - `nvm_get_mirror`: allow ports, userinfo, IPv6 hosts, and percent-encoding
 - `nvm_sanitize_auth_header`: allow `~`, completing RFC 7235 `token68` (#3751)

Refactors

 - `nvm --help`: extract the set-colors legend into `nvm_print_color_legend`

Performance

 - Optimize nvm_tree_contains_path with in-memory POSIX parent-walk (#3912)

Docs

 - [readme] document platforms with no official node binaries
 - `install.sh`: Fix missing words in bash/zsh completion message (#3887)
 - Remove stray closing HTML tag (#3919)

Misc

 - [meta] remove CLAUDE.md symlink in favor of AGENTS.md (#3928)
 - [meta] add `release-notes.sh`, the release notes generator

Tests

 - homebrew/actions changed their default branch
 - [actions] WSL: pin every distribution, and test the newest of each line
 - `nvm_print_color_legend`: look up the function with `PATH` emptied
 - `nvm_print_color_legend`: check for the function, not a same-named file
 - `nvm_print_color_legend`: fix the `fast` suite on GNU userlands
 - [actions] `release.yml`: provide `GH_TOKEN` so release-notes PR lookup can run
2026-09-21 10:23:47 +08:00
Jordan Harband 072622c748 [Fix] nvm_alias, nvm_version_path: reject .. path components
`nvm_alias` concatenated the requested name onto `$NVM_DIR/alias` and read whatever that resolved to,
so a name with a `..` component escaped the alias dir
- under the default layout, `../../.npmrc` reaches `$HOME/.npmrc`.
`nvm_print_alias_file` echoes every non-comment line of what it opens,
and `nvm use` reports the first one in its "is not yet installed" error,
so an untrusted `.nvmrc` could disclose any file the invoking user can read.

The write side already rejected `..` in an alias name (9275c5ba);
apply the same check on the read side, and to `nvm_version_path`,
which composes a version into a path with no check of its own.

Slashes stay legal, since `lts/iron` and the `lts/*` alias file depend on them.
2026-09-21 10:01:34 +08:00
Jordan Harband 5267556406 [Tests] homebrew/actions changed their default branch 2026-09-21 09:17:45 +08:00
Jordan Harband a4f801ed72 [Fix] nvm_get_make_jobs: count cores on platforms the case does not name
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests: xenial / xenial (dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-24.04) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.17) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests: nvm install with set -e / finisher (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests: nvm install with set -e / matrix (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-13) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine-3.23) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine-3.23) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian-13) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
latest-npm.yml / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian-12) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine-3.17) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine-3.23) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-24.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian-13) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian-12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian-13) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine-3.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine-3.23) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine-3.23) (push) Canceled after 0s
`nvm_get_os` also returns `win` (Cygwin/MSYS/MinGW) and the empty string,
neither of which had an arm,
so `NVM_CPU_CORES` went unassigned
and nvm asked the user to report a gap it already knew about.
On an unrecognized `uname` that also meant a single-threaded source build;
`win` refuses source builds a few lines later either way.

`NUMBER_OF_PROCESSORS` comes last because Windows scopes it to the calling process' processor group.

Assigning `NVM_CPU_CORES` in every arm also keeps the
`nvm_is_natural_num` check below from aborting dash and ksh under `set -u`.
2026-09-10 17:08:50 -07:00
Jordan Harband 7fc22fc9c7 [readme] document platforms with no official node binaries
The README never said which platforms nvm can detect but nodejs.org does not build for,
so a user on one of them only finds out from a slow, silent, source-build fallback.

Also corrects the Alpine section:
nvm remaps Alpine to a musl arch itself now,
and nodejs.org has published `linux-x64-musl` since v24.20.0,
so both the "no concrete plans" and the "does not exist errors" claims are out of date.

Coverage bounds are stated per release line rather than per patch,
since the newest of them are still shipping.
2026-09-10 17:11:20 -07:00
Jordan Harband 74bb42ee23 [Fix] nvm-exec: improve the no-version failure message
The message claimed "no .nvmrc file found" even when one was found and its version simply was not installed,
and it never mentioned that `NODE_VERSION=default` selects the `default` alias.

Refs #3810
2026-09-08 23:47:09 -07:00
Jordan Harband e361b93e4b [Fix] nvm use: do not clobber man's default search path
`man` consults its own configured search path only when MANPATH holds an empty entry;
a list without one replaces the default outright.
`nvm use` produced exactly that,
so activating a version could hide every system man page.

Contribute the empty entry as a trailing one,
so that nvm's directory keeps precedence over the system's,
and only when the list has none already,
so that repeated `nvm use` calls are idempotent and an empty entry the user placed stays where they put it.

The `$(manpath)` snapshot this replaces went stale the moment man's configuration changed,
and cost a subprocess per `nvm use`.
It was also dead: `local MANPATH` scoped the assignment to `nvm()`,
so `export` did not outlive the call and MANPATH went untouched whenever it started out unset.
Only ksh, where `local` is not a builtin, ever ran it.

`nvm deactivate` now unsets MANPATH where nvm's was the only real entry,
rather than leaving a bare `:` behind.

Reported and diagnosed by @al0ksar in #3890, which used a leading empty entry instead.
That one accrues one more colon on every `nvm use`,
which `nvm deactivate` then leaves behind,
and it loses to the system's man pages wherever nvm's bin directory is not first on PATH.

Supersedes #2077.

Refs #3890
Refs #2077
2026-09-08 11:01:03 -07:00
Jordan Harband a5ff3a32f4 [actions] WSL: pin every distribution, and test the newest of each line
The Ubuntu entries were pinned but `Debian` and `Alpine` were floating
aliases, so what those jobs tested drifted whenever the action updated.

Every line now carries a pin and the newest release setup-wsl offers for
it: Debian 12 and 13, Ubuntu 18.04, 20.04 and 24.04, Alpine 3.17 and 3.23.
`Alpine-3.17` is the image the unofficial jobs already ran, named
explicitly. Debian's pin is 12 rather than 11 because `Debian` and
`Debian-11` share a floating `aka.ms/wsl-debian-gnulinux` redirect and so
cannot be held still at all, where `Debian-12` is an immutable
salsa.debian.org artifact. The Debian-only steps key off `startsWith`, so
both Debian entries take the same path and moving a pin will not strand them.

There is no floating "newest" name to use instead: `kali-linux` is the only
unversioned distribution left, and setup-wsl's own CI disables
`additional-packages` on it. The newest only moves when the action's major
does, so the `uses:` ref is the thing to keep current.

Which is the other half of this: move that ref from v6 to v7. v6 is a dead
major, five months stale at v6.1.0 with no v6.2.0 and v7.0.0 tagged the next
day, so new distributions will only ever appear on v7 and later. v7's only
removals are the deprecated bare `Debian` and `Alpine`, which pinning has
already stopped using, and every name here is valid on both. It also drops
the Node.js 20 deprecation warning each WSL job currently emits, and it
tightens two pins that v6 left floating: Ubuntu 20.04 moves from
`aka.ms/wslubuntu2004` to a 20.04.6 image on releases.ubuntu.com, and 24.04
to a 24.04.4 one. Six of the seven platforms are now immutable artifacts;
Ubuntu 18.04 predates the format and still redirects through aka.ms.

Choosing a supported Debian also settles the 404s that had been failing
every Debian job: bullseye left LTS on 2026-08-31 and its security suite is
between homes, with `security.debian.org` still publishing an index whose
pool is being pruned and `archive.debian.org` carrying no `debian-security`
for bullseye yet. bookworm is on live mirrors, so `ca-certificates` is
current again, which matters for a job whose whole purpose is to fetch nvm
and node over TLS.

To keep a pin working once its release ages out in turn, derive sources.list
from the image's own codename and list every layout a release passes through:
main and security move to the archive on separate schedules, and the security
suite is renamed to `<codename>/updates` on the way. `apt-get update`
discards whichever entries 404, and where an index outlives its pool we fall
back once to main alone. Debian 13 moved to deb822, so clear both formats
first and leave what we write as the only thing apt reads.

Drop the blanket `apt-get upgrade` with it: it fetched 77 packages the test
never uses, and `apt-get install` already takes the newest version any
working mirror offers.
2026-09-08 11:01:02 -07:00
Jordan Harband aeace4606f [Fix] nvm_hash_reset: only run hash -r where the shell supports it
Under bash's `set +h`, `hash -r` errors with "hash: hashing disabled",
which is then printed on every `nvm use`, including the one at shell startup.

Guarding on `$-` alone would be wrong:
`zsh` never puts `h` in `$-` - there `h` is `HIST_IGNORE_DUPS` -
and `dash` has no `h` flag at all,
so it would skip the call in 3 of the 4 shells the fast suite runs.

Gate on the shell instead, and skip only where the call fails:
bash under `set +h`, and `ksh93`, whose `hash` takes no `-r` and whose
usage error aborts `nvm use` before it can export `NVM_BIN`.
`ksh` is detected by probing rather than by version,
so `mksh` and `pdksh`, which do accept `-r`, keep getting the call.

The `${-#*h}` test is from #3910.

Refs #2065
Refs #3247
2026-09-04 09:16:10 -07:00
Jordan Harband 25b378323c [Fix] zsh: restore nomatch and markdirs rather than clobbering them
`unsetopt local_options nomatch` unsets both named options,
so LOCAL_OPTIONS is off by the time the function returns and the
`nomatch` change escapes into the caller's shell:
one `nvm ls` or `nvm alias` leaves NO_MATCH off for the rest of the session,
after which an unmatched glob is silently passed through as a literal.

`setopt local_options nonomatch`,
already used in `nvm_check_file_permissions`, restores on return.

The `markdirs` line also cancelled the snapshot
taken for `shwordsplit` on the line above it;
that one is latent,
as `nvm_ls` is only ever called inside a command substitution.
2026-09-03 20:44:59 -07:00
Jordan Harband 38f0f2cfdf [Tests] nvm_print_color_legend: look up the function with PATH emptied
The presence checks were still satisfiable by this test file itself,
which is an executable named `nvm_print_color_legend`.
Filtering `command -v` output on a `/` was not enough:
dash and zsh report a bare name,
not a path,
for a current-directory match reached through an empty `PATH` component,
and that is indistinguishable from a function.
So `nvm unload` looked as though it had left the function behind in exactly the shells CI runs as `sh`, `dash`, and `zsh`,
while bash, which reports `./name`, passed.

Emptying `PATH` for the lookup asks about the function alone,
and is immune to whatever `PATH` happens to hold.

Reproduced first, then fixed:
with `PATH=":${PATH}"` the previous check fails under dash and zsh
and passes under bash, matching CI exactly.
The assertions now hold in sh, bash, dash, and zsh
with the directory absent from `PATH`, present on it, and via an empty entry,
and both dropping `nvm_print_color_legend` from `nvm unload`
and renaming the function out from under the guard
are still caught in all twelve combinations.
2026-09-03 15:12:34 -07:00
Jordan Harband 812a76bb41 [Fix] nvm unload: drop the undefined nvm_format_help_message_colors
`unset -f` was passed a name that has never been a function.
It arrived with `set-colors` in 6848c16d and has never existed.

That matters because shells disagree about what `unset -f` does with a name that is not a function.
bash unsets the rest of the list and carries on;
Linux dash and zsh appear to stop there,
which silently left every one of the ten names after it defined:
`nvm_echo_with_colors`, `nvm_err_with_colors`,
`nvm_get_artifact_compression`, `nvm_install_binary_extract`,
`nvm_extract_tarball`, `nvm_process_nvmrc`,
`nvm_process_nvmrc_content`, `nvm_nvmrc_invalid_msg`,
`nvm_write_nvmrc`, and most recently `nvm_print_color_legend`.

Nothing noticed until `nvm_print_color_legend` gained a test
asserting that `nvm unload` removes it,
because it sorts first among the survivors.

With the dead name gone,
every remaining entry is a real function,
so no shell has an undefined name to disagree about.
2026-09-03 13:57:58 -07:00
Jordan Harband 26fef4fe1a [Tests] nvm_print_color_legend: check for the function, not a same-named file
The presence checks used `command -v`,
which finds executables as readily as functions,
and this test file is itself an executable named `nvm_print_color_legend`.
Whenever its own directory is on `PATH`, as it is under CI,
`command -v` kept resolving to the file
long after `nvm unload` had removed the function,
so the unload assertion could never pass there
and the "is it defined" guard could never fail.

`command -v` prints a bare name for a function
and a path for an executable,
in sh, bash, dash, zsh, and ksh alike,
so requiring the result to contain no slash
distinguishes the two.

Verified both ways round:
with the test's directory on `PATH`
the suite passes in all four shells,
and removing `nvm_print_color_legend` from `nvm unload`'s list
is still caught in all four.
2026-09-03 12:08:18 -07:00
Jordan Harband 17f12a1207 [Tests] nvm_print_color_legend: fix the fast suite on GNU userlands
The `nvm unload` assertion failed every `fast` job on Linux
while passing on macOS,
and its shape made the cause impossible to read off the failure.
`set -e` aborts the command substitution
when `nvm unload` returns non-zero,
which leaves an empty string
that the assertion then reports as
"unload left nvm_print_color_legend defined".
Run the unload with `set +e` inside the subshell
and report its exit status next to the lookup,
so a failing unload can no longer be misread
as a function that survived it.

The accompanying `sed: couldn't flush stdout: Broken pipe`
came from the `grep -q` pipelines:
`grep -q` exits at its first match
and hands SIGPIPE to the `sed` feeding it,
which BSD sed swallows and GNU sed reports.
Match whole lines with `case` against the already-captured string instead,
which needs no pipe at all,
and capture `nvm --help` before stripping it
rather than piping it through two processes into `grep -q`.

Test stderr is now empty in sh, bash, dash, and zsh.
2026-09-03 11:54:45 -07:00
Jordan Harband ab83657ba6 [Refactor] nvm --help: extract the set-colors legend into nvm_print_color_legend 2026-09-03 10:17:16 -07:00
Jordan Harband 10a277ec47 [Fix] nvm_get_mirror: allow ports, userinfo, IPv6 hosts, and percent-encoding
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests: xenial / xenial (dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 2 shlvls) (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine) (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests: nvm install with set -e / finisher (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: nvm install with set -e / matrix (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
nvm-install-test.yml / test (nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine) (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
latest-npm.yml / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
nvm-install-test.yml / test (no nvmrc, ${{ fromJson(needs.matrix.outputs.matrix) }}, 1 shlvl) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine) (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine) (push) Canceled after 0s
3c480159 correctly made this validator actually enforce,
instead of the no-op `awk '{ $0 ~ "..." }'` it had been,
but its character class had never been audited against real mirror URLs:
it has no `:`,
so enabling enforcement silently rejected every mirror URL bearing a port.

    $ NVM_NODEJS_ORG_MIRROR=https://mirror.internal:8443/dist nvm_ls_remote
    $NVM_NODEJS_ORG_MIRROR and $NVM_IOJS_ORG_MIRROR may only contain a URL

No request is made at all,
so an internal mirror on a non-default port has been unusable since v0.40.5.

Allow RFC 3986 `unreserved` plus the authority and path punctuation
a mirror URL legitimately needs:
`:` for a port,
`@` for userinfo,
`[`/`]` for an IPv6 literal host,
and `%` for percent-encoding.

`sub-delims` and the query/fragment delimiters stay rejected:
nvm appends a path to this value,
so a query string could never have worked,
and several of those characters are shell metacharacters.
2026-09-02 19:40:47 -07:00
Jordan Harband 6798d1dbc9 [actions] release.yml: provide GH_TOKEN so release-notes PR lookup can run
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests: xenial / xenial (dash) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine) (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine) (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine) (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine) (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine) (push) Canceled after 0s
In GitHub Actions, `gh` refuses to run without a token,
and `release-notes.sh` fails closed on `gh` errors,
so the `make release` dry run died once the script was checked in.
The workflow already permits `api.github.com` egress and only needs the default read-only token.
2026-08-17 23:33:17 -07:00
Jordan Harband df7a936157 [meta] add release-notes.sh, the release notes generator
The `release` target has invoked `./release-notes.sh` since 0b8ed9fa,
but the script itself was never committed,
so the "Tests: release process" workflow fails on a fresh checkout.
2026-08-17 23:21:32 -07:00
Jordan Harband f0b0c6bb0b v0.40.7
New Stuff

 - `nvm install`: serialize concurrent installs of the same version
 - `nvm install`: add `NVM_NO_SOURCE_FALLBACK` to disable the source fallback

Robustness

 - `nvm install`: reject a structurally broken installed version
 - `nvm_install_binary_extract`: replace a broken version dir atomically
 - `install.sh`: `nvm_download`: avoid `eval` so arguments aren't re-parsed by the shell

Docs

 - [readme] link every referenced person and project to its canonical page

Misc

 - [Dev Deps] update `markdown-link-check`

Tests

 - install_nvm_from_git: don't fail when master is at the latest release tag
2026-08-17 23:08:13 -07:00
Jordan Harband 0b8ed9fa7d [Dev Deps] update markdown-link-check 2026-08-17 22:59:46 -07:00
Jordan Harband 65ded65d46 [readme] link every referenced person and project to its canonical page
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (sh, gawk) (push) Canceled after 0s
Tests: fast / fast (bash, mawk) (push) Canceled after 0s
Tests: installation_node / installation_node (dash, without curl) (push) Canceled after 0s
Tests: installation_node / installation_node (sh, without curl) (push) Canceled after 0s
Tests: xenial / xenial (dash) (push) Canceled after 0s
urchin tests / tests (sh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Canceled after 0s
Tests: fast / fast (zsh, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (bash) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (sh) (push) Canceled after 0s
urchin tests / tests (bash, install_script) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.1) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Canceled after 0s
Code scanning - action / CodeQL-Build (push) Canceled after 0s
Tests: linting / doctoc (push) Canceled after 0s
Tests: release process / release (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Canceled after 0s
Tests: fast / fast (dash, gawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (dash) (push) Canceled after 0s
Tests: installation_node / installation_node (sh) (push) Canceled after 0s
urchin tests / tests (dash, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.10) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.0) (push) Canceled after 0s
Tests: xenial / all xenial tests (push) Canceled after 0s
Tests on Windows: `nvm install` / tests, on windows (push) Canceled after 0s
Tests: `nvm install-latest-npm` / matrix (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Canceled after 0s
Tests: fast / fast (bash, gawk) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh) (push) Canceled after 0s
urchin tests / tests (zsh, sourcing) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (0.12) (push) Canceled after 0s
Tests: linting / all linting (push) Canceled after 0s
Tests: fast / all fast tests (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Canceled after 0s
Tests: fast / fast (zsh, mawk) (push) Canceled after 0s
urchin tests / tests (dash, slow) (push) Canceled after 0s
urchin tests / tests (sh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.4) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.5) (push) Canceled after 0s
Tests: linting / eclint (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Canceled after 0s
Tests: installation_node / installation_node (dash) (push) Canceled after 0s
Tests: fast / fast (dash, mawk) (push) Canceled after 0s
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Canceled after 0s
Tests: xenial / xenial (bash) (push) Canceled after 0s
Tests: xenial / xenial (sh) (push) Canceled after 0s
Tests: xenial / xenial (zsh) (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / Cygwin nvm install (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (21) (push) Canceled after 0s
Tests: linting / dockerfile_lint (push) Canceled after 0s
Tests: linting / check_exec (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Canceled after 0s
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Canceled after 0s
Tests: installation_node / installation_node (bash) (push) Canceled after 0s
urchin tests / tests (bash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (bash, sourcing) (push) Canceled after 0s
urchin tests / tests (dash, installation_iojs) (push) Canceled after 0s
urchin tests / tests (sh, installation_iojs) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.17) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (9.2) (push) Canceled after 0s
Tests: installation_node / all installation_node tests (push) Canceled after 0s
urchin tests / all test suites, all shells (push) Canceled after 0s
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, dash) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Canceled after 0s
Tests: fast / fast (sh, mawk) (push) Canceled after 0s
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Canceled after 0s
Tests: installation_node / installation_node (zsh, without curl) (push) Canceled after 0s
urchin tests / tests (bash, slow) (push) Canceled after 0s
urchin tests / tests (zsh, installation_iojs) (push) Canceled after 0s
urchin tests / tests (zsh, slow) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (${{ fromJson(needs.matrix.outputs.latest) }}) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (14.16) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (5.9) (push) Canceled after 0s
Tests: shellcheck / shellcheck (push) Canceled after 0s
Tests: linting / test_naming (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, sh) (push) Canceled after 0s
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Canceled after 0s
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Canceled after 0s
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Canceled after 0s
Tests: installation_node / installation_node (bash, without curl) (push) Canceled after 0s
update readme TOC / update readme TOC (push) Canceled after 0s
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (20.5) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (4.6) (push) Canceled after 0s
Tests: `nvm install-latest-npm` / nvm install-latest-npm (6.1) (push) Canceled after 0s
Tests: alpine / all alpine tests (push) Canceled after 0s
Tests: installation_iojs / all installation_iojs tests (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine) (push) Canceled after 0s
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine) (push) Canceled after 0s
Link the first mention of each named person to their GitHub and each named project, tool, or OS to its official homepage or repo.

Mentions that appear only inside a heading (Ansible),
an HTML comment (doctoc),
or a multi-word code span (grunt) are left unlinked,
since a link there would
break the generated table-of-contents anchors or fail to render.
2026-07-24 11:11:57 -07:00
Jordan Harband 809f3ee5ab [New] nvm install: serialize concurrent installs of the same version
Two `nvm install <same version>` runs could race on the version directory
- one removing or replacing it while the other reads or writes it.
Take a per-version advisory lock
(an atomically-created directory under $NVM_DIR/.cache locks)
around the binary/source install,
so a second run of the same version waits for the first;
installs of different versions never contend.

NVM_INSTALL_LOCK_TIMEOUT (seconds, default 600) bounds the wait,
after which nvm reports the lock path so a lock left by a killed install can be removed.
NVM_INSTALL_LOCK_STALE (minutes, default 0 / off)
opts into automatically stealing a lock older than that,
for unattended or CI use.
2026-07-24 10:55:58 -07:00
Jordan Harband 9570a22bfe [New] nvm install: add NVM_NO_SOURCE_FALLBACK to disable the source fallback
By default a failed binary download falls back to compiling node from source,
which is slow and pointless on platforms that always have prebuilt binaries.
`-b` already disables the fallback per-invocation;
`NVM_NO_SOURCE_FALLBACK=1` makes it the default for every `nvm install`,
so CI images and dev setups need not thread `-b` through every callsite.

It behaves exactly like `-b`
- aborting with a non-zero exit on a failed binary download
- and is mutually exclusive with `-s`, for the same reason `-b` is.
2026-07-24 10:54:17 -07:00
Jordan Harband aee1f83f0f [Robustness] nvm install: reject a structurally broken installed version
`nvm_is_version_installed` only checks that `bin/node` has the execute bit,
which a zero-byte binary and a dangling `npm` symlink both pass, so a partial
install could be reported as a success — and a broken existing version could
short-circuit `nvm install` as "already installed".

Add `nvm_validate_install`, which requires a non-empty `bin/node` and an `npm`
entry that resolves, and use it in two places: gate the "already installed"
shortcut on it, so a broken version is reinstalled rather than reused, and
re-check it after an install reports success, so a broken result fails loudly
instead of being activated.

It checks layout, not execution: a correctly installed binary can still fail
to run on an incompatible host (e.g. a newer node on an older glibc), which is
not a broken install, and a corrupt download is already rejected by the
checksum check before extraction.
2026-07-24 10:51:53 -07:00
Jordan Harband 72a878447f [Robustness] nvm_install_binary_extract: replace a broken version dir atomically
A version directory left without a working `bin/node`
- e.g. a partial or interrupted earlier install
- wedged reinstallation:
`nvm install` saw the version as not installed and re-extracted,
but the per-entry `mv` refused to overwrite the leftover non-empty `bin/`,
`lib/`, … subdirectories and left a half-updated tree behind
(and, without `-b`, fell back to a from-source compile)

Remove any pre-existing version directory and move the freshly extracted tree into place with a single rename,
so a version is either fully installed or not present at all.
The removal is safe: it runs only after the tarball has downloaded and extracted successfully into the cache.
Fall back to the previous per-entry move when a single rename cannot cross filesystems.
2026-07-24 10:50:47 -07:00
Jordan Harband b17550a0b9 [Robustness] install.sh: nvm_download: avoid eval so arguments aren't re-parsed by the shell
Tests: `nvm install-latest-npm` / matrix (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, bash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Has been cancelled
urchin tests / tests (dash, installation_iojs) (push) Has been cancelled
Tests on Windows: `nvm install` / Cygwin nvm install (push) Has been cancelled
Tests: fast / fast (zsh, gawk) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (sh) (push) Has been cancelled
Tests: installation_node / installation_node (bash, without curl) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (bash) (push) Has been cancelled
Code scanning - action / CodeQL-Build (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, zsh) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Has been cancelled
Tests: xenial / xenial (dash) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Has been cancelled
Tests: xenial / all xenial tests (push) Has been cancelled
Tests: fast / all fast tests (push) Has been cancelled
Tests: fast / fast (bash, mawk) (push) Has been cancelled
Tests: fast / fast (dash, mawk) (push) Has been cancelled
Tests: installation_node / installation_node (zsh) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine) (push) Has been cancelled
Tests: installation_node / all installation_node tests (push) Has been cancelled
Tests: linting / eclint (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, sh) (push) Has been cancelled
urchin tests / tests (bash, installation_iojs) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Has been cancelled
urchin tests / tests (dash, sourcing) (push) Has been cancelled
urchin tests / tests (sh, sourcing) (push) Has been cancelled
urchin tests / tests (zsh, installation_iojs) (push) Has been cancelled
Tests on Windows: `nvm install` / tests, on windows (push) Has been cancelled
Tests: installation_node / installation_node (bash) (push) Has been cancelled
Tests: installation_node / installation_node (dash, without curl) (push) Has been cancelled
Tests: installation_node / installation_node (sh, without curl) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, bash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Has been cancelled
Tests: release process / release (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Has been cancelled
urchin tests / tests (sh, slow) (push) Has been cancelled
urchin tests / tests (zsh, slow) (push) Has been cancelled
Tests: shellcheck / shellcheck (push) Has been cancelled
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine) (push) Has been cancelled
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Has been cancelled
Tests: fast / fast (bash, gawk) (push) Has been cancelled
Tests: installation_node / installation_node (zsh, without curl) (push) Has been cancelled
urchin tests / tests (dash, slow) (push) Has been cancelled
urchin tests / tests (zsh, sourcing) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian) (push) Has been cancelled
Tests: linting / doctoc (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, dash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, sh) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Has been cancelled
urchin tests / tests (bash, install_script) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Has been cancelled
Tests: xenial / xenial (bash) (push) Has been cancelled
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Has been cancelled
urchin tests / tests (bash, sourcing) (push) Has been cancelled
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Has been cancelled
Tests: alpine / all alpine tests (push) Has been cancelled
Tests: fast / fast (zsh, mawk) (push) Has been cancelled
Tests: installation_node / installation_node (dash) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine) (push) Has been cancelled
urchin tests / all test suites, all shells (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, dash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Has been cancelled
urchin tests / tests (bash, slow) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Has been cancelled
Tests: fast / fast (dash, gawk) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (dash) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine) (push) Has been cancelled
Tests: linting / test_naming (push) Has been cancelled
Tests: linting / check_exec (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Has been cancelled
Tests: xenial / xenial (zsh) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Has been cancelled
Tests: linting / all linting (push) Has been cancelled
Tests: fast / fast (sh, mawk) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Has been cancelled
Tests: installation_node / installation_node (sh) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Has been cancelled
Tests: linting / dockerfile_lint (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Has been cancelled
Tests: xenial / xenial (sh) (push) Has been cancelled
urchin tests / tests (sh, installation_iojs) (push) Has been cancelled
update readme TOC / update readme TOC (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Has been cancelled
Tests: installation_iojs / all installation_iojs tests (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine) (push) Has been cancelled
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Has been cancelled
Tests: fast / fast (sh, gawk) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Has been cancelled
`install.sh` has its own `nvm_download`,
which joined `"$@"` into a single string with `nvm_echo` and rewrote the curl-style flags with `sed`,
then ran the result through `eval command wget $ARGS`.
Flattening argv into a string is the root cause: every argument was re-parsed by the shell,
so any shell metacharacter in a legitimate value was interpreted rather than passed through.
An `$NVM_DIR` containing a space silently word-split and wrote to the wrong path,
an apostrophe or parentheses were a syntax error,
a glob character expanded against the cwd,
and an `$NVM_SOURCE` mirror URL with an `&` in its query string backgrounded `wget` and ran the remainder as a bogus command.
The `sed` rewrites were also unanchored substring replacements that would mangle a URL legitimately containing `-o `,
and `ARGS` was an undeclared global that `nvm_reset` never unset.

Translate the flags per-argument with a POSIX `set --` loop and invoke `command wget "$@"` instead,
so each argument stays a literal argv element.
This is the same shape `nvm.sh`'s `nvm_download` has used since 6d870d18,
and it stops the two implementations from diverging.

Unlike `nvm.sh`, no mirror-supplied data reaches this function:
its arguments come only from `$NVM_SOURCE`, `$NVM_INSTALL_GITHUB_REPO`, `$NVM_INSTALL_VERSION`, `$NVM_DIR`, `$XDG_CONFIG_HOME`, and `$HOME`, and `install.sh`'s `nvm_latest_version` is a hardcoded string rather than `nvm.sh`'s `nvm_get_latest`.
This is therefore a robustness fix and not a security one,
since the only party who can influence these arguments is the one already running the installer.
2026-07-15 15:55:21 -07:00
Jordan Harband 52047edfb1 [Tests] install_nvm_from_git: don't fail when master is at the latest release tag
The avoid_ref check read HEAD's tags via `git for-each-ref` with no --git-dir,
so it inspected the caller's checkout instead of the installed clone.
Whether it passed then depended on which ref triggered the workflow
(the same commit passed when built as the v0.40.6 tag but failed when built as master, since only the former had the tag present),
not on the install result.
Query the installed clone and compare commits,
so a HEAD that is legitimately the latest release commit
(eg master right after a release)
is exempted deterministically.
2026-07-15 15:02:22 -07:00
Jordan Harband b6cf55f6ad v0.40.6 2026-07-15 14:09:54 -07:00
Jordan Harband 9275c5badd [Robustness] reject unsafe LTS alias names from a mirror's index.tab
A mirror-supplied LTS codename (field 10 of index.tab) was used verbatim as an alias filename,
so a hostile codename such as `../../../.bashrc` could make nvm_make_alias write outside $NVM_DIR/alias
- with the default layout, into shell startup files.
Constrain remote codenames to safe filename characters at ingestion in nvm_ls_remote_index_tab,
and reject any `..` path component in nvm_make_alias as a backstop for every caller.
2026-07-15 13:46:52 -07:00
Jordan Harband 882ed79ece [Docs] threat model: document the mirror payload/metadata trust boundary
Payloads
(binaries, plus source tarballs that nvm compiles and runs at install time) are trusted by construction,
since nvm exists to build and run them;
parsed metadata (index.tab, SHASUMS, LTS codenames) is not,
and must never reach a command evaluator,
an awk/sed program body,
or an unvalidated filesystem path.
This records why the existing version-string and checksum hardening exists,
and scopes a malicious payload from a configured mirror as out of scope:
no privilege boundary is crossed.
2026-07-15 13:44:04 -07:00
Jordan Harband d83da5d75b [actions] add tests-alpine: a green fast suite and a musl-binary regression matrix
The full suite cannot run on Alpine: the install-based suites pin ancient Node (0.10.x, io.js) that has no musl binary and cannot source-compile on musl.
Run the fast unit suite instead (mirroring the ubuntu runner: non-root via su-exec, passwordless sudo, a PTY, no system node), plus a binary-only regression matrix that installs every (Alpine, Node) pair with a real unofficial musl binary via `nvm install -b`: x64 back to node 8.17.0 on old Alpine, arm64 at the v20.20.1/v22.21.1/v24.9.0 floors on modern Alpine.
2026-07-14 23:18:07 -07:00
Jordan Harband 438009f54e [Tests] make the fast suite pass on Alpine
`nvm_get_arch`: skip the smartos arm64/armv8l cases, which have no uname mock and fall through to the real host (adding a musl suffix on Alpine).
`nvm_get_arch_unofficial`: skip the glibc chroot (fixed /lib64 loader, sudo); the musl mapping is already covered by the `nvm_get_arch alpine` test.
`nvm_install_no_progress_bar`: skip below the musl floor, since v0.12.18 has no musl binary and hardcodes the glibc tarball URL.
2026-07-14 23:17:01 -07:00