From 12052c180c7e936843a9c85e111c2367dc814578 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 12:14:13 +0000 Subject: [PATCH] fix(repo): declare the Node/pnpm floors the toolchain actually requires MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root `engines` said `node: ">=22"` / `pnpm: ">=9"`, admitting Node 22.0-22.10 and pnpm 9 - versions `@changesets/cli@3` refuses outright. Nothing enforces the declaration (no `engine-strict`, `packageManager` pinned to pnpm@10.31.0, every workflow on `node-version: '22.x'`), so this was a false declaration rather than an outage: a contributor picking a version by reading `engines` got a toolchain combination that does not work, with no guard to say so. Per the maintainer ruling of 2026-08-25, the minimal truthful correction: "engines": { "node": ">=22.11", "pnpm": ">=10" } The segmented range `^22.11 || ^24 || >=26` was considered and rejected as an ongoing maintenance tax; `engine-strict=true` is ruled a separate follow-up card and is deliberately NOT part of this change. Second half - the surfaces that restate those floors: - `QUICK_REFERENCE.md`'s pnpm row is pinned to `engines.pnpm` by `scripts/__tests__/quick-reference-current-release-4143.test.ts`; regenerated with `pnpm quick-reference:sync` (the Node row is derived as the first integer of the range, so `>=22.11` still reads "≥ 22" and does not move). - `CONTRIBUTING.md` claimed "Node.js 18.0 or higher" and a Node 18.x/20.x test matrix; CI has no Node matrix at all - it shards the suite four ways on 22.x. - `scripts/setup.sh`, the automated setup README points contributors at, checked for Node >= 20 and pnpm >= 9. It now READS both floors out of `engines` rather than repeating them, so the script cannot drift from the manifest again, and it compares full versions (`sort -V`) instead of majors, which is what makes a 22.11 floor expressible at all. - `content/docs/guide/deployment.md` built this workspace with `corepack prepare pnpm@9` and Netlify `NODE_VERSION = "20"` / `PNPM_VERSION = "9"`. --- CONTRIBUTING.md | 6 +++--- QUICK_REFERENCE.md | 2 +- content/docs/guide/deployment.md | 6 +++--- package.json | 4 ++-- scripts/setup.sh | 21 +++++++++++++-------- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c03c78e370..81439d8457 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,8 +20,8 @@ Thank you for your interest in contributing to Object UI! This document provides ### Prerequisites -- **Node.js** 18.0 or higher -- **pnpm** (recommended package manager) +- **Node.js** 22.11 or higher (the floor root `package.json` declares in `engines.node`) +- **pnpm** 10 or higher (the required package manager — the workspace pins `pnpm@10.31.0` via `packageManager`) - **Git** for version control - Basic knowledge of React, TypeScript, and Tailwind CSS @@ -375,7 +375,7 @@ Our repository includes several automated GitHub workflows that will run when yo - **Type Checking**: Validates TypeScript types - **Tests**: Runs unit and integration tests - **Build**: Ensures all packages build successfully -- **Matrix Testing**: Tests on Node.js 18.x and 20.x +- **Sharded Testing**: Tests run across 4 shards, all on Node.js 22.x — the only Node version any workflow declares - **Coverage Thresholds**: Enforces minimum test coverage (see below) ##### Test Coverage Requirements diff --git a/QUICK_REFERENCE.md b/QUICK_REFERENCE.md index ef00feb7f4..0708d493d1 100644 --- a/QUICK_REFERENCE.md +++ b/QUICK_REFERENCE.md @@ -128,7 +128,7 @@ behind (objectui#5394 — that had happened once per release, three times). - **Client:** `@objectstack/client` ^17.0.0 (declared by `apps/console/package.json` and `packages/data-objectstack/package.json`) - **Node.js:** ≥ 22 (see root `engines.node`) -- **pnpm:** ≥ 9 (the workspace pins `pnpm@10.31.0` via `packageManager`) +- **pnpm:** ≥ 10 (the workspace pins `pnpm@10.31.0` via `packageManager`) - **React:** 18.x or 19.x (the `peerDependencies.react` range the packages declare) - **TypeScript:** ≥ 5.0 (strict mode) — the stack floor stated in AGENTS.md §2, not a manifest fact: nothing in this tree declares a `typescript` range to check it against, diff --git a/content/docs/guide/deployment.md b/content/docs/guide/deployment.md index 54109fa4d7..a169552382 100644 --- a/content/docs/guide/deployment.md +++ b/content/docs/guide/deployment.md @@ -20,7 +20,7 @@ Create a multi-stage `Dockerfile` at the project root: ```dockerfile # Stage 1: Build FROM node:22-alpine AS builder -RUN corepack enable && corepack prepare pnpm@9 --activate +RUN corepack enable && corepack prepare pnpm@10 --activate WORKDIR /app COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ @@ -131,8 +131,8 @@ Create `netlify.toml` in the project root: publish = "apps/console/dist" [build.environment] - NODE_VERSION = "20" - PNPM_VERSION = "9" + NODE_VERSION = "22" + PNPM_VERSION = "10" # SPA fallback — redirect all routes to index.html [[redirects]] diff --git a/package.json b/package.json index 2d6d4ab1b3..3ba40db411 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "homepage": "https://www.objectui.org", "packageManager": "pnpm@10.31.0", "engines": { - "node": ">=22", - "pnpm": ">=9" + "node": ">=22.11", + "pnpm": ">=10" }, "workspaces": [ "packages/*", diff --git a/scripts/setup.sh b/scripts/setup.sh index 770309775e..4ac2309f4b 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -11,17 +11,22 @@ NC='\033[0m' # No Color echo -e "${BLUE}🚀 ObjectUI Development Environment Setup${NC}" echo -e "${BLUE}==========================================${NC}\n" -# Check Node.js +# Check Node.js — the floor is READ from the root package.json's `engines.node` +# rather than repeated here, so this script and the manifest cannot drift apart +# (objectui#5306: this check demanded Node 20 while the manifest said 22). echo -e "${YELLOW}Checking prerequisites...${NC}" if ! command -v node &> /dev/null; then echo -e "${RED}❌ Node.js is not installed${NC}" - echo -e "${YELLOW}Please install Node.js 20+ from https://nodejs.org/${NC}" + echo -e "${YELLOW}Please install Node.js from https://nodejs.org/ — the required version is the one root package.json declares in engines.node${NC}" exit 1 fi -NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) -if [ "$NODE_VERSION" -lt 20 ]; then - echo -e "${RED}❌ Node.js version must be 20 or higher (current: $(node -v))${NC}" +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +# `>=22.11` -> `22.11`. A failed read exits the script under `set -e`, so an +# unreadable manifest can never be mistaken for a satisfied floor. +NODE_FLOOR=$(node -p "require('$REPO_ROOT/package.json').engines.node.replace(/^[^0-9]*/, '')") +if [ "$(printf '%s\n%s\n' "$NODE_FLOOR" "$(node -v | cut -d'v' -f2)" | sort -V | head -n1)" != "$NODE_FLOOR" ]; then + echo -e "${RED}❌ Node.js $NODE_FLOOR or higher is required (current: $(node -v))${NC}" exit 1 fi echo -e "${GREEN}✓ Node.js $(node -v) detected${NC}" @@ -32,9 +37,9 @@ if ! command -v pnpm &> /dev/null; then npm install -g pnpm fi -PNPM_VERSION=$(pnpm -v | cut -d'.' -f1) -if [ "$PNPM_VERSION" -lt 9 ]; then - echo -e "${YELLOW}📦 Upgrading pnpm to v9+...${NC}" +PNPM_FLOOR=$(node -p "require('$REPO_ROOT/package.json').engines.pnpm.replace(/^[^0-9]*/, '')") +if [ "$(printf '%s\n%s\n' "$PNPM_FLOOR" "$(pnpm -v)" | sort -V | head -n1)" != "$PNPM_FLOOR" ]; then + echo -e "${YELLOW}📦 Upgrading pnpm to v$PNPM_FLOOR+...${NC}" npm install -g pnpm@latest fi echo -e "${GREEN}✓ pnpm $(pnpm -v) detected${NC}"