.appCreating React Native Simulator Builds in App Center
Using App Center for mobile CI/CD is simple, but it does not allow for much customization. Our team requested a simulator build to facilitate automated testing. After some research and tinkering, I was able to come up with a clever (read: hacky) solution.

I generally like using App Center for mobile CI/CD. It is dead simple to get a pipeline up and running. However, it does not allow for much customization. I recently ran up against this limitation when trying to set up a build pipeline for iOS simulator builds.
Our QA team requested a
.ipaThe general idea is:
Create the
artifact by running.appin a pre-build scriptxcodebuildDistribute the artifact using the App Center CLI
Exit the build before the usual build steps run
Adding the build pipelines
We are going to set up two pipelines, one for building the app, and one for distribution. The reason we need a separate pipeline for distributions is that the standard iOS OS type in App Center will only let you distribute
.ipa.app.zip.appThe first pipeline should be configured the same as any other iOS build pipeline you may have already set up. Set an environment variable (eg.
$IS_CI_SIMULATOR_BUILDThe second will be a “Custom” app type, which has no build step but lets us distribute
.zip.appWe will also need to create an authentication token. We will use this later to authenticate with the App Center CLI in order to upload our build.
Pre-build Script
Branching paths in appcenter-pre-build.sh
if [[ $IS_CI_SIMULATOR_BUILD ]]; then
bash ./scripts/ios-sim-build.sh
fi
Our codebase should be build-agnostic, so we can use an environment variable to tell App Center to run our simulator build script at the end of the regular build script.
We also need to add an additional environment variable to our build pipeline called
$APPCENTER_OWNER_APP_NAMEhttps://appcenter.ms/orgs/${YOUR_ORG}/apps/${YOUR_RELEASE_PIPELINE_NAME}/distribute/releases$(YOUR_ORG}/${YOUR_RELEASE_PIPELINE_NAME}The simulator build script
#!/usr/bin/env bash
unset PREFIX
cd ios && pod install && cd ..
xcodebuild -workspace "ios/MyApp.xcworkspace" \
-derivedDataPath "./ios-sim-build" \
-scheme "MyApp" \
-configuration "Release" \
-destination "generic/platform=iOS Simulator" \
clean build
appcenter login --token $APPCENTER_USER_TOKEN
export BUILD_VERSION=`appcenter distribute releases list --app $APPCENTER_OWNER_APP_NAME | sed -n '1p' | sed "s/[^0-9]//g"`
# path may be different based on the name of your configuration
cd ios-sim-build/Build/Products/qa-iphonesimulator
zip -rq MyApp.zip MyApp.app
appcenter distribute release \
--app $APPCENTER_OWNER_APP_NAME \
--file PayPower.zip \
--group "QA"
--build-version $(($BUILD_VERSION + 1))
exit
xcodebuild
Ok, here’s the meat of the script:
- runs the build, resulting in the
xcodebuildfile we need..app- : path to the .xcworkspace file
-workspace - : path to the directory where the temp build files will be stored
-derivedDataPath - : usually the name of your project unless you have created custom schemes
-scheme - : usually
-configurationor"Debug"unless you have created custom configurations. You probably want"Release"because it will include the bundled JS, whereasReleasewill be looking for the metro server.Debug - : use
-destinationas the value to get a"generic/platform=iOS Simulator"artifact.app - +
clean: clean cache files and start the buildbuild
AppCenter Distribution
We’ve got our
artifact. All we have to do now is find a way to distribute it!.appAuthenticate using
appcenter login --token $APPCENTER_USER_TOKENGet the previous build number using
andappcenter distribute releases list, so we can increment it and use it for the current releasesedZip the .app file
Distribute using
appcenter distribute release- quits the builds early and shows a green checkmark
exit
Conclusion
After using this approach with my team for a few weeks, we identified some opportunities for improvement. We realized that the
.zipsCreating this pipeline has allowed our QA team to stay perfectly in sync with the development team. Before this approach, we had to manually run a build every time there was a push to
developNewsletter Sign-up
Receive summaries directly in your inbox.







