From 1adf988868cf21523ee064411f9605b33d8f4ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Tue, 28 Oct 2025 14:19:04 +0100 Subject: [PATCH 1/8] Remove platform restriction from host package's podspec --- packages/host/react-native-node-api.podspec | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/host/react-native-node-api.podspec b/packages/host/react-native-node-api.podspec index 13e941b7..5ed4072a 100644 --- a/packages/host/react-native-node-api.podspec +++ b/packages/host/react-native-node-api.podspec @@ -29,7 +29,6 @@ Pod::Spec.new do |s| s.license = package["license"] s.authors = package["author"] - s.platforms = { :ios => min_ios_version_supported } s.source = { :git => "https://github.com/callstackincubator/react-native-node-api.git", :tag => "#{s.version}" } s.source_files = "apple/**/*.{h,m,mm}", "cpp/**/*.{hpp,cpp,c,h}", "weak-node-api/include/*.h", "weak-node-api/*.hpp" From 97c5c36d366f01fb6002a5ab9250c47134e8ea1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 29 Oct 2025 21:34:25 +0100 Subject: [PATCH 2/8] Add fallback for watchFolders in the metro config --- apps/test-app/metro.config.js | 13 ++++++++++++- eslint.config.js | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/test-app/metro.config.js b/apps/test-app/metro.config.js index 2c321b49..95e22157 100644 --- a/apps/test-app/metro.config.js +++ b/apps/test-app/metro.config.js @@ -1,5 +1,6 @@ const { makeMetroConfig } = require("@rnx-kit/metro-config"); -module.exports = makeMetroConfig({ + +const config = makeMetroConfig({ transformer: { getTransformOptions: async () => ({ transform: { @@ -9,3 +10,13 @@ module.exports = makeMetroConfig({ }), }, }); + +if (config.watchFolders.length === 0) { + // This patch is needed to locate packages in the monorepo from the MacOS app + // which is intentionally kept outside of the workspaces configuration to prevent + // duplicate react-native version and pollution of the package lock. + const path = require("node:path"); + config.watchFolders.push(path.resolve(__dirname, "../..")); +} + +module.exports = config; diff --git a/eslint.config.js b/eslint.config.js index c0af837e..e1bacb32 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -47,6 +47,7 @@ export default tseslint.config( { files: [ "apps/test-app/*.js", + "apps/macos-test-app/*.js", "packages/node-addon-examples/**/*.js", "packages/host/babel-plugin.js", "packages/host/react-native.config.js", @@ -68,6 +69,7 @@ export default tseslint.config( }, { files: [ + "**/metro.config.js", "packages/gyp-to-cmake/bin/*.js", "packages/host/bin/*.mjs", "packages/host/scripts/*.mjs", From f83c5c518d88d1ca09f13116168ce65b964a053a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 27 Oct 2025 22:57:39 +0100 Subject: [PATCH 3/8] Update Podspec to detect React Native package name --- .changeset/silly-mice-warn.md | 5 +++++ packages/host/scripts/patch-hermes.rb | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .changeset/silly-mice-warn.md diff --git a/.changeset/silly-mice-warn.md b/.changeset/silly-mice-warn.md new file mode 100644 index 00000000..7ebdc578 --- /dev/null +++ b/.changeset/silly-mice-warn.md @@ -0,0 +1,5 @@ +--- +"react-native-node-api": patch +--- + +Detects "pod install" from React Native MacOS apps and vendors Hermes accordingly diff --git a/packages/host/scripts/patch-hermes.rb b/packages/host/scripts/patch-hermes.rb index a6cb11f7..76252154 100644 --- a/packages/host/scripts/patch-hermes.rb +++ b/packages/host/scripts/patch-hermes.rb @@ -4,8 +4,18 @@ raise "React Native Node-API cannot reliably patch JSI when React Native Core is prebuilt." end +def get_react_native_package + if caller.any? { |frame| frame.include?("node_modules/react-native-macos/") } + return "react-native-macos" + elsif caller.any? { |frame| frame.include?("node_modules/react-native/") } + return "react-native" + else + raise "Unable to determine React Native package from call stack." + end +end + if ENV['REACT_NATIVE_OVERRIDE_HERMES_DIR'].nil? - VENDORED_HERMES_DIR ||= `npx react-native-node-api vendor-hermes --silent '#{Pod::Config.instance.installation_root}'`.strip + VENDORED_HERMES_DIR ||= `npx react-native-node-api vendor-hermes --react-native-package '#{get_react_native_package()}' --silent '#{Pod::Config.instance.installation_root}'`.strip # Signal the patched Hermes to React Native ENV['BUILD_FROM_SOURCE'] = 'true' ENV['REACT_NATIVE_OVERRIDE_HERMES_DIR'] = VENDORED_HERMES_DIR From f509d4ac5edf51100fb596815acd564e22f1f67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 27 Oct 2025 22:33:14 +0100 Subject: [PATCH 4/8] Add script to init a MacOS test app Enable Hermes and Fabric Patch react_native_post_install to pass react native path Don't pod install when initializing Patch macos app with scripts and source files Re-arm the init script Move linked deps into install command to make --install-links effective Using regular linking for monorepo deps Include original dependencies Enable new arch in Podfile Fix comment from review --- .gitignore | 3 + package-lock.json | 27 ++--- package.json | 4 +- scripts/init-macos-test-app.ts | 190 +++++++++++++++++++++++++++++++++ tsconfig.json | 1 + tsconfig.scripts.json | 10 ++ 6 files changed, 221 insertions(+), 14 deletions(-) create mode 100644 scripts/init-macos-test-app.ts create mode 100644 tsconfig.scripts.json diff --git a/.gitignore b/.gitignore index 42f6c1a8..6c7c7bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ node_modules/ dist/ *.tsbuildinfo + +# Treading the MacOS app as ephemeral +apps/macos-test-app diff --git a/package-lock.json b/package-lock.json index 76bde18c..9604cb48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "globals": "^16.0.0", "prettier": "^3.6.2", "react-native": "0.81.4", + "read-pkg": "^9.0.1", "tsx": "^4.20.5", "typescript": "^5.8.0", "typescript-eslint": "^8.38.0" @@ -14607,7 +14608,7 @@ }, "packages/cli-utils": { "name": "@react-native-node-api/cli-utils", - "version": "0.1.0", + "version": "0.1.1", "dependencies": { "@commander-js/extra-typings": "^14.0.0", "bufout": "^0.3.2", @@ -14824,11 +14825,11 @@ } }, "packages/cmake-rn": { - "version": "0.4.1", + "version": "0.5.1", "dependencies": { - "@react-native-node-api/cli-utils": "0.1.0", + "@react-native-node-api/cli-utils": "0.1.1", "cmake-file-api": "0.1.0", - "react-native-node-api": "0.5.2", + "react-native-node-api": "0.6.1", "zod": "^4.1.11" }, "bin": { @@ -14841,11 +14842,11 @@ }, "packages/ferric": { "name": "ferric-cli", - "version": "0.3.4", + "version": "0.3.6", "dependencies": { "@napi-rs/cli": "~3.0.3", - "@react-native-node-api/cli-utils": "0.1.0", - "react-native-node-api": "0.5.2" + "@react-native-node-api/cli-utils": "0.1.1", + "react-native-node-api": "0.6.1" }, "bin": { "ferric": "bin/ferric.js" @@ -14859,9 +14860,9 @@ } }, "packages/gyp-to-cmake": { - "version": "0.3.0", + "version": "0.4.0", "dependencies": { - "@react-native-node-api/cli-utils": "0.1.0", + "@react-native-node-api/cli-utils": "0.1.1", "gyp-parser": "^1.0.4", "pkg-dir": "^8.0.0", "read-pkg": "^9.0.1" @@ -14872,11 +14873,11 @@ }, "packages/host": { "name": "react-native-node-api", - "version": "0.5.2", + "version": "0.6.1", "license": "MIT", "dependencies": { "@expo/plist": "^0.4.7", - "@react-native-node-api/cli-utils": "0.1.0", + "@react-native-node-api/cli-utils": "0.1.1", "pkg-dir": "^8.0.0", "read-pkg": "^9.0.1", "zod": "^4.1.11" @@ -14892,7 +14893,7 @@ }, "peerDependencies": { "@babel/core": "^7.26.10", - "react-native": "0.79.1 || 0.79.2 || 0.79.3 || 0.79.4 || 0.79.5 || 0.79.6 || 0.80.0 || 0.80.1 || 0.80.2 || 0.81.0 || 0.81.1 || 0.81.2 || 0.81.3 || 0.81.4" + "react-native": "0.79.1 || 0.79.2 || 0.79.3 || 0.79.4 || 0.79.5 || 0.79.6 || 0.79.7 || 0.80.0 || 0.80.1 || 0.80.2 || 0.81.0 || 0.81.1 || 0.81.2 || 0.81.3 || 0.81.4" } }, "packages/node-addon-examples": { @@ -14915,7 +14916,7 @@ "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", - "react-native-node-api": "^0.5.2", + "react-native-node-api": "^0.6.1", "read-pkg": "^9.0.1", "rolldown": "1.0.0-beta.29" } diff --git a/package.json b/package.json index eb2f9dff..be2dbf31 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "test": "npm test --workspace react-native-node-api --workspace cmake-rn --workspace gyp-to-cmake --workspace node-addon-examples", "bootstrap": "node --run build && npm run bootstrap --workspaces --if-present", "prerelease": "node --run build && npm run prerelease --workspaces --if-present", - "release": "changeset publish" + "release": "changeset publish", + "init-macos-test-app": "node scripts/init-macos-test-app.ts" }, "author": { "name": "Callstack", @@ -64,6 +65,7 @@ "globals": "^16.0.0", "prettier": "^3.6.2", "react-native": "0.81.4", + "read-pkg": "^9.0.1", "tsx": "^4.20.5", "typescript": "^5.8.0", "typescript-eslint": "^8.38.0" diff --git a/scripts/init-macos-test-app.ts b/scripts/init-macos-test-app.ts new file mode 100644 index 00000000..7d3abd1e --- /dev/null +++ b/scripts/init-macos-test-app.ts @@ -0,0 +1,190 @@ +import assert from "node:assert/strict"; +import cp from "node:child_process"; +import fs from "node:fs"; +import path from "node:path"; +import { readPackage } from "read-pkg"; + +const REACT_NATIVE_VERSION = "0.79.6"; +const ROOT_PATH = path.join(import.meta.dirname, ".."); +const APP_PATH = path.join(ROOT_PATH, "apps", "macos-test-app"); +const OTHER_APP_PATH = path.join(ROOT_PATH, "apps", "test-app"); + +function exec(command: string, args: string[], options: cp.SpawnOptions = {}) { + const { status } = cp.spawnSync(command, args, { + stdio: "inherit", + ...options, + }); + assert.equal(status, 0, `Failed to execute '${command}'`); +} + +async function deletePreviousApp() { + if (fs.existsSync(APP_PATH)) { + console.log("Deleting existing app directory"); + await fs.promises.rm(APP_PATH, { recursive: true, force: true }); + } +} + +async function initializeReactNativeTemplate() { + console.log("Initializing community template"); + exec("npx", [ + "@react-native-community/cli", + "init", + "MacOSTestApp", + "--skip-install", + "--skip-git-init", + // "--platform-name", + // "react-native-macos", + "--version", + REACT_NATIVE_VERSION, + "--directory", + APP_PATH, + ]); + + // Clean up + const CLEANUP_PATHS = [ + "ios", + "android", + "__tests__", + ".prettierrc.js", + ".gitignore", + ]; + + for (const cleanupPath of CLEANUP_PATHS) { + await fs.promises.rm(path.join(APP_PATH, cleanupPath), { + recursive: true, + force: true, + }); + } +} + +async function patchPackageJson() { + console.log("Patching package.json scripts"); + const packageJson = await readPackage({ cwd: APP_PATH }); + const otherPackageJson = await readPackage({ cwd: OTHER_APP_PATH }); + + packageJson.scripts = { + ...packageJson.scripts, + metro: "react-native start --reset-cache --no-interactive", + "mocha-and-metro": "mocha-remote --exit-on-error -- node --run metro", + premacos: "killall 'MacOSTestApp' || true", + macos: "react-native run-macos --no-packager", + test: "mocha-remote --exit-on-error -- concurrently --passthrough-arguments --kill-others-on-fail npm:metro 'npm:macos -- {@}' --", + "test:allTests": "MOCHA_REMOTE_CONTEXT=allTests node --run test -- ", + "test:nodeAddonExamples": + "MOCHA_REMOTE_CONTEXT=nodeAddonExamples node --run test -- ", + "test:nodeTests": "MOCHA_REMOTE_CONTEXT=nodeTests node --run test -- ", + "test:ferricExample": + "MOCHA_REMOTE_CONTEXT=ferricExample node --run test -- ", + }; + + const transferredDependencies = new Set([ + "@rnx-kit/metro-config", + "mocha-remote-cli", + "mocha-remote-react-native", + ]); + + const { dependencies: otherDependencies = {} } = otherPackageJson; + + packageJson.dependencies = { + ...packageJson.dependencies, + "react-native-macos-init": "^2.1.3", + "@react-native-node-api/node-addon-examples": path.relative( + APP_PATH, + path.join(ROOT_PATH, "packages", "node-addon-examples"), + ), + "@react-native-node-api/node-tests": path.relative( + APP_PATH, + path.join(ROOT_PATH, "packages", "node-tests"), + ), + "@react-native-node-api/ferric-example": path.relative( + APP_PATH, + path.join(ROOT_PATH, "packages", "ferric-example"), + ), + "react-native-node-api": path.relative( + APP_PATH, + path.join(ROOT_PATH, "packages", "host"), + ), + ...Object.fromEntries( + Object.entries(otherDependencies).filter(([name]) => + transferredDependencies.has(name), + ), + ), + }; + + await fs.promises.writeFile( + path.join(APP_PATH, "package.json"), + JSON.stringify(packageJson, null, 2), + "utf8", + ); +} + +function installDependencies() { + console.log("Installing dependencies"); + exec("npm", ["install", "--prefer-offline"], { + cwd: APP_PATH, + }); +} + +function initializeReactNativeMacOSTemplate() { + console.log("Initializing react-native-macos template"); + exec("npx", ["react-native-macos-init"], { + cwd: APP_PATH, + }); +} + +async function patchPodfile() { + console.log("Patching Podfile"); + const replacements = [ + [ + // As per https://github.com/microsoft/react-native-macos/issues/2723#issuecomment-3392930688 + "require_relative '../node_modules/react-native-macos/scripts/react_native_pods'\nrequire_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'", + "require_relative '../node_modules/react-native-macos/scripts/cocoapods/autolinking'", + ], + [ + ":hermes_enabled => false,", + // Adding the new_arch_enabled here as it's not a part of the template + ":hermes_enabled => true,\n :new_arch_enabled => true,", + ], + [ + ":fabric_enabled => ENV['RCT_NEW_ARCH_ENABLED'] == '1',", + ":fabric_enabled => true,", + ], + [ + "react_native_post_install(installer)", + "react_native_post_install(installer, '../node_modules/react-native-macos')", + ], + ]; + + const podfilePath = path.join(APP_PATH, "macos", "Podfile"); + let podfileContents = await fs.promises.readFile(podfilePath, "utf8"); + for (const [searchValue, replaceValue] of replacements) { + podfileContents = podfileContents.replace(searchValue, replaceValue); + } + await fs.promises.writeFile(podfilePath, podfileContents, "utf8"); +} + +async function copySourceFiles() { + console.log("Copying source files from test-app into macos-test-app:"); + const FILE_NAMES = [ + "App.tsx", + // Adds the babel plugin needed to transform require calls + "babel.config.js", + // Adds the ability to reference symlinked packages + "metro.config.js", + ]; + for (const fileName of FILE_NAMES) { + console.log(`↳ ${fileName}`); + await fs.promises.copyFile( + path.join(OTHER_APP_PATH, fileName), + path.join(APP_PATH, fileName), + ); + } +} + +await deletePreviousApp(); +await initializeReactNativeTemplate(); +await patchPackageJson(); +installDependencies(); +initializeReactNativeMacOSTemplate(); +await patchPodfile(); +await copySourceFiles(); diff --git a/tsconfig.json b/tsconfig.json index a733c3ff..4ca25b74 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ }, "files": ["prettier.config.js", "eslint.config.js"], "references": [ + { "path": "./tsconfig.scripts.json" }, { "path": "./packages/cli-utils/tsconfig.json" }, { "path": "./packages/cmake-file-api/tsconfig.json" }, { "path": "./packages/cmake-file-api/tsconfig.tests.json" }, diff --git a/tsconfig.scripts.json b/tsconfig.scripts.json new file mode 100644 index 00000000..88041106 --- /dev/null +++ b/tsconfig.scripts.json @@ -0,0 +1,10 @@ +{ + "extends": "./configs/tsconfig.node.json", + "compilerOptions": { + "composite": true, + "emitDeclarationOnly": true, + "declarationMap": false, + "rootDir": "scripts" + }, + "include": ["scripts"] +} From 02ae255dd89c96cd3bfa572d5e19c89bc33637d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 27 Oct 2025 23:18:46 +0100 Subject: [PATCH 5/8] Add job in the check workflow to initialize and build the MacOS test app No need to Setup Android SDK Debugging with Copilot Pass --mode when building from CLI Install CMake 3.22 Fix bootstrap issue Trying a higher CMake version Remove debug info from workflow Build universal Darwin libraries Add missing x86_64-apple-darwin Rust target to macOS CI job (#298) * Initial plan * Add missing x86_64-apple-darwin Rust target to macOS job Co-authored-by: kraenhansen <1243959+kraenhansen@users.noreply.github.com> * Add only missing x86_64-apple-darwin target (aarch64 is host) Co-authored-by: kraenhansen <1243959+kraenhansen@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: kraenhansen <1243959+kraenhansen@users.noreply.github.com> Run MacOS test app Use package script to run all tests --- .github/workflows/check.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index ec9c7cee..a221cfc4 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -107,6 +107,39 @@ jobs: # TODO: Enable release mode when it works # run: npm run test:ios -- --mode Release working-directory: apps/test-app + test-macos: + # Disabling this on main for now, as initializing the template takes a long time and + # we don't have macOS-specific code yet + if: contains(github.event.pull_request.labels.*.name, 'MacOS 💻') + name: Test app (macOS) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/jod + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: "17" + distribution: "temurin" + # Install CMake 3 since 4.x may have compatibility issues with Hermes build system + - name: Install compatible CMake version + uses: jwlawson/actions-setup-cmake@v2 + with: + cmake-version: "3.31.2" + - run: rustup target add x86_64-apple-darwin + - run: npm ci + - run: npm run bootstrap + env: + CMAKE_RN_TRIPLETS: arm64;x86_64-apple-darwin + FERRIC_TARGETS: aarch64-apple-darwin,x86_64-apple-darwin + - run: npm run init-macos-test-app + - run: pod install --project-directory=macos + working-directory: apps/macos-test-app + - name: Run MacOS test app + run: npm run test:allTests -- --mode Release + working-directory: apps/macos-test-app test-android: if: github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'Android 🤖') name: Test app (Android) From 6a005db0f666ebcbe5c0dfcca99587934d778502 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 18:50:16 +0000 Subject: [PATCH 6/8] Initial plan From 39ce0b18ce545de7f00a70e35418425f8ad82e05 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 18:56:39 +0000 Subject: [PATCH 7/8] Document Node.js LTS version and centralize configuration Add documentation comment explaining that we're using Node.js v22.x "Jod" LTS (became LTS on October 29, 2024). Centralize the version in an environment variable to make future updates easier and more consistent across all jobs. Co-authored-by: kraenhansen <1243959+kraenhansen@users.noreply.github.com> --- .github/workflows/check.yml | 15 +++++++++------ .github/workflows/release.yml | 5 ++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index a221cfc4..e4c2c8b5 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -5,6 +5,9 @@ env: NDK_VERSION: 27.1.12297006 # Enabling the Gradle test on CI (disabled by default because it downloads a lot) ENABLE_GRADLE_TESTS: true + # Node.js LTS version: Using v22.x "Jod" (became LTS on October 29, 2024) + # Previous LTS was v20.x "Iron". See: https://nodejs.org/en/about/previous-releases + NODE_VERSION: lts/jod on: push: @@ -25,7 +28,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} # Set up JDK and Android SDK only because we need weak-node-api, to build ferric-example and to run the linting # TODO: Remove this once we have a way to run linting without building the native code - name: Set up JDK 17 @@ -62,7 +65,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} - name: Set up JDK 17 uses: actions/setup-java@v4 with: @@ -84,7 +87,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} - name: Set up JDK 17 uses: actions/setup-java@v3 with: @@ -117,7 +120,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} - name: Set up JDK 17 uses: actions/setup-java@v3 with: @@ -148,7 +151,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} - name: Set up JDK 17 uses: actions/setup-java@v4 with: @@ -229,7 +232,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} - name: Set up JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f682950b..1607c5de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,9 @@ name: Release env: # Version here should match the one in React Native template and packages/cmake-rn/src/cli.ts NDK_VERSION: 27.1.12297006 + # Node.js LTS version: Using v22.x "Jod" (became LTS on October 29, 2024) + # Previous LTS was v20.x "Iron". See: https://nodejs.org/en/about/previous-releases + NODE_VERSION: lts/jod on: push: @@ -19,7 +22,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts/jod + node-version: ${{ env.NODE_VERSION }} - name: Set up JDK 17 uses: actions/setup-java@v3 with: From fac4c519f13cb9fda1c2153cbb2c0acb819dc1b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 19:33:19 +0000 Subject: [PATCH 8/8] Update copilot instructions with Node.js LTS information Revert workflow file changes and instead add Node.js LTS documentation to copilot-instructions.md. This reminds future AI agents that the current LTS is v22.x "Jod" (not "Iron") and prevents incorrect suggestions about LTS version naming. Co-authored-by: kraenhansen <1243959+kraenhansen@users.noreply.github.com> --- .github/copilot-instructions.md | 9 +++++++++ .github/workflows/check.yml | 15 ++++++--------- .github/workflows/release.yml | 5 +---- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index bcd409ce..72dfaa92 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -28,6 +28,15 @@ See the [README.md](../README.md#packages) for detailed descriptions of each pac - Android: `*.android.node/` with jniLibs structure + `react-native-node-api-module` marker file - iOS: `*.apple.node` (XCFramework renamed) + marker file +## Node.js Version + +This project uses **Node.js v22.x LTS "Jod"** (became LTS on October 29, 2024). The previous LTS was v20.x "Iron". + +**Important**: When reviewing CI workflows or suggesting Node.js version changes: +- The current active LTS codename is "Jod" (v22.x), not "Iron" (v20.x) +- Use `lts/jod` (lowercase) in GitHub Actions workflow files +- Check https://nodejs.org/en/about/previous-releases for the latest LTS information + ## Essential Workflows ### Development Setup diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e4c2c8b5..a221cfc4 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -5,9 +5,6 @@ env: NDK_VERSION: 27.1.12297006 # Enabling the Gradle test on CI (disabled by default because it downloads a lot) ENABLE_GRADLE_TESTS: true - # Node.js LTS version: Using v22.x "Jod" (became LTS on October 29, 2024) - # Previous LTS was v20.x "Iron". See: https://nodejs.org/en/about/previous-releases - NODE_VERSION: lts/jod on: push: @@ -28,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod # Set up JDK and Android SDK only because we need weak-node-api, to build ferric-example and to run the linting # TODO: Remove this once we have a way to run linting without building the native code - name: Set up JDK 17 @@ -65,7 +62,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod - name: Set up JDK 17 uses: actions/setup-java@v4 with: @@ -87,7 +84,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod - name: Set up JDK 17 uses: actions/setup-java@v3 with: @@ -120,7 +117,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod - name: Set up JDK 17 uses: actions/setup-java@v3 with: @@ -151,7 +148,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod - name: Set up JDK 17 uses: actions/setup-java@v4 with: @@ -232,7 +229,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod - name: Set up JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1607c5de..f682950b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,9 +3,6 @@ name: Release env: # Version here should match the one in React Native template and packages/cmake-rn/src/cli.ts NDK_VERSION: 27.1.12297006 - # Node.js LTS version: Using v22.x "Jod" (became LTS on October 29, 2024) - # Previous LTS was v20.x "Iron". See: https://nodejs.org/en/about/previous-releases - NODE_VERSION: lts/jod on: push: @@ -22,7 +19,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: ${{ env.NODE_VERSION }} + node-version: lts/jod - name: Set up JDK 17 uses: actions/setup-java@v3 with: