My First Experience Integrating React Native with CircleCI
A couple of days ago (22/11/2024), I got a task to integrate our React Native development app with CircleCI. My principal engineer provided the initial configuration, and I thought, "This shouldn’t be too hard—I just need to plug in the config and make it work."
But when I tried running it, the tests failed.
Here’s the configuration I started with:
version: 2.1
orbs:
node: circleci/node@5.2.0
android: circleci/android@2.5.0
rn: react-native-community/react-native@7.3.0
ruby: circleci/ruby@2.1.1
commands:
detox_build_android:
steps:
- android/restore-gradle-cache
- run: |
npm install -g detox-cli react-native-cli
yarn android:detox:build:emu
- android/save-gradle-cache
create_env_file:
steps:
- run:
name: Creating .env file
command: |
cat \<< EOF > .env
APP_ID=$APP_ID
<another_env_property>
EOF
- persist_to_workspace:
root: .
paths:
- .env
jobs:
detox_android:
executor:
name: android/android-machine
resource-class: large
tag: "2023.08.1"
steps:
- checkout
- create_env_file
- run:
name: Cat .env File
command: cat .env
- run:
name: Install dependencies
command: yarn install --frozen-lockfile
- run:
name: Generate release.keystore
command: echo "$RELEASE_KEYSTORE" | base64 --decode > android/app/release.keystore
# - detox_build_android
- rn/android_emulator_start:
device_name: Pixel_5_API_33
# - run:
# name: Set APK Path
# command: echo "APK_PATH=android/app/build/outputs/apk/release/app-release.apk" >> $BASH_ENV
- run:
name: Wait for Emulator to Fully Boot
command: |
adb wait-for-device
adb shell getprop sys.boot_completed | grep 1 || sleep 5
adb shell input keyevent 82
- detox_build_android
- run:
name: Run Detox Tests
command: detox test -c android.emu.release --loglevel verbose
workflows:
test_and_distribute:
jobs:
- detox_android:
filters:
branches:
only:
- main
A New Challenge
To be honest, I had never worked with anything related to CI/CD before, so this was my first experience—exciting, but also a little daunting! 😅
I dove into trial and error mode, trying everything I could think of. After what felt like 374 attempts, I decided to explore the documentation more thoroughly.
That’s when I stumbled upon a helpful blog post: React Native E2E Tests and Automatic Deploys (Detox + Fastlane + CircleCI).
This blog provided a lot of insight into the flow I needed to follow to get the tests running.
Debugging the Configuration
One key thing to note about CircleCI’s free plan is its limitations. For example, apps can only be run on Linux. If you need to test with iOS, you’ll have to upgrade to a paid plan.
After carefully reviewing the configuration provided by my engineer, I realized one critical step was missing: starting the Metro bundler.
I checked the CircleCI React Native documentation and found a specific command to run Metro. After adding this step to the config, everything finally worked smoothly! yay !
My Working Configuration
Here’s the configuration I used to run React Native CLI with Detox on CircleCI. Keep in mind that since I’m using the free plan, this setup only works for Android. To run tests on iOS, you’ll need to subscribe to a paid plan.
version: 2.1
orbs:
rn: react-native-community/react-native@8.0.0
android: circleci/android@3.0.2
commands:
install_init:
steps:
- rn/yarn_install
- run:
name: Install Global CLI Tools
command: |
npm install -g detox-cli react-native-cli
react-native --version
jobs:
checking:
executor:
name: rn/linux_js
node_version: '18.2'
steps:
- checkout
- install_init
- run:
command: yarn checker // run linter, prettier, jest
- persist_to_workspace:
paths:
- .
root: .
test_android:
executor:
name: android/android_machine
resource_class: large
tag: '2023.10.1'
steps:
- attach_workspace:
at: .
- rn/android_emulator_start:
build_tools_version: '33.0.0'
device_name: Pixel_5_API_33
platform_version: android-33
- install_init
- rn/metro_start
- run:
name: Detox Test
command: yarn detox:test:android -l verbose
workflows:
e2e_test:
jobs:
- checking
- rn/android_build:
name: build_android
build_image_version: 'v15.0'
resource_class: large
build_cache: false
gradle_options: '-Xmx4g -XX:MaxMetaspaceSize=512m'
build_type: debug
requires:
- checking
- test_android:
requires:
- build_android
Lessons Learned
This experience taught me the importance of reading the documentation thoroughly and not being afraid to experiment. CI/CD might seem intimidating at first, but once you understand the flow, it becomes manageable—even fun!
Top comments (0)