Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 49 additions & 39 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
branches:
- main
pull_request:
types: [labeled, opened, synchronize, reopened]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -25,34 +26,38 @@ jobs:
node-version: lts/jod
- run: npm ci
- run: npm run lint
test:
unit-tests:
strategy:
fail-fast: false
matrix:
runner:
- ubuntu-latest
- windows-latest
- macos-latest
variant:
- unit-tests
- android-tests
- ios-tests
exclude:
# iOS tests are only supported on macOS runners
- runner: ubuntu-latest
variant: ios-tests
- runner: windows-latest
variant: ios-tests
# The reactivecircus/android-emulator-runner action does not support Windows runners
# See https://github.com/marketplace/actions/android-emulator-runner#github-action---android-emulator-runner
- runner: windows-latest
variant: android-tests
# MacOS is slow and expensive at running Android emulators
- runner: macos-latest
variant: android-tests

name: Test (${{ matrix.variant }} on ${{ matrix.runner }})
runs-on: ${{ matrix.runner }}
name: Unit tests (${{ matrix.runner }})
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"
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
packages: tools platform-tools ndk;${{ env.NDK_VERSION }}
- run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi i686-linux-android aarch64-apple-ios-sim
- run: npm ci
- run: npm run bootstrap
- run: npm test
test-ios:
if: github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'Apple 🍎')
name: Test app (iOS)
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -70,28 +75,39 @@ jobs:
- run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi i686-linux-android aarch64-apple-ios-sim
- run: npm ci
- run: npm run bootstrap
# Unit tests
- if: matrix.variant == 'unit-tests'
name: Run tests (Unit)
run: npm test
# Integration tests (iOS)
- if: matrix.variant == 'ios-tests'
run: npm run pod-install
- run: npm run pod-install
working-directory: apps/test-app
- if: matrix.variant == 'ios-tests'
name: Run tests (iOS)
- name: Run tests (iOS)
run: npm run test:ios
working-directory: apps/test-app
# Integration tests (Android)
test-android:
if: github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'Android 🤖')
name: Test app (Android)
runs-on: ubuntu-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"
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
packages: tools platform-tools ndk;${{ env.NDK_VERSION }}
- run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi i686-linux-android aarch64-apple-ios-sim
- run: npm ci
- run: npm run bootstrap
- name: Clone patched Hermes version
if: matrix.variant == 'android-tests'
shell: bash
run: |
REACT_NATIVE_OVERRIDE_HERMES_DIR=$(npx react-native-node-api vendor-hermes --silent)
echo "REACT_NATIVE_OVERRIDE_HERMES_DIR=$REACT_NATIVE_OVERRIDE_HERMES_DIR" >> $GITHUB_ENV
working-directory: apps/test-app
- name: Setup Android Emulator cache
if: matrix.variant == 'android-tests'
uses: actions/cache@v4
id: avd-cache
with:
Expand All @@ -101,29 +117,25 @@ jobs:
key: ${{ runner.os }}-avd-29
# See https://github.com/marketplace/actions/android-emulator-runner#running-hardware-accelerated-emulators-on-linux-runners
- name: Enable KVM group perms
if: matrix.runner == 'ubuntu-latest' && matrix.variant == 'android-tests'
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Build weak-node-api for all architectures
if: matrix.variant == 'android-tests'
run: npm run build-weak-node-api -- --android
working-directory: packages/host
- name: Build ferric-example for all architectures
if: matrix.variant == 'android-tests'
run: npm run build -- --android
working-directory: packages/ferric-example
- name: Run tests (Android)
if: matrix.variant == 'android-tests'
timeout-minutes: 75
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
force-avd-creation: false
emulator-options: -no-snapshot-save -no-metrics -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
arch: ${{ runner.os == 'macOS' && 'arm64-v8a' || 'x86' }}
arch: x86
ndk: ${{ env.NDK_VERSION }}
cmake: 3.22.1
working-directory: apps/test-app
Expand All @@ -134,5 +146,3 @@ jobs:
adb uninstall com.microsoft.reacttestapp || true
# Build, install and run the app
npm run test:android
# Wait a bit for the sub-process to terminate, before terminating the emulator
sleep 5
11 changes: 6 additions & 5 deletions apps/test-app/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "react-native-node-api-test-app",
"type": "commonjs",
"private": true,
"version": "0.1.0",
"scripts": {
Expand All @@ -8,8 +9,8 @@
"build:android": "react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res",
"ios": "react-native run-ios --no-packager",
"pod-install": "cd ios && pod install",
"test:android": "mocha-remote --exit-on-error -- concurrently --kill-timeout 1000 npm:start npm:android",
"test:ios": "mocha-remote --exit-on-error -- concurrently --kill-timeout 1000 npm:start npm:ios"
"test:android": "mocha-remote --exit-on-error -- tsx ./scripts/run-tests.ts android",
"test:ios": "mocha-remote --exit-on-error -- tsx ./scripts/run-tests.ts ios"
},
"dependencies": {
"@babel/core": "^7.26.10",
Expand All @@ -23,11 +24,11 @@
"@react-native/typescript-config": "0.79.0",
"@rnx-kit/metro-config": "^2.0.1",
"@types/react": "^19.0.0",
"concurrently": "^9.1.2",
"bufout": "^0.3.4",
"ferric-example": "^0.1.0",
"mocha": "^11.6.0",
"mocha-remote-cli": "^1.13.1",
"mocha-remote-react-native": "^1.13.1",
"mocha-remote-cli": "^1.13.2",
"mocha-remote-react-native": "^1.13.2",
"react": "19.0.0",
"react-native": "0.79.1",
"react-native-node-addon-examples": "*",
Expand Down
48 changes: 48 additions & 0 deletions apps/test-app/scripts/run-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import assert from "node:assert/strict";
import path from "node:path";

import { spawn, SpawnFailure } from "bufout";

// Ideally, we would just use "concurrently" or "npm-run-all" to run these in parallel but:
// - "concurrently" hangs the emulator action on Ubuntu
// - "npm-run-all" shows symptoms of not closing metro when Mocha Remote sends a SIGTERM

const platform = process.argv[2];
assert(
platform === "android" || platform === "ios",
"Platform must be 'android' or 'ios'"
);

const cwd = path.resolve(__dirname, "..");
const env = {
...process.env,
FORCE_COLOR: "1",
};

const metro = spawn("react-native", ["start", "--no-interactive"], {
cwd,
stdio: "inherit",
outputPrefix: "[metro] ",
env,
});

const build = spawn(
"react-native",
[
`run-${platform}`,
"--no-packager",
...(platform === "android" ? ["--active-arch-only"] : []),
],
{
cwd,
stdio: "inherit",
outputPrefix: `[${platform}] `,
env,
}
);

Promise.all([metro, build]).catch((err) => {
if (!(err instanceof SpawnFailure)) {
throw err;
}
});
7 changes: 6 additions & 1 deletion apps/test-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"extends": "@react-native/typescript-config/tsconfig.json"
"extends": "@react-native/typescript-config/tsconfig.json",
"compilerOptions": {
"types": ["react-native"]
},
"files": ["App.tsx", "index.ts"],
"references": [{ "path": "./tsconfig.node-scripts.json" }]
}
12 changes: 12 additions & 0 deletions apps/test-app/tsconfig.node-scripts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "@tsconfig/node22/tsconfig.json",
"compilerOptions": {
"composite": true,
"emitDeclarationOnly": true,
"outDir": "dist",
"rootDir": "scripts",
"types": ["node", "bufout"]
},
"include": ["scripts/**/*.ts"],
"exclude": []
}
Loading
Loading