From dbd577cde66bf89b6bf4fac417337185bc7984e2 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Fri, 11 Jul 2025 23:53:52 -0800 Subject: [PATCH] ci: download exact version of node specifed (#20936) Co-authored-by: nektro <5464072+nektro@users.noreply.github.com> --- .buildkite/Dockerfile | 8 +- scripts/bootstrap.sh | 121 +++++++++++++++++++++++---- test/js/node/process/process.test.js | 6 +- 3 files changed, 110 insertions(+), 25 deletions(-) diff --git a/.buildkite/Dockerfile b/.buildkite/Dockerfile index 18388fe6c5..e2747b3f85 100644 --- a/.buildkite/Dockerfile +++ b/.buildkite/Dockerfile @@ -1,8 +1,6 @@ ARG LLVM_VERSION="19" ARG REPORTED_LLVM_VERSION="19.1.7" ARG OLD_BUN_VERSION="1.1.38" -ARG DEFAULT_CFLAGS="-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -ffunction-sections -fdata-sections -faddrsig -fno-unwind-tables -fno-asynchronous-unwind-tables" -ARG DEFAULT_CXXFLAGS="-flto=full -fwhole-program-vtables -fforce-emit-vtables" ARG BUILDKITE_AGENT_TAGS="queue=linux,os=linux,arch=${TARGETARCH}" FROM --platform=$BUILDPLATFORM ubuntu:20.04 as base-arm64 @@ -12,8 +10,6 @@ FROM base-$TARGETARCH as base ARG LLVM_VERSION ARG OLD_BUN_VERSION ARG TARGETARCH -ARG DEFAULT_CXXFLAGS -ARG DEFAULT_CFLAGS ARG REPORTED_LLVM_VERSION ENV DEBIAN_FRONTEND=noninteractive \ @@ -64,9 +60,7 @@ RUN echo "ARCH_PATH=$([ "$TARGETARCH" = "arm64" ] && echo "aarch64-linux-gnu" || ENV LD_LIBRARY_PATH=/usr/lib/gcc/${ARCH_PATH}/13:/usr/lib/${ARCH_PATH} \ LIBRARY_PATH=/usr/lib/gcc/${ARCH_PATH}/13:/usr/lib/${ARCH_PATH} \ CPLUS_INCLUDE_PATH=/usr/include/c++/13:/usr/include/${ARCH_PATH}/c++/13 \ - C_INCLUDE_PATH=/usr/lib/gcc/${ARCH_PATH}/13/include \ - CFLAGS=${DEFAULT_CFLAGS} \ - CXXFLAGS="${DEFAULT_CFLAGS} ${DEFAULT_CXXFLAGS}" + C_INCLUDE_PATH=/usr/lib/gcc/${ARCH_PATH}/13/include RUN if [ "$TARGETARCH" = "arm64" ]; then \ export ARCH_PATH="aarch64-linux-gnu"; \ diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 0107374fdf..3b742cf365 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Version: 14 +# Version: 15 # A script that installs the dependencies needed to build and test Bun. # This should work on macOS and Linux with a POSIX shell. @@ -733,28 +733,119 @@ nodejs_version() { } install_nodejs() { - case "$pm" in - dnf | yum) - bash="$(require bash)" - script=$(download_file "https://rpm.nodesource.com/setup_$(nodejs_version).x") - execute_sudo "$bash" "$script" + # Download Node.js directly from nodejs.org + nodejs_version="$(nodejs_version_exact)" + + # Determine platform name for Node.js download + case "$os" in + darwin) + nodejs_platform="darwin" ;; - apt) - bash="$(require bash)" - script="$(download_file "https://deb.nodesource.com/setup_$(nodejs_version).x")" - execute_sudo "$bash" "$script" + linux) + nodejs_platform="linux" + ;; + *) + error "Unsupported OS for Node.js download: $os" ;; esac - case "$pm" in - apk) - install_packages nodejs npm + # Determine architecture name for Node.js download + case "$arch" in + x64) + nodejs_arch="x64" + ;; + aarch64) + nodejs_arch="arm64" ;; *) - install_packages nodejs + error "Unsupported architecture for Node.js download: $arch" ;; esac + case "$abi" in + musl) + nodejs_mirror="https://bun-nodejs-release.s3.us-west-1.amazonaws.com" + nodejs_foldername="node-v$nodejs_version-$nodejs_platform-$nodejs_arch-musl" + ;; + *) + nodejs_mirror="https://nodejs.org/dist" + nodejs_foldername="node-v$nodejs_version-$nodejs_platform-$nodejs_arch" + ;; + esac + + # Download Node.js binary archive + nodejs_url="$nodejs_mirror/v$nodejs_version/$nodejs_foldername.tar.gz" + nodejs_tar="$(download_file "$nodejs_url")" + nodejs_extract_dir="$(dirname "$nodejs_tar")" + + # Extract Node.js + execute tar -xzf "$nodejs_tar" -C "$nodejs_extract_dir" + + # Install Node.js binaries to system + nodejs_dir="$nodejs_extract_dir/$nodejs_foldername" + + # Copy bin files preserving symlinks + for file in "$nodejs_dir/bin/"*; do + filename="$(basename "$file")" + if [ -L "$file" ]; then + # Get the symlink target + target="$(readlink "$file")" + # The symlinks are relative (like ../lib/node_modules/npm/bin/npm-cli.js) + # and will work correctly from /usr/local/bin since we're copying + # node_modules to /usr/local/lib/node_modules + execute_sudo ln -sf "$target" "/usr/local/bin/$filename" + elif [ -f "$file" ]; then + # Copy regular files + execute_sudo cp -f "$file" "/usr/local/bin/$filename" + execute_sudo chmod +x "/usr/local/bin/$filename" + fi + done + + # Copy node_modules directory to lib + if [ -d "$nodejs_dir/lib/node_modules" ]; then + execute_sudo mkdir -p "/usr/local/lib" + execute_sudo cp -Rf "$nodejs_dir/lib/node_modules" "/usr/local/lib/" + fi + + # Copy include files if they exist + if [ -d "$nodejs_dir/include" ]; then + execute_sudo mkdir -p "/usr/local/include" + execute_sudo cp -Rf "$nodejs_dir/include/node" "/usr/local/include/" + fi + + # Copy share files if they exist (man pages, etc.) + if [ -d "$nodejs_dir/share" ]; then + execute_sudo mkdir -p "/usr/local/share" + # Copy only node-specific directories + for sharedir in "$nodejs_dir/share/"*; do + if [ -d "$sharedir" ]; then + dirname="$(basename "$sharedir")" + execute_sudo cp -Rf "$sharedir" "/usr/local/share/" + fi + done + fi + + # Ensure /usr/local/bin is in PATH + if ! echo "$PATH" | grep -q "/usr/local/bin"; then + print "Adding /usr/local/bin to PATH" + append_to_profile 'export PATH="/usr/local/bin:$PATH"' + export PATH="/usr/local/bin:$PATH" + fi + + # Verify Node.js installation + if ! command -v node >/dev/null 2>&1; then + error "Node.js installation failed: 'node' command not found in PATH" + fi + + installed_version="$(node --version 2>/dev/null || echo "unknown")" + expected_version="v$nodejs_version" + + if [ "$installed_version" != "$expected_version" ]; then + error "Node.js installation failed: expected version $expected_version but got $installed_version. Please check your PATH and try running 'which node' to debug." + fi + + print "Node.js $installed_version installed successfully" + # Ensure that Node.js headers are always pre-downloaded so that we don't rely on node-gyp install_nodejs_headers } @@ -766,7 +857,7 @@ install_nodejs_headers() { execute tar -xzf "$nodejs_headers_tar" -C "$nodejs_headers_dir" nodejs_headers_include="$nodejs_headers_dir/node-v$nodejs_version/include" - execute_sudo cp -R "$nodejs_headers_include/" "/usr" + execute_sudo cp -R "$nodejs_headers_include" "/usr/local/" # Also install to node-gyp cache locations for different node-gyp versions # This ensures node-gyp finds headers without downloading them diff --git a/test/js/node/process/process.test.js b/test/js/node/process/process.test.js index d8ef7c338a..ea2d60ad41 100644 --- a/test/js/node/process/process.test.js +++ b/test/js/node/process/process.test.js @@ -2,7 +2,7 @@ import { spawnSync, which } from "bun"; import { describe, expect, it } from "bun:test"; import { familySync } from "detect-libc"; import { existsSync, readFileSync, writeFileSync } from "fs"; -import { bunEnv, bunExe, isMacOS, isMusl, isWindows, tmpdirSync } from "harness"; +import { bunEnv, bunExe, isMacOS, isWindows, tmpdirSync } from "harness"; import { basename, join, resolve } from "path"; expect.extend({ @@ -1134,7 +1134,7 @@ it("process.versions", () => { expect(process.versions.modules).toEqual("137"); }); -it.todoIf(isMacOS || isMusl)("should be the node version on the host that we expect", async () => { +it.todoIf(isMacOS)("should be the node version on the host that we expect", async () => { const subprocess = Bun.spawn({ cmd: ["node", "--version"], stdout: "pipe", @@ -1144,6 +1144,6 @@ it.todoIf(isMacOS || isMusl)("should be the node version on the host that we exp }); let [out, exited] = await Promise.all([new Response(subprocess.stdout).text(), subprocess.exited]); - expect(out.trim()).toEqual(isWindows ? "v24.3.0" : "v24.4.0"); // TODO: this *should* be v24.3.0 but scripts/bootstrap.sh needs to be enhanced to do so + expect(out.trim()).toEqual("v24.3.0"); expect(exited).toBe(0); });