Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
42713f5
chore: app harness for testing RN/Expo apps with configured dependenc…
russellwheatley Apr 22, 2026
a4dd1be
chore: expo app setup
russellwheatley Apr 22, 2026
d5f14d7
chore: README for build harness
russellwheatley Apr 22, 2026
d03299c
ci: build harness for expo/bare RN for android and iOS
russellwheatley Apr 23, 2026
6894ac8
Merge branch 'main' into rn-and-expo-example
russellwheatley Apr 23, 2026
75dc97e
chore: update READMEs so that there is no duplication and a single RE…
russellwheatley Apr 23, 2026
97b4c52
efactor(pr): address reviewer feedback on harness cleanup and shell p…
russellwheatley Apr 23, 2026
b54408e
fix: yarn app:expo:start
russellwheatley Apr 23, 2026
b36f703
fix: extra args optional
russellwheatley Apr 24, 2026
1579b8d
fix: bare RN script
russellwheatley Apr 24, 2026
01cd00a
fix: force app to use static linking for expo build harness
russellwheatley Apr 24, 2026
0b1b96c
fix: expo build issues
russellwheatley Apr 24, 2026
4728cbe
ci: build harness workflow
russellwheatley Apr 24, 2026
18c9a6e
ci: incorrect name
russellwheatley Apr 24, 2026
cd9a1bf
ci: fix build harness workflow
russellwheatley Apr 24, 2026
c9bb7f9
fix: gem bundler for build harness
russellwheatley Apr 24, 2026
a491b75
fix: build gradle runs in isolation so need to parse package.json ins…
russellwheatley Apr 27, 2026
b394bbc
chore: update script with Ruby/bundler config + documentation
russellwheatley Apr 27, 2026
b696ede
ci: fix ios bare app by pinning ruby
russellwheatley Apr 27, 2026
b4cba8a
fix: iOS expo might need NODE_PATH to build
russellwheatley Apr 27, 2026
97c6d9e
ci: expo android needs node path
russellwheatley Apr 27, 2026
54035dc
podfile.lock
russellwheatley Apr 27, 2026
73344c0
chore: bump cache key to get changes
russellwheatley Apr 27, 2026
16ef7df
chore: setup reproduction environment
russellwheatley Apr 27, 2026
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
207 changes: 207 additions & 0 deletions .github/workflows/build_harnesses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
name: Build Harnesses

on:
workflow_dispatch:
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- 'website/**'
- '.spellcheck.dict.txt'
- '**/*.md'
push:
branches:
- main
- v14-release
paths-ignore:
- 'docs/**'
- 'website/**'
- '.spellcheck.dict.txt'
- '**/*.md'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
ios:
name: iOS (${{ matrix.harness }})
runs-on: macos-15
timeout-minutes: 80
strategy:
fail-fast: false
matrix:
harness:
- bare
- expo
env:
# Keep in sync with the existing iOS E2E workflow, which tracks latest-stable
# because Firebase iOS SDK updates can require newer Xcode versions.
XCODE_VERSION: latest-stable
IOS_GOOGLE_SERVICES_PATH: ${{ runner.temp }}/GoogleService-Info.plist
ANDROID_GOOGLE_SERVICES_PATH: ${{ runner.temp }}/google-services.json
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50

- uses: actions/setup-node@v4
with:
node-version: 22

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.XCODE_VERSION }}

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3

- name: Create CI Firebase config files
run: bash ./scripts/write-ci-firebase-configs.sh "${IOS_GOOGLE_SERVICES_PATH}" "${ANDROID_GOOGLE_SERVICES_PATH}"

- name: Cache CocoaPods and specs
uses: actions/cache@v4
with:
path: |
~/Library/Caches/CocoaPods
~/.cocoapods/repos
apps/build-harness/ios/Pods
key: ${{ runner.os }}-harness-pods-v1-${{ hashFiles('yarn.lock', 'apps/build-harness/ios/Podfile.lock', 'apps/build-harness-expo/package.json', 'apps/build-harness-expo/app.config.js') }}
restore-keys: |
${{ runner.os }}-harness-pods-v1-

- name: Yarn install
run: yarn

- name: Sync bare harness
if: matrix.harness == 'bare'
run: |
bash ./scripts/sync-build-harness.sh sync \
--ios-google-services "${IOS_GOOGLE_SERVICES_PATH}" \
--android-google-services "${ANDROID_GOOGLE_SERVICES_PATH}" \
--no-yarn-install \
--pod-install

- name: Build bare iOS harness
if: matrix.harness == 'bare'
working-directory: apps/build-harness/ios
run: |
xcodebuild \
-workspace BuildHarness.xcworkspace \
-scheme BuildHarness \
-configuration Debug \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO \
build

- name: Sync Expo harness
if: matrix.harness == 'expo'
run: |
bash ./scripts/sync-build-harness-expo.sh sync \
--ios-google-services "${IOS_GOOGLE_SERVICES_PATH}" \
--android-google-services "${ANDROID_GOOGLE_SERVICES_PATH}" \
--no-yarn-install

- name: Prebuild Expo iOS harness
if: matrix.harness == 'expo'
working-directory: apps/build-harness-expo
run: |
export NODE_PATH="$PWD/node_modules"
CI=1 yarn expo prebuild --clean --platform ios

- name: Build Expo iOS harness
if: matrix.harness == 'expo'
working-directory: apps/build-harness-expo/ios
run: |
WORKSPACE="RNFBExpoHarness.xcworkspace"
SCHEME="RNFBExpoHarness"
xcodebuild \
-workspace "${WORKSPACE}" \
-scheme "${SCHEME}" \
-configuration Debug \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO \
build

android:
name: Android (${{ matrix.harness }})
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
harness:
- bare
- expo
env:
IOS_GOOGLE_SERVICES_PATH: ${{ runner.temp }}/GoogleService-Info.plist
ANDROID_GOOGLE_SERVICES_PATH: ${{ runner.temp }}/google-services.json
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50

- uses: actions/setup-node@v4
with:
node-version: 22

- name: Configure JDK
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'

- name: Create CI Firebase config files
run: bash ./scripts/write-ci-firebase-configs.sh "${IOS_GOOGLE_SERVICES_PATH}" "${ANDROID_GOOGLE_SERVICES_PATH}"

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-harness-gradle-v1-${{ hashFiles('yarn.lock', 'apps/build-harness/android/**/*.gradle', 'apps/build-harness/android/gradle.properties', 'apps/build-harness-expo/package.json', 'apps/build-harness-expo/app.config.js') }}
restore-keys: |
${{ runner.os }}-harness-gradle-v1-

- name: Yarn install
run: yarn

- name: Sync bare harness
if: matrix.harness == 'bare'
run: |
bash ./scripts/sync-build-harness.sh sync \
--ios-google-services "${IOS_GOOGLE_SERVICES_PATH}" \
--android-google-services "${ANDROID_GOOGLE_SERVICES_PATH}" \
--no-yarn-install \
--no-pod-install

- name: Build bare Android harness
if: matrix.harness == 'bare'
working-directory: apps/build-harness/android
run: ./gradlew :app:assembleDebug

- name: Sync Expo harness
if: matrix.harness == 'expo'
run: |
bash ./scripts/sync-build-harness-expo.sh sync \
--ios-google-services "${IOS_GOOGLE_SERVICES_PATH}" \
--android-google-services "${ANDROID_GOOGLE_SERVICES_PATH}" \
--no-yarn-install

- name: Prebuild Expo Android harness
if: matrix.harness == 'expo'
working-directory: apps/build-harness-expo
run: |
export NODE_PATH="$PWD/node_modules"
CI=1 yarn expo prebuild --clean --platform android

- name: Build Expo Android harness
if: matrix.harness == 'expo'
working-directory: apps/build-harness-expo/android
run: ./gradlew :app:assembleDebug
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,10 @@ tests/ios/resetXcode.sh

google-services.json
GoogleService-Info.plist
apps/build-harness/android/app/google-services.json
apps/build-harness/ios/BuildHarness/GoogleService-Info.plist
apps/build-harness/.build-harness.local.json
apps/build-harness/.bundle/

# generated files
RNFBVersion.m
Expand Down
44 changes: 44 additions & 0 deletions apps/build-harness-expo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

# generated native folders
/ios
/android
GoogleService-Info.plist
google-services.json
.build-harness.local.json
Loading
Loading