Blaze compiles your Flutter app on a macOS runner, signs it with Apple's cloud signing and uploads it to App Store Connect. You do not create, export or upload certificates or provisioning profiles: one App Store Connect API key is all Blaze needs from Apple.
Before You Start
You need:
- An Apple Developer Program membership.
- Your Team ID, the 10-character code under Membership details in your Apple Developer account. Enter it on Signing & keys, in the App Store Connect API key card (below).
- The app's bundle ID registered with Apple, and the app created in App Store Connect with that bundle ID (Apple Developer).
- An App Store Connect API team key with the App Manager role: its Issuer ID, Key ID and
.p8file (Apple Developer). - The owner or admin role in the Blaze workspace to upload the key and enter the Team ID. Developers see the card read-only.
Bundle ID
The bundle ID is PRODUCT_BUNDLE_IDENTIFIER of the Runner target in ios/Runner.xcodeproj. It must match three things:
- The identifier registered in your Apple Developer account.
- The app in App Store Connect.
- The Bundle ID in Blaze: open the application page, then the App Store Connect card's ··· menu, then iOS settings….
Before each build, Blaze reads ios/Runner.xcodeproj/project.pbxproj from GitHub and stops the deployment at Prepare runner if none of the bundle IDs declared there is the one in Blaze, so a build never uploads to the wrong app.
In the same iOS settings dialog, App Store app ID is the number in the app's App Store Connect URL. iOS tester groups in Blaze need it.
How Blaze Signs iOS Builds
On the build runner, and only in the runner's copy of your project, Blaze:
- rewrites the Xcode project's signing settings for automatic signing:
CODE_SIGN_STYLEbecomesAutomatic,PROVISIONING_PROFILE_SPECIFIERandCODE_SIGN_IDENTITYare cleared, andDEVELOPMENT_TEAMbecomes your Team ID; - compiles without signing, then exports an App Store build with
xcodebuild -exportArchive -allowProvisioningUpdates, authenticated with your App Store Connect API key.
Apple then provides the distribution certificate and App Store provisioning profiles through cloud signing. Manual signing settings in your repository are overridden, so there is nothing to configure in project.pbxproj, and the Certificates & profiles card on Signing & keys normally stays empty.
Connect Your App Store Connect Key
Open the application page, then Signing & keys from the ··· menu. Each app has its own App Store Connect key and Team ID, and a new app starts with neither. When another app in the workspace already has a key that works, as apps in one Apple Developer team usually do, the card offers Copy from that app, which brings its Team ID too.
Enter your Team ID and the key's IDs
In the App Store Connect API key card, fill in Team ID from Membership details in your Apple Developer account. Then fill in Issuer ID (a UUID) and Key ID, both shown on the App Store Connect API page of App Store Connect.
Upload the .p8
Click Upload .p8 (Replace .p8 once a key is connected) and choose the AuthKey_<Key ID>.p8 file. The form saves as soon as you pick the file, so enter the IDs first.
Check the result
Blaze refuses a file that is empty or is not a private key. It then checks the key with Apple, which costs no build minutes. The card reads Valid when Apple accepts the key and a Team ID is saved, Team ID missing when only the Team ID is still needed, and says why when Apple refuses the key.
Once a key is connected, you can enter or correct the Team ID without uploading the key again: type it in Team ID and click Save Team ID. Apple lets you download a .p8 only once, so the stored key stays as it is.
Every iOS deployment checks at Prepare runner, whatever the target, that the app has a Team ID and that Apple accepts the key, so an iOS build never starts without either.
Version and Build Number
The version comes from the version: line of pubspec.yaml at the commit being built, for example version: 1.4.0. Anything after a + is ignored, because Blaze assigns the build number.
On the runner, Blaze sets that version and build number on the app and on every extension target (widgets, notification service and other extensions), because App Store Connect rejects an app whose extensions carry a different version. If App Store Connect already has a higher build number for the app, the export moves the build number past it, the log says so, and the deployment records the number that actually shipped.
Once a version has been approved for the App Store, App Store Connect only accepts builds with a higher version. Raise version: in pubspec.yaml when you start the next release.
How Blaze Builds iOS
Each iOS deployment moves through the steps shown on the deployment page:
- Prepare runner: reads
pubspec.yamlandios/Runner.xcodeproj/project.pbxprojfrom GitHub, checkspath:dependencies, theenvironment: flutter:constraint against the Flutter version you pinned and the bundle ID, checks that the app has a Team ID, and checks the App Store Connect key with Apple. - Clone, pub get & pods: selects the Xcode version from Build settings, checks out the exact commit being deployed, runs
flutter pub getand installs CocoaPods and Swift packages. - Compile: runs
flutter build ios --release --no-codesign, passing your environment variables as--dart-define. - Code sign & export: signs through Apple's cloud signing and exports the
.ipa. - Upload → TestFlight: uploads the
.ipato App Store Connect. Blaze never submits a build for App Review; see Deployment for what each target does after the upload.
Along the way, Blaze also:
- uses the CocoaPods CDN for the build when your
Podfilepoints at the CocoaPods git specs repository, and says so in the log; - installs
flutterfire_cliwhen your Xcode project uses FlutterFire, so its Crashlytics symbol upload build phase can run; - keeps Flutter SDK, pub, CocoaPods, Swift package and compiled build caches between deployments.
What Is Not Supported
- Flavors and custom schemes. Builds use the Runner scheme's Release configuration, without
--flavor. - Your own certificates and provisioning profiles. Signing always goes through Apple's cloud signing with the API key.
- A different entry point. Blaze builds
lib/main.dart. - Environment variables in
Info.plistor.xcconfigfiles. They reach Dart only. See Environment Variables. - Submitting for App Review. Choose the build for a version in App Store Connect and submit it there.
- An app in a subdirectory of the repository. See Build Configuration.
Troubleshooting
Prepare runner says App Store Connect rejected the API key. The Issuer ID, the Key ID and the .p8 must belong to the same key, and the key must not be revoked. Upload the key again on Signing & keys.
Prepare runner says the bundle ID does not match. Change Bundle ID in iOS settings, or PRODUCT_BUNDLE_IDENTIFIER in the Xcode project, so they are the same.
Code sign & export fails with "Cloud signing permission error". Blaze signs with Apple's cloud-managed distribution certificates, and this error means Apple did not let your API key use them. The key needs the Admin role: create a key with the Admin role in App Store Connect, then replace the key on Signing & keys.
Clone, pub get & pods says the Xcode version is not installed on this runner. The version pinned in Build settings is not on the runner image. The message lists the versions that are; choose one of them, or latest on the runner.
Prepare runner says the app has no Apple Team ID, or that it is not 10 capital letters and digits. Copy the Team ID from Membership details in your Apple Developer account. On Signing & keys, an owner or admin types it in the App Store Connect API key card's Team ID and clicks Save Team ID; the stored key stays as it is.
The upload is rejected. Check that the app exists in App Store Connect with the same bundle ID, and that version: in pubspec.yaml is higher than the last version approved for the App Store.
Next Steps
- Apple Developer: bundle ID, app record and the API key
- Build Configuration: Flutter and Xcode versions
- Deployment: targets and the deployment page
- iOS deployment in the Flutter docs