fix(install): put mise's Node on PATH and refuse Node older than 22.6 - #245
Merged
Merged
Conversation
On a machine with no Node.js the installer bootstrapped mise and `mise use -g node@lts` installed Node 24, but only mise's own bin dir was ever added to PATH, never its shims. The next check could not see node, so every bare box, as root or as a sudo user, ended with "Failed to install Node.js via mise." and exit 1. mise's shims dir now goes on PATH for the rest of the run, `mise reshim` gives threatcrush a shim once npm has installed it, and new login shells find it through one marked line appended to ~/.profile. That line is written only when this run bootstrapped Node itself. When the login shell reads ~/.bash_profile, ~/.bash_login or ~/.zprofile instead, the installer leaves those files alone and prints the line to add. On an existing Node.js older than 22.6 (Ubuntu's apt nodejs is 18.19.1), npm only printed EBADENGINE warnings and the installer reported success. The daemon then segfaulted loading better-sqlite3. The CLI now declares engines.node >=22.6 (@profullstack/hqtui needs 22.6, better-sqlite3 13 needs 22), and the installer stops before installing anything. Its message names the version it found, the version required, and how to upgrade. If `threatcrush --version` fails after install, the installer now reports a failure instead of "ThreatCrush unknown installed successfully!". The mise test used to grep the script for `mise use -g node@lts`. It now runs the real script under sh against stub node, npm, mise and curl.
ThreatCrush Security Scan13 finding(s) HIGH/CRITICAL: 1 | MEDIUM: 6 | LOW: 6
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Bare machines install again. With no Node.js,
install.shbootstraps mise andmise use -g node@ltsinstalls Node 24 correctly. Before this PR,ensure_mise_pathonly added mise's own bin dir (~/.local/bin) to PATH and never mise's shims, so the next check found nonodeand every bare box, as root or as a sudo user, ended withFailed to install Node.js via mise.and exit 1. Now:${MISE_DATA_DIR:-${XDG_DATA_HOME:-~/.local/share}/mise}/shims) goes on PATH for the rest of the run, so the global install runs with mise's npm.mise reshimruns after the install. npm linksthreatcrushinto mise's version-stamped node dir, and without a reshim it gets no shim.~/.profile: one markedexport PATH="<shims>:$PATH"line, appended only if the line isn't already there, and only when this run bootstrapped Node itself. It then prints exactly what it added. A user who already had a usable Node.js is never touched. bash skips~/.profilewhen~/.bash_profileor~/.bash_loginexists, and zsh reads~/.zprofile. Those files are the user's own, so in those cases the installer leaves them alone and prints the line to add. Every path also prints the line to paste into the current shell, becausecurl | shcan't change its parent's PATH.mise usefails, the installer now shows mise's output. Before, the failure either exited silently underset -eor went through amise installfallback. That fallback never activated a version, so the shims had nothing to run.Node.js older than 22.6 is refused before anything is installed. On Ubuntu's
apt install nodejs npm(18.19.1), npm only printed EBADENGINE warnings, the installer said✓ ThreatCrush 0.13.7 installed successfully!, andthreatcrush daemonthen segfaulted in better-sqlite3.apps/cli/package.jsonnow declares"engines": { "node": ">=22.6" }.@profullstack/hqtui0.5 needs>=22.6andbetter-sqlite313 needs>=22.A CLI that doesn't run is no longer reported as installed. If
threatcrush --versionfails after install, the installer prints its output and exits 1. Before, it printed✓ ThreatCrush unknown installed successfully!.shellcheck can read the file again. A directive written
# shellcheck disable=SC2086 -- …is a parse error (SC1073) that stopped shellcheck from checking anything. The trailing comment now starts with#.Tests exercise the script instead of grepping it.
install-script.test.tsused to check that the script containedmise use -g node@lts. The new tests run the realinstall.shunder/bin/sh(dash) in a temp HOME. PATH holds only real coreutils plus stubs: acurlthat serves a fake mise installer and fails any other URL, a fake mise that installs a fake node/npm and writes shims, and node/npm stubs that report a chosen version and record their argv. They cover:. ~/.profile) runsthreatcrush;.bash_profile/.bash_login/ zsh left untouched, and the printed line works;engines.node, so the installer and the package can't drift apart;Two
install-docs.test.tsassertions that pinned the old README sentence were removed rather than re-pinned.Docs.
README.mdandapps/cli/README.mdnow state the Node.js 22.6+ requirement and what the installer does when Node is missing or too old./docsdoesn't mention a Node version, so it is unchanged.How verified
Each container was fresh and started with
--init. The branch was mounted read-only and run assh /src/apps/web/public/install.sh; the live URL was not used. npm'slatestwas 0.13.9 at run time (0.13.8/0.13.9 were published at 19:19 UTC today), so the installer installed 0.13.9, not 0.13.7.ubuntu:24.04, root, onlycurl ca-certificates: installer exit 0.bash -lc 'command -v threatcrush; threatcrush --version'→/root/.local/share/mise/shims/threatcrush,0.13.9.bash -lc 'threatcrush start && threatcrush status'→✓ threatcrushd started,Status: ● RUNNING,Version: 0.13.9,Mode: system, exit 0.ubuntu:24.04, non-roottcuser(bash, passwordless sudo), onlycurl ca-certificates sudo:su - tcuser -c 'sh …/install.sh'exited 0 and added the same line to/home/tcuser/.profile. Thensu - tcuser -c 'threatcrush --version'→0.13.9, andsu - tcuser -c 'threatcrush start && threatcrush status'→Status: ● RUNNING,Mode: user, exit 0.ubuntu:24.04+apt install nodejs npm(v18.19.1): installer exit 1.threatcrushwas not on PATH,npm ls -ghad no threatcrush, mise had not been installed, and~/.profilewas unchanged.Following the message (
apt remove nodejs npm, re-run) bootstrapped v24.21.0 and printed✓ ThreatCrush 0.13.9 installed successfully!. A newbash -lcshell then gave0.13.9andStatus: ● RUNNING.node:22-bookworm(v22.23.3 at/usr/local/bin/node), root: same flow as before this PR: npm install,✓ ThreatCrush 0.13.9 installed successfully!, exit 0. mise was not installed and no~/.profileline was written.bash -lc 'threatcrush start && threatcrush status'→Status: ● RUNNING.install.shfrom master, the newinstall-script.test.tshas 8 failing tests; against this branch, 19/19 pass.pnpm --filter @profullstack/threatcrush-web test: 55 files, 484 tests passed (re-run after rebasing onto 42ed31d).pnpm --dir apps/web exec tsc --noEmitexits 0. On master it reported TS2769 (NODE_ENVmissing from the hermeticenv) in this test file.-s sh: the only remaining finding is SC2024 on the pre-existingsudo npm … >"$LOG", where writing the log as the invoking user is intended.