P0: pin project runtime and document FreeCAD parity plan
This commit is contained in:
90
scripts/bootstrap-node.sh
Executable file
90
scripts/bootstrap-node.sh
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_dir="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd -P)"
|
||||
# shellcheck disable=SC1091
|
||||
. "$repo_dir/config/node-runtime.env"
|
||||
|
||||
runtime_root="$repo_dir/.runtime"
|
||||
mkdir -p "$runtime_root/downloads"
|
||||
|
||||
os_name="$(uname -s)"
|
||||
cpu_name="$(uname -m)"
|
||||
case "$os_name:$cpu_name" in
|
||||
Linux:x86_64|Linux:amd64) platform=linux; arch=x64; archive_ext=tar.xz; checksum="$NODE_LINUX_X64_SHA256" ;;
|
||||
Linux:aarch64|Linux:arm64) platform=linux; arch=arm64; archive_ext=tar.xz; checksum="$NODE_LINUX_ARM64_SHA256" ;;
|
||||
Darwin:x86_64|Darwin:amd64) platform=darwin; arch=x64; archive_ext=tar.gz; checksum="$NODE_DARWIN_X64_SHA256" ;;
|
||||
Darwin:arm64|Darwin:aarch64) platform=darwin; arch=arm64; archive_ext=tar.gz; checksum="$NODE_DARWIN_ARM64_SHA256" ;;
|
||||
*)
|
||||
echo "Unsupported project runtime platform: $os_name/$cpu_name (use Node $NODE_VERSION manually on this host)." >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
archive_name="node-v${NODE_VERSION}-${platform}-${arch}.${archive_ext}"
|
||||
archive_path="$runtime_root/downloads/$archive_name"
|
||||
runtime_dir="$runtime_root/node-v${NODE_VERSION}-${platform}-${arch}"
|
||||
|
||||
if [ -x "$runtime_dir/bin/node" ] && [ "$($runtime_dir/bin/node --version)" = "v$NODE_VERSION" ]; then
|
||||
printf '%s\n' "$runtime_dir"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -e "$archive_path" ]; then
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
actual_checksum="$(sha256sum "$archive_path" | awk '{print $1}')"
|
||||
else
|
||||
actual_checksum="$(shasum -a 256 "$archive_path" | awk '{print $1}')"
|
||||
fi
|
||||
if [ "$actual_checksum" != "$checksum" ]; then
|
||||
rm -f "$archive_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -e "$archive_path" ]; then
|
||||
temp_archive="$archive_path.part"
|
||||
rm -f "$temp_archive"
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "curl is required to bootstrap the project-local Node runtime." >&2
|
||||
exit 2
|
||||
fi
|
||||
curl --fail --location --retry 3 --output "$temp_archive" "$NODE_DIST_BASE/$archive_name"
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
actual_checksum="$(sha256sum "$temp_archive" | awk '{print $1}')"
|
||||
else
|
||||
actual_checksum="$(shasum -a 256 "$temp_archive" | awk '{print $1}')"
|
||||
fi
|
||||
if [ "$actual_checksum" != "$checksum" ]; then
|
||||
rm -f "$temp_archive"
|
||||
echo "SHA-256 verification failed for $archive_name." >&2
|
||||
exit 3
|
||||
fi
|
||||
mv "$temp_archive" "$archive_path"
|
||||
fi
|
||||
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
actual_checksum="$(sha256sum "$archive_path" | awk '{print $1}')"
|
||||
else
|
||||
actual_checksum="$(shasum -a 256 "$archive_path" | awk '{print $1}')"
|
||||
fi
|
||||
if [ "$actual_checksum" != "$checksum" ]; then
|
||||
echo "Cached Node archive checksum does not match the pinned value." >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
extract_dir="$(mktemp -d "$runtime_root/extract.XXXXXX")"
|
||||
cleanup() { rm -rf "$extract_dir"; }
|
||||
trap cleanup EXIT
|
||||
tar -xf "$archive_path" -C "$extract_dir"
|
||||
extracted_dir="$extract_dir/node-v${NODE_VERSION}-${platform}-${arch}"
|
||||
if [ ! -x "$extracted_dir/bin/node" ]; then
|
||||
echo "Node archive did not contain the expected executable." >&2
|
||||
exit 4
|
||||
fi
|
||||
rm -rf "$runtime_dir"
|
||||
mv "$extracted_dir" "$runtime_dir"
|
||||
if [ "$($runtime_dir/bin/node --version)" != "v$NODE_VERSION" ]; then
|
||||
echo "Bootstrapped Node version is not v$NODE_VERSION." >&2
|
||||
exit 4
|
||||
fi
|
||||
printf '%s\n' "$runtime_dir"
|
||||
9
scripts/check-runtime.mjs
Normal file
9
scripts/check-runtime.mjs
Normal file
@@ -0,0 +1,9 @@
|
||||
const expected = process.env.BITBYBIT_NODE_VERSION ?? "22.23.2";
|
||||
const actual = process.versions.node;
|
||||
|
||||
if (actual !== expected) {
|
||||
console.error(`Project runtime mismatch: expected Node ${expected}, got ${actual}. Use ./npmw or ./nodew.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Project runtime OK: Node ${actual}`);
|
||||
Reference in New Issue
Block a user