Article updated in March 2023 with the latest benchmarks numbers.
Time spent on uploading the .ipa binary to App Store Connect is notorious for taking anywhere from seconds up to an hour. This is not because the upload takes a long time, but because Apple needs to process the build and run checks for possible issues before making the uploaded build available in App Store Connect. Waiting for Apple to finish the processing so that we can make further actions with the build can really eat into one’s build minutes and delay getting feedback about the build. Keep reading to find out how Codemagic and Magic Actions resolve those issues.
Problem 1. Uploaded builds are not immediately available
In order to distribute the builds to testers or upload release notes, there are a few actions that have to be performed in App Store Connect after the build has been uploaded, such as
- Approve the application for beta review
- Upload release notes in multiple languages
- Release our application for external testers
The issue is that before the build becomes available in TestFlight to perform these actions, Apple needs to process it, which can take a long time. Regardless of whether you’re performing these actions manually or trusting your CI with these tasks, you cannot upload release notes or make the build available to testers until Apple has finished processing.
Problem 2. Waiting after Apple costs money
Waiting for Apple to process the build can cost you both time and money. You can either wait for that email from App Store Connect saying your build was successfully uploaded to App Store Connect and start clicking away to upload release notes, or you can automate the task in a CI workflow and keep the build machine busy until Apple is done processing. If you’re paying for the used build minutes, this can quickly skyrocket your CI costs.
Spoiler alert: neither manual actions or paying for the processing time is required with Codemagic!
Problem 3: Long feedback cycle
Last but not least, long processing time increases the time it takes for your team to get feedback on whether or not the tests have passed and the compilation and code signing was successful on the CI. It is evident that the faster we can get feedback from CI on build status without resorting to manual actions, the more productive and happier the developers in the team.
Solution: Magic Actions
To address all these problems, the Codemagic team released post-processing of App Store Distribution jobs or Magic actions for short.
Magic actions are quite cool. Once the build is uploaded to App Store Connect, we start post-processing asynchronously outside of the macOS virtual machine. MacOS is required for the iOS build process because it has Xcode, which is necessary to compile the .ipa artifact, you also need to have xOS runtimes for instrumentation tests. Every other part of the pipeline can be executed in any other OS.
This means that you don’t need to wait around and pay for Apple to process your builds in order to get a green build and continue with development. Your build will finish right after the app artifact has been uploaded and you will receive a build status update. All the following steps, like waiting for Apple to process the build, submitting the build to beta review, uploading release notes or distributing the build to beta groups, take place asynchronously.
The timeout on the post-processing step is set to 120 minutes and this does not count towards build minutes or concurrencies, it’s completely free.
Moreover, as your team grows, cutting build times even by 20 minutes on each deploy to testers is a major win since resources will become free sooner and teams need not to spend money on buying new racks of macOS machines or increasing their capacity with a CI provider. Check out some real life examples of how much time you can with Magic Actions below.
Getting started with post-processing a.k.a. “Magic Actions”
If you are building native iOS, Flutter, React Native, Ionic, or Unity apps using codemagic.yaml, then post-processing takes place automatically, provided that you are using app_store_connect
in the publishing section of your configuration file.
There are two ways to achieve this:
- Provide the relevant information in the Apple Developer Portal Integration under Teams > Integrations > Developer Portal:
And then update the configuration file with the API Key and authentication method as integration
:
workflows:
ios-app-workflow:
integrations:
app_store_connect: <your API key name>
scripts:
- ...
publishing:
app_store_connect:
auth: integration
You can find more information about it in this blog post. This way, you can use the same developer account for multiple apps without configuring each of them.
- Provide the following information in the configuration file:
artifacts:
- build/ios/ipa/*.ipa
publishing:
app_store_connect:
api_key: $APP_STORE_CONNECT_PRIVATE_KEY # Contents of the API key
key_id: $APP_STORE_CONNECT_KEY_IDENTIFIER # Alphanumeric value that identifies the API key
issuer_id: $APP_STORE_CONNECT_ISSUER_ID # Alphanumeric value that identifies who created the API key
submit_to_testflight: false # Optional boolean, defaults to false. Whether or not to submit the uploaded build to TestFlight to automatically enroll your build to beta testers.
# beta_groups: # Specify the names of beta tester groups that will get access to the build once it has passed beta review.
# - group name 1
# - group name 2
You can find more about it in thisblog post.
Uploading the .ipa will be done asynchronously as a post-processing action.
Submitting your app for TestFlight beta review using submit_to_testflight
will also be handled during post-processing.
For more information about post-processing with codemagic.yaml, please see here.
If you are publishing Flutter iOS apps with the Workflow Editor, then post-processing will be handled automatically when uploading the .ipa to App Store Connect or if you have checked the option to submit your app to TestFlight beta review.
Workflow Editor and codemagic.yaml
users should also note that if you have also added a release_notes.json
file to the root of your repository, as described here, this will also be handled as a post-processing task.
Real-life examples of how Magic Actions cut build times
To find out how much Magic Actions reduces build times, we decided to do a test using several CI/CD providers using the same build scripts we use on Codemagic. This was possible thanks to Codemagic’s open-source CLI tools, which can be used to build, code sign, and publish iOS apps on any building infrastructure. All tests make use of Xcode 14.2 to maintain consistency across the results.
Test 1. Codemagic CI/CD
In the first test we ran the workflow for a simple iOS app on a Codemagic standard M1 Mac Mini instance. The overall build time was 1m 25s (85 seconds) when using Magic Actions. A total of 1m 22s was saved which means the build was 150% quicker than if they hadn’t been used.
Test 2. Bitrise
In the second test we used a Bitrise standard macOS machine using the same build script used in the Codemagic test. The overall build time was 2m 56s (176 seconds) which means Codemagic was 207% quicker.
Test 3. GitHub Actions
In the final test, we set up the same application on Github actions using the same build script that was used on Codemagic and Bitrise. The total build time was 5m 12s (312 seconds) which means the Codemagic build was 367% quicker than Github with Magic Actions.
The sample project used for testing is available on GitHub.