Skip to content

Throwing RealmInExpoGoError only when native module fails to load #5083

Throwing RealmInExpoGoError only when native module fails to load

Throwing RealmInExpoGoError only when native module fails to load #5083

Workflow file for this run

name: Pull request build and test
on:
push:
# The workflow will run only when both `branches` and `paths-ignore` are satisfied.
branches:
- main
paths-ignore:
- "**.md"
- "**.png"
- "packages/realm-web/**"
- "packages/realm-web-integration-tests/**"
- "packages/realm-react/**"
- "packages/realm-tools/**"
pull_request:
# Note that the workflow will still run if paths outside of `paths-ignore` have
# been modified in the PR, irrespective of an individual commit only modifying
# ignored paths. (See: https://github.com/actions/runner/issues/2324)
paths-ignore:
- "**.md"
- "**.png"
- "packages/realm-web/**"
- "packages/realm-web-integration-tests/**"
- "packages/realm-react/**"
- "packages/realm-tools/**"
workflow_dispatch:
env:
REALM_DISABLE_ANALYTICS: 1
CMAKE_VERSION: 3.29.2
NDK_VERSION: 25.1.8937393
JAVA_VERSION: 17
WIREIT_LOGGER: simple
# Globally Mocha remote settings
MOCHA_REMOTE_TIMEOUT: 60000
LONG_TIMEOUT: 300000 # 5 minutes
MOCHA_REMOTE_REPORTER: mocha-github-actions-reporter
MOCHA_REMOTE_EXIT_ON_ERROR: true
# Git branch of the BaaS repo to use when testing
BAAS_BRANCH: master
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
generate-jsi:
name: Generate JSI binding source-code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
# Ignoring scripts to prevent a prebuild from getting fetched / built
run: npm ci --ignore-scripts
- name: Generate JSI
run: |
npm run bindgen:jsi --workspace realm
- name: Upload dist artifacts
uses: actions/upload-artifact@v4
with:
name: jsi-binding-source
# Including README.md to pin paths to the root of the repository
path: |
README.md
packages/realm/binding/jsi/jsi_init.cpp
build-ts:
name: Build TypeScript files
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
# Ignoring scripts to prevent a prebuilt from getting fetched / built
run: npm ci --ignore-scripts
- name: Build / bundle all packages
run: npm run build
- name: Upload dist artifacts
uses: actions/upload-artifact@v4
with:
name: ts-build
# Including README.md to pin paths to the root of the repository
path: |
README.md
packages/*/dist
packages/realm/binding/dist
packages/realm/binding/generated
prebuild-node:
name: Prebuild ${{ matrix.os }} ${{ matrix.arch }} (Node.js)
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- os: linux
runner: ubuntu-latest
arch: x64
- os: linux
runner: ubuntu-latest
arch: arm
- os: linux
runner: ubuntu-latest
arch: arm64
- os: windows
runner: windows-latest
arch: x64
- os: windows
runner: windows-2019
arch: ia32
- os: darwin
runner: macos-latest
arch: x64
- os: darwin
runner: macos-latest
arch: arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup Wireit cache
uses: google/wireit@setup-github-actions-caching/v1
- name: MSVC Setup
if: ${{ runner.os == 'Windows' }}
uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: ${{ env.CMAKE_VERSION }}
# ninja-build is used by default if available and results in faster build times
# On linux, electron requires a connected display. We fake this by giving it a headless environment using xvfb
# Relevant issue: https://github.com/juliangruber/browser-run/issues/147
- name: Linux Environment setup
if: ${{ matrix.runner == 'ubuntu-latest' }}
run: sudo apt-get install ccache ninja-build
# The ccache installed by github doesn't want to be moved around. Let the ccache action download a new one.
- name: Remove pre-installed ccache
if: ${{ runner.os == 'Windows' }}
shell: bash
# There are two; remove both
run: |
rm -fv $(which ccache)
rm -fv $(which ccache)
- name: ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.arch }}
max-size: '2.0G'
create-symlink: ${{ runner.os != 'Windows' }}
- name: Install dependencies
# Ignoring scripts to prevent a prebuilt from getting fetched / built
run: npm ci --ignore-scripts
- name: Insert ccache executables
if: ${{ runner.os == 'Windows' }}
shell: bash
run: |
cl_exe=$(which cl.exe)
cl_dir=$(dirname "$cl_exe")
# For 32-bit it uses a different compiler than the one in the path
if [ ${{ matrix.arch }} = ia32 ]; then
cl_dir=$(dirname "$cl_dir")/x86
cl_exe="$cl_dir/cl.exe"
fi
cl_dir_windows="C:${cl_dir#/c}"
mv -v "$cl_exe" "$cl_dir"/cl-real.exe
cp -v "$cl_dir"/cl.exe.config "$cl_dir"/cl-real.exe.config
ccache_exe=$(which ccache.exe)
cp -v "$ccache_exe" "$cl_dir"/cl.exe
ls -l "$cl_dir"
echo "CCACHE_COMPILER=$cl_dir_windows/cl-real.exe" >> $GITHUB_ENV
echo 'CCACHE_COMPILERTYPE=msvc' >> $GITHUB_ENV
echo 'CCACHE_STATSLOG=C:\Users\runneradmin\ccache\statslog.txt' >> $GITHUB_ENV
#echo 'CCACHE_LOGFILE=C:\Users\runneradmin\ccache\logfile.txt' >> $GITHUB_ENV
# This tells msbuild to compile only one file at a time; ccache needs that.
echo 'UseMultiToolTask=true' >> $GITHUB_ENV
echo 'VCPKG_KEEP_ENV_VARS=CCACHE_COMPILER;CCACHE_STATSLOG;CCACHE_LOGFILE;CCACHE_COMPILERTYPE;UseMultiToolTask' >> $GITHUB_ENV
- name: Build native module
run: npm run prebuild-node --workspace realm
env:
PREBUILD_ARCH: ${{ matrix.arch }}
- name: Upload prebuild artifact
uses: actions/upload-artifact@v4
with:
name: node-${{ matrix.os }}-${{ matrix.arch }}-prebuild
# Including README.md to pin paths to the root of the repository
path: |
README.md
packages/realm/prebuilds/realm-*-napi-*.tar.gz
prebuild-apple-archives:
name: Prebuild ${{ matrix.platform }} (Apple React Native)
runs-on: macos-latest-large
strategy:
fail-fast: false
matrix:
platform:
- iphonesimulator
- iphoneos
- macosx
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup CMake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: ${{ env.CMAKE_VERSION }}
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ github.job }}-${{ matrix.platform }}
max-size: '2.0G'
create-symlink: true
- name: Install dependencies
# Ignoring scripts to prevent a prebuild from getting fetched / built
run: npm ci --ignore-scripts
- name: Build archive
run: npm run prebuild-apple --workspace realm -- --platform ${{ matrix.platform }} --skip-creating-xcframework
- name: Upload archive
uses: actions/upload-artifact@v4
with:
name: apple-${{ matrix.platform }}-archive
# Including README.md to pin paths to the root of the repository
path: |
README.md
packages/realm/bindgen/vendor/realm-core/build-xcode/include/
packages/realm/bindgen/vendor/realm-core/build-xcode/${{ matrix.platform }}.xcarchive/Products/usr/local/lib/librealm-combined.a
if-no-files-found: error
prebuild-apple:
name: Combine Xcframework (Apple React Native)
runs-on: macos-latest-large
needs: prebuild-apple-archives
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
# Ignoring scripts to prevent a prebuild from getting fetched / built
run: npm ci --ignore-scripts
- name: Download archives
uses: actions/download-artifact@v4
with:
pattern: apple-*-archive
merge-multiple: true
- name: Create Xcframework
run: npm run prebuild-apple --workspace realm -- --platform none --skip-collecting-headers
- uses: actions/upload-artifact@v4
with:
name: apple-prebuild
# Including README.md to pin paths to the root of the repository
path: |
README.md
packages/realm/prebuilds/apple/realm-core.xcframework/
if-no-files-found: error
prebuild-android:
name: Prebuild ${{ matrix.architecture }} (Android React Native)
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
architecture:
- arm64-v8a
- armeabi-v7a
- x86
- x86_64
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup CMake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: ${{ env.CMAKE_VERSION }}
- name: Install ninja
run: sudo apt-get install ninja-build
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ github.job }}-${{ matrix.architecture }}
max-size: '2.0G'
create-symlink: true
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '${{ env.JAVA_VERSION }}'
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Install NDK
run: sdkmanager --install "ndk;${{ env.NDK_VERSION }}"
- name: Install dependencies
# Ignoring scripts to prevent a prebuild from getting fetched / built
run: npm ci --ignore-scripts
- name: Build archive
run: npm run prebuild-android --workspace realm -- --architecture ${{ matrix.architecture }} --configuration Release
- name: Upload archive
uses: actions/upload-artifact@v4
with:
name: android-${{ matrix.architecture }}-prebuild
# Including README.md to pin paths to the root of the repository
path: |
README.md
packages/realm/prebuilds/android/${{ matrix.architecture }}/
if-no-files-found: error
merge-prebuilds:
name: Merge prebuild artifacts
runs-on: ubuntu-latest
needs:
- prebuild-node
- prebuild-apple
- prebuild-android
steps:
- uses: actions/upload-artifact/merge@v4
with:
name: prebuilds
pattern: '*-prebuild'
node-electron-tests:
name: Test ${{ matrix.environment }} on ${{ matrix.runner }} (${{matrix.script_name}})
needs:
- build-ts
- prebuild-node
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
# Node on Linux
- runner: ubuntu-latest
script_name: test:ci
environment: node
prebuild: node-linux-x64-prebuild
# Node on macOS
- runner: macos-latest
script_name: test:ci
environment: node
prebuild: node-darwin-arm64-prebuild
# Electron on Linux
- runner: ubuntu-latest
script_name: test:ci:main
environment: electron
prebuild: node-linux-x64-prebuild
- runner: ubuntu-latest
script_name: test:ci:renderer
environment: electron
prebuild: node-linux-x64-prebuild
# Electron on macOS
- runner: macos-latest
script_name: test:ci:main
environment: electron
prebuild: node-darwin-arm64-prebuild
- runner: macos-latest
script_name: test:ci:renderer
environment: electron
prebuild: node-darwin-arm64-prebuild
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: MSVC Setup
if: ${{ runner.os == 'Windows' }}
uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: ${{ env.CMAKE_VERSION }}
- name: Set xvfb wrapper for Linux / electron tests
if: ${{ runner.os == 'Linux' && matrix.environment == 'electron' }}
run: |
sudo apt-get install xvfb
echo "wrapper=xvfb-run" >> $GITHUB_ENV
- name: Download TypeScript build
uses: actions/download-artifact@v4
with:
name: ts-build
- name: Download prebuild native module
uses: actions/download-artifact@v4
with:
name: ${{ matrix.prebuild }}
- name: Install dependencies
run: npm ci
env:
# Ensure we install the prebuild built in the previous job
npm_config_realm_local_prebuilds: ${{github.workspace}}/packages/realm/prebuilds
- name: Start BaaS test server
id: baas
uses: ./.github/actions/baas-test-server
with:
branch: ${{ env.BAAS_BRANCH }}
env:
BAASAAS_KEY: ${{ secrets.BAASAAS_KEY }}
- name: Create Mocha Remote Context
id: mocha-env
run: echo "context=syncLogLevel=warn,longTimeoutMs=${{ env.LONG_TIMEOUT }},baseUrl=${{ steps.baas.outputs.baas-url }}" >> $GITHUB_OUTPUT
- name: Run tests
env:
MOCHA_REMOTE_CONTEXT: ${{ steps.mocha-env.outputs.context }}
# The non react native environments should not take so long
timeout-minutes: 60
run: ${{ env.wrapper }} npm run ${{ matrix.script_name}} --prefix integration-tests/environments/${{ matrix.environment }}
apple-tests:
name: Test iOS (React Native)
needs:
- build-ts
- generate-jsi
- prebuild-apple
env:
DEVELOPER_DIR: /Applications/Xcode_14.3.1.app
IOS_DEVICE_NAME: iPhone 14
# See https://guides.cocoapods.org/using/faq.html#can-i-change-the-default-cocoapods-repositories-folder
CP_HOME_DIR: ${{ github.workspace }}/.cocoapods
runs-on: macos-latest-large
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: CocoaPods cache
uses: actions/cache@v4
with:
path: ${{ env.CP_HOME_DIR }}
key: ${{ github.job }}-cocoapods
- name: Cached React Native Test App CocoaPods
uses: actions/cache@v4
with:
path: integration-tests/environments/react-native-test-app/ios/Pods
key: ${{ github.job }}-pods-${{ hashFiles('integration-tests/environments/react-native-test-app/ios/Podfile.lock') }}
- name: MSVC Setup
if: ${{ runner.os == 'Windows' }}
uses: ilammy/msvc-dev-cmd@v1
# we use a different version for Android, and it is specified below
- name: Setup CMake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: ${{ env.CMAKE_VERSION }}
- name: ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ github.job }}
max-size: '2.0G'
create-symlink: true
- name: Install iOS tools
run: |
npm install -g ios-deploy
- name: Download JSI
uses: actions/download-artifact@v4
with:
name: jsi-binding-source
- name: Download TypeScript build
uses: actions/download-artifact@v4
with:
name: ts-build
- name: Download Apple prebuild
uses: actions/download-artifact@v4
with:
name: apple-prebuild
- name: Install dependencies
# Ignoring scripts to prevent a prebuild from getting fetched / built
run: npm ci --ignore-scripts
# The following makes subsequent "open -a Simulator" calls work
- name: Invoke the simulator
run: open -a ${{ env.DEVELOPER_DIR }}/Contents/Developer/Applications/Simulator.app
- name: Boot the simulator
run: |
xcrun simctl boot '${{ env.IOS_DEVICE_NAME }}'
SIMULATOR_UDID=`xcrun simctl list devices booted --json | jq -r '.devices[][] | select(.name == "${{ env.IOS_DEVICE_NAME }}").udid'`
echo "Simulator booted with UDID = $SIMULATOR_UDID"
echo "SIMULATOR_UDID=$SIMULATOR_UDID" >> $GITHUB_ENV
- name: Start BaaS test server
id: baas
uses: ./.github/actions/baas-test-server
with:
branch: ${{ env.BAAS_BRANCH }}
env:
BAASAAS_KEY: ${{ secrets.BAASAAS_KEY }}
- name: Create Mocha Remote Context
id: mocha-env
run: echo "context=syncLogLevel=warn,longTimeoutMs=${{ env.LONG_TIMEOUT }},baseUrl=${{ steps.baas.outputs.baas-url }}" >> $GITHUB_OUTPUT
# Because the Xcode project injects its own CCACHE_CONFIGPATH,
# the configuration set by the ccache action doesn't propagate.
- name: Expose Ccache config to Xcode
run: |
echo "CCACHE_DIR=`ccache --get-config cache_dir`" >> $GITHUB_ENV
echo "CCACHE_MAXSIZE=`ccache --get-config max_size`" >> $GITHUB_ENV
echo "CCACHE_COMPILERCHECK=`ccache --get-config compiler_check`" >> $GITHUB_ENV
- name: Bundle test app
working-directory: integration-tests/environments/react-native-test-app
run: |
mkdir dist
npx react-native bundle --entry-file index.js --platform ios --dev false --minify false --bundle-output dist/main.ios.jsbundle --assets-dest dist/res
- name: Run 'pod install'
env:
USE_CCACHE: 1
USE_HERMES: 1
USE_BRIDGELESS: 1
RCT_NEW_ARCH_ENABLED: 1
working-directory: integration-tests/environments/react-native-test-app/ios
timeout-minutes: 15
run: pod install --verbose
- name: Build test app
working-directory: integration-tests/environments/react-native-test-app/ios
run: xcodebuild archive -workspace RealmTests.xcworkspace -configuration Release -scheme RealmTests -destination generic/platform="iOS Simulator" -archivePath ./build/realmtests.xcarchive | xcbeautify
- name: Run tests
env:
PLATFORM: ios
MOCHA_REMOTE_CONTEXT: ${{ steps.mocha-env.outputs.context }}
timeout-minutes: 30
working-directory: integration-tests/environments/react-native-test-app/ios
run: |
# Install the app
xcrun simctl install $SIMULATOR_UDID ./build/realmtests.xcarchive/Products/Applications/ReactTestApp.app
# Run Mocha Remote wrapping the launch of the app
npx mocha-remote -- xcrun simctl launch --terminate-running-process --console-pty $SIMULATOR_UDID com.microsoft.ReactTestApp
android-tests:
name: Test Android (React Native)
needs:
- build-ts
- generate-jsi
- prebuild-android
runs-on: macos-latest-large
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup node version
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '${{ env.JAVA_VERSION }}'
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Install NDK
run: sdkmanager --install "ndk;${{ env.NDK_VERSION }}"
- name: ccache
uses: hendrikmuhs/ccache-action@v1
with:
key: ${{ github.job }}
max-size: '2.0G'
create-symlink: true
- name: Download JSI
uses: actions/download-artifact@v4
with:
name: jsi-binding-source
- name: Download TypeScript build
uses: actions/download-artifact@v4
with:
name: ts-build
- name: Download Android prebuild
uses: actions/download-artifact@v4
with:
pattern: android-*-prebuild
merge-multiple: true
- name: Install dependencies
# Ignoring scripts to prevent a prebuild from getting fetched / built
run: npm ci --ignore-scripts
- name: Start BaaS test server
id: baas
uses: ./.github/actions/baas-test-server
with:
branch: ${{ env.BAAS_BRANCH }}
env:
BAASAAS_KEY: ${{ secrets.BAASAAS_KEY }}
- name: Create Mocha Remote Context
id: mocha-env
run: echo "context=syncLogLevel=warn,longTimeoutMs=${{ env.LONG_TIMEOUT }},baseUrl=${{ steps.baas.outputs.baas-url }}" >> $GITHUB_OUTPUT
- name: Setup Java Gradle cache for android test app
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Setup Android Emulator cache
uses: actions/cache@v4
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-29
- name: Bundle test app
working-directory: integration-tests/environments/react-native-test-app
run: |
mkdir dist
npx react-native bundle --entry-file index.js --platform android --dev false --minify false --bundle-output dist/main.android.jsbundle --assets-dest dist/res
- name: Generate a keystore for signing
working-directory: integration-tests/environments/react-native-test-app
env:
STORE_PATH: debug.keystore
STORE_PASS: android
KEY_ALIAS: debug-key
KEY_PASS: android
run: |
keytool -genkey -v -keyalg RSA -keysize 2048 -validity 10000 -dname cn=Realm -keystore ${{ env.STORE_PATH }} -storepass ${{ env.STORE_PASS }} -alias ${{ env.KEY_ALIAS }} -keypass ${{ env.KEY_PASS }}
jq --arg storeFile ${{ env.STORE_PATH }} --arg storePassword ${{ env.STORE_PASS }} --arg keyAlias ${{ env.KEY_ALIAS }} --arg keyPassword ${{ env.KEY_PASS }} '. +{android: {signingConfigs: { release: { $storeFile, $storePassword, $keyAlias, $keyPassword } }}}' app.json > patched-app.json
mv patched-app.json app.json
- name: Run tests
env:
# Limit architecture to speed up the build
ORG_GRADLE_PROJECT_reactNativeArchitectures: x86
# Enabling new architecture and bridgeless
ORG_GRADLE_PROJECT_newArchEnabled: true
ORG_GRADLE_PROJECT_bridgelessEnabled: true
MOCHA_REMOTE_CONTEXT: ${{ steps.mocha-env.outputs.context }}
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: x86
ndk: ${{ env.NDK_VERSION }}
cmake: 3.22.1
working-directory: integration-tests/environments/react-native-test-app/android
script: |
# Setup port forwarding to Mocha Remote
adb reverse tcp:8090 tcp:8090
# Uninstall the app if already in the snapshot (unlikely but could result in a signature mismatch failure)
adb uninstall com.microsoft.reacttestapp || true
# Build and install the app
./gradlew installRelease
# Launch the app
# -W wait for launch to complete, to allow the logcat script to find a pid
# -S force stop the target app before starting the activity
adb shell am start -W -S -n com.microsoft.reacttestapp/.MainActivity
# Start Mocha Remote, wrapping logcat
npx mocha-remote -- npm run logcat