Many teams encounter a problem when automating iOS releases: the IPA is built on a macOS node, but they don’t want to rely on Xcode for the upload process.
Reasons include:
- GUI is not suitable in CI environments
- Manual operations are too heavy for multi-project uploads
- Upload behavior can change after Xcode updates
- Linux servers are better suited for running release scripts
Thus, a typical architecture emerges: macOS handles building, Linux handles uploading.
This article focuses on how to automatically upload IPA to App Store Connect from a Linux environment and truly integrate the upload action into the automation workflow.
Decouple Build and Upload
When first setting up CI, many people put IPA generation and App Store upload in the same stage. In reality, these two tasks can be completely decoupled.
The build stage handles archiving, signing, and exporting the IPA, usually on macOS.
The upload stage handles metadata generation, App Store Connect upload, and build submission. This stage can be entirely placed on Linux.
Linux is Better Suited as an Upload Node
If a project has moved to daily builds, multi-environment releases, automated testing, and multi-person collaboration,
Linux advantages become clear.
For example:
| Scenario | Linux Advantage |
|---|---|
| Jenkins | Easy deployment |
| Docker | Easy isolation |
| GitLab CI | Mature Runner |
| GitHub Actions | Easy scripting |
GUI upload is hard to maintain in these environments. In real projects, it’s common that:
- macOS node runs
flutter build ipaorxcodebuild archiveto generateapp.ipa - Linux node receives the IPA, uploads to App Store Connect, and outputs logs
What is Needed for Linux Upload
The upload stage requires:
| Item | Purpose |
|---|---|
| IPA file | Upload payload |
| Apple ID | Developer account |
| App-Specific Password | Upload authentication |
| Upload tool | Submit the IPA |
Obtain App-Specific Password
Do not use your Apple login password. You need to create an App-Specific Password in your Apple ID security settings. The upload tool will use this password for authentication.
Upload Tool in Linux Environment
Here we take AppUploader (Happy Upload) CLI as an example.
The Linux version is located at runtime/appuploader_cli. First, grant permissions: chmod +x appuploader_cli
Execute Upload Command
Direct upload:
./appuploader_cli upload \
-f app.ipa \
-u user@example.com \
-p xxxx-xxxx-xxxx-xxxx \
--type ios
Alternatively:
./appuploader_cli --upload-app \
-f app.ipa \
-u user@example.com \
-p xxxx-xxxx-xxxx-xxxx \
--type ios
What happens during the upload? The CLI tool will:
- Automatically parse IPA information: read Bundle ID, Version, Build Number
- Generate metadata: including
AppStoreInfo.plist, no manual creation needed - Submit to App Store Connect: after successful upload, Apple begins processing the build
Complete CI Example
Below is a GitLab CI scenario.
Build stage (macOS Runner):
build_ios:
script:
- flutter build ipa
Generates:
build/ios/ipa/app.ipa
Upload Stage (Linux Runner)
upload_ios:
script:
- chmod +x appuploader_cli
- ./appuploader_cli upload \
-f build/ios/ipa/app.ipa \
-u $APPLE_ID \
-p $APP_PASSWORD \
--type ios
Where to Check Results After Upload
Go to App Store Connect → TestFlight. If the upload was successful, the build should appear within a few minutes. If not, check the following:
| Check Item | Content |
|---|---|
| Build Number | Is it incremented? |
| Bundle ID | Does it match? |
| IPA Signing | Is it App Store type? |
| App-Specific Password | Is it valid? |
Project Types Suitable for Linux Automated Upload
The following project types are well-suited:
| Type | Scenario |
|---|---|
| Flutter | Automated build |
| React Native | CI release |
| Unity | Cloud build |
| uni-app | Upload after cloud packaging |
| HBuilderX | Automatic IPA submission |
Now many teams adopt:
| Task | Tool |
|---|---|
| Development | Flutter / RN |
| Packaging | macOS |
| Upload | Linux CLI |
| Review Mgmt | App Store Connect |
This way:
- Linux handles automation
- macOS only handles compilation
- Release process is easier to maintain
Automated IPA upload to App Store Connect from Linux essentially shifts the iOS release process from GUI to scripting. Once the IPA is generated, the upload can be completed independently via CLI.