Managing multiple TestFlight apps, such as separate versions for production and development environments, can be quite challenging. However, by using Xcode Cloud’s Continuous Integration and Continuous Delivery (CICD) workflows with Bitbucket/Github, you can automate the deployment process.
This blog post will walk you through the process of deploying two different versions of the same React Native app to TestFlight: one for production (co.example.new
) and one for development/debugging (co.example.new.debug
). It covers creating separate build configurations, app bundle identifiers, app icons, and setting up workflows to automatically deploy the apps to TestFlight.
Step 1: Create App Bundle Identifiers
To handle two different versions of the app, you’ll need to create separate app bundle identifiers:
- Go to the Apple Developer Portal.
- Create two new App IDs:
-
co.example.new
for the production version. -
co.example.new.debug
for the development/debugging version.
-
Step 2: Duplicate Build Configurations in Xcode
Now that the app IDs are ready, the next step is to create distinct build configurations for production and development in Xcode.
- Open your project in Xcode.
- Go to the Build Settings tab.
- Find and duplicate the
Release
andDebug
configurations. Name themProd
andDev
, respectively. - Update the PRODUCT_BUNDLE_IDENTIFIER field:
- Set
Prod
to useco.example.new
. - Set
Dev
to useco.example.new.debug
.
- Set
Why Duplicate Build Configurations?
Duplicating the build configurations allows you to handle different environments (such as production and development) within the same project. Each configuration will use its respective bundle ID, app signing certificates, and provisioning profiles.
Step 3: Create a New Schema for the Development Build
After setting up the build configurations, you need to create a schema for the development build.
- Under Product > Scheme > Manage Schemes, duplicate the default schema.
- Rename the new schema to something like
DevAppNameSchema
. - Go to the Run and Archive actions of the new schema.
- In Run, set the build configuration to
Dev
. - In Archive, also set the build configuration to
Dev
.
- In Run, set the build configuration to
This new schema ensures that when you run or archive the app with the DevAppNameSchema
, it uses the Dev
build configuration, which is tied to the development bundle ID (co.example.new.debug
).
Step 4: Configure Signing and Capabilities
Now, let's configure the app's signing and capabilities to use the correct provisioning profiles for each version.
- In Xcode, under Targets > Signing & Capabilities, update the configurations:
- For the
Prod
build configuration, use the AppName provisioning profile. - For the
Dev
build configuration, use the AppNameDebug provisioning profile.
- For the
This ensures that Xcode uses the appropriate provisioning profile when deploying each version of the app to TestFlight.
Step 5: Set Up Unique App Icons
To make it easy to differentiate between the production and development builds, you can configure unique app icons for each version of the app.
- In the
ios/Images.xcassets
directory, duplicate theAppIcon.appiconset
folder and rename itAppIcon-Debug.appiconset
. - Place the development-specific app icon assets in the
AppIcon-Debug.appiconset
folder. - In Xcode:
- Under Build Settings, find the Primary App Icon Set Name field.
- Set the
Prod
build configuration to useAppIcon
. - Set the
Dev
build configuration to useAppIcon-Debug
.
Now, when you run the production version of the app, it will show the standard icon, and the development version will display the debug-specific icon.
Step 6: Set Up Xcode Cloud CICD Workflows
Xcode Cloud helps automate your build and deployment process by triggering workflows when you push changes to your Bitbucket repository. For this setup, I created two workflows—one for each app version.
Workflow 1: Production Build Workflow
- Go to Xcode Cloud in your Xcode project.
- Set up a workflow for the main branch in your Bitbucket repository.
- Under Environment Settings, configure the workflow to use the
Prod
build configuration. - Ensure that the workflow archives and uploads the app to TestFlight using the production provisioning profile and app bundle ID (
co.example.new
).
This workflow will be triggered whenever changes are pushed to the main branch, automatically deploying the production build to TestFlight.
Workflow 2: Development Build Workflow
- Create a second workflow, this time connected to the dev branch in your Bitbucket repository.
- Configure the workflow to use the
Dev
build configuration. - Ensure that the workflow archives and uploads the app to TestFlight using the development provisioning profile and app bundle ID (
co.example.new.debug
).
Now, any changes pushed to the dev branch will trigger the development workflow, deploying the development build to TestFlight.
Step 7: Testing the Workflows
To test the workflows, push some changes to the main branch and ensure that the production workflow is triggered in Xcode Cloud. Then, push changes to the dev branch to trigger the development workflow.
Each workflow should build, archive, and deploy the correct version of the app to TestFlight, using the appropriate app bundle ID and app icon.
Conclusion
By following these steps, you can efficiently manage multiple versions of your React Native app on TestFlight. Setting up separate build configurations, schemas, provisioning profiles, and app icons for production and development environments allows for a seamless CICD workflow using Xcode Cloud.
With automatic deployments triggered by Bitbucket pushes, your team can focus on development without worrying about manual TestFlight deployments. Whether you’re running beta tests or preparing for a production release, this setup keeps everything streamlined and organized.
Thank you for following along! I hope this guide simplifies your multi-environment deployment process. If you have any questions or suggestions, feel free to leave them in the comments below!
Happy coding and smooth deployments!
Top comments (0)