Streamlining React Native Builds with Xcode Cloud
Recently, I embarked on a side project to build a mobile app and validate our MVP. As a solo developer, I value automation to focus more on writing code and less on repetitive tasks. This was my first foray into building a mobile app for real-world users, so I aimed to identify and automate processes early on.
Choosing React Native and Expo
For the app’s frontend, I chose React Native (Expo) to leverage the “write once, run anywhere” capability for web, iOS, and Android. Expo’s ease of setup and the Expo client app meant I could bypass the initial complexities of Xcode.
Initial Challenges
After initializing the project, I set up a GitHub Action to use expo eas for triggering builds to TestFlight. This was sufficient at first, but I quickly hit the monthly build limit. Each commit triggered a build, and with the app’s heavy reliance on the camera (unusable on a simulator), I needed more frequent builds.
Exploring Alternatives
I explored Expo’s documentation for local builds, but the free GitHub tier lacked access to a macOS machine, making it cumbersome compared to Expo’s seamless handling of builds. While researching, I discovered that Apple developer accounts offer 50 hours of build minutes on Xcode Cloud. Intrigued, I linked my repo, but initial builds failed due to unfamiliarity with Xcode and Apple development.
Setting Up Xcode Cloud
Delving into documentation and forums, I learned about ci_scripts, essential for configuring builds. Apple supports three types:
- Post-clone script: Runs after Xcode Cloud clones your Git repository.
- Pre-xcodebuild script: Runs before Xcode Cloud runs xcodebuild.
- Post-xcodebuild script: Runs after Xcode Cloud runs xcodebuild.
To build React Native apps, a post-clone script is necessary to install prerequisites similar to local setups.
Here’s the script I used:
#!/bin/sh
# ci_post_clone.sh
set -e # Exit immediately if a command exits with a non-zero status.
echo "===== Installing CocoaPods ====="
export HOMEBREW_NO_INSTALL_CLEANUP=TRUE
brew install cocoapods
brew upgrade cocoapods
echo "===== Installing Node.js ====="
brew install node
echo "===== Installing yarn ====="
brew install yarn
echo "===== Running yarn install ====="
yarn install
echo "===== Cleaning CocoaPods cache ====="
pod cache clean --all
echo "===== Running pod install ====="
cd /Volumes/workspace/repository/ios
echo "Podfile contents:"
cat Podfile
pod install --verbose
echo "Podfile.lock contents:"
cat Podfile.lock
echo "===== Build environment setup complete ====="
Conclusion
This setup has significantly streamlined my build process, allowing me to focus more on development. Hopefully, this guide helps others facing similar challenges in automating their React Native builds with Xcode Cloud