What does a Flutter-aware CI service like Codemagic or Bitrise handle that GitHub Actions with subosito/flutter-action leaves to you?
answer
- all-in-one versus assemble-it-yourself
- Flutter version as a setting
- keystore upload becomes env vars
- automatic iOS signing via API key
- publishing to stores and testers
basics
~20 sCodemagic and Bitrise are all-in-one Flutter CI services: they select the Flutter version, provide macOS machines, manage signing files and publish to stores or Firebase App Distribution. With GitHub Actions and subosito/flutter-action you script those steps yourself, often with fastlane.
solid answer
~40 sThe Flutter docs list Codemagic, Bitrise and Appcircle as **all-in-one options with built-in Flutter functionality**, and GitHub Actions among the systems you combine with fastlane. On Codemagic, for example, the Flutter version is a setting (a channel, an exact version or `fvm`), an uploaded Android keystore is exposed as `CM_KEYSTORE_PATH` and related variables, automatic iOS signing creates certificates and profiles through an App Store Connect API key without the team owning a Mac, and publishing to stores or Firebase App Distribution is configuration. With GitHub Actions, `subosito/flutter-action` installs Flutter, and everything else, from macOS runners and the keychain to uploads, is steps you write. The trade-off is convenience and Flutter defaults against control and one CI system for the whole organisation.
code
bash · 4 lines# Tester build for Firebase App Distribution from any CI system
flutter build ipa --export-method ad-hoc
flutter build apk
ls build/ios/ipa build/app/outputs/flutter-apkgo deeper
Recall the two families: Flutter-aware services such as Codemagic and Bitrise, and general CI such as GitHub Actions with subosito/flutter-action and fastlane.
Explain what each side handles: Flutter version selection, macOS machines, keystore variables, automatic iOS signing and publishing, versus scripting them yourself.
Pick for the team: time to first signed build, iOS signing without Macs, portability of scripts, and the right export method for tester distribution.
Weigh a specialised mobile CI against one organisation-wide CI, including cost of macOS minutes, vendor lock-in and who maintains the Flutter-specific scripts.
## Two families of Flutter CI The Flutter continuous-delivery page sorts the options into two groups: - **All-in-one options with built-in Flutter functionality**: Codemagic, Bitrise and Appcircle. - **General CI systems combined with fastlane**: GitHub Actions, GitLab, CircleCI, Cirrus and others. Both can build the car-wash booking app on every merge. The difference is how much of the Flutter-specific plumbing you write and maintain. ## What the Flutter-aware services provide Using Codemagic as the documented example: 1. **Flutter version as configuration.** The workflow names a channel, an exact version, or `fvm` to use the project's FVM config. 2. **Build machines.** macOS machines for iOS builds are part of the service. 3. **Android signing.** You upload the keystore and enter its passwords; the build exports `CI=true` and `CM_KEYSTORE_PATH`, `CM_KEYSTORE_PASSWORD`, `CM_KEY_ALIAS` and `CM_KEY_PASSWORD`, which the release `signingConfig` reads. Codemagic can also generate `key.properties` for the Flutter workflow editor. 4. **iOS signing.** With **automatic code signing**, Codemagic uses an App Store Connect API key to create the certificate and provisioning profile, without the team needing a Mac. 5. **Publishing.** Uploading to App Store Connect, Google Play or Firebase App Distribution is a configured step with credentials stored in the service. Bitrise and Appcircle offer comparable Flutter-specific building blocks. ## What a GitHub Actions workflow leaves to you - **Installing Flutter**: `subosito/flutter-action` does this, with inputs for the channel or version and `cache: true` for its caching. - **Choosing runners**: Android can build on Linux; `flutter build ipa` needs a macOS runner. - **Signing**: decoding the keystore, writing `key.properties`, creating a temporary keychain, importing certificates and profiles, choosing an export plist. - **Uploading**: usually fastlane lanes for Play and App Store Connect, or vendor CLIs. - **Tester delivery**: scripting the Firebase App Distribution upload yourself. ## How to choose | Concern | Flutter-aware service | GitHub Actions + subosito + fastlane | |---|---|---| | Time to first signed build | short, mostly configuration | longer, mostly scripting | | iOS signing without a Mac on the team | built in | you build it with an API key and tools | | One CI for backend and app | a second system | same system as the rest of the org | | Portability | tied to the service's config | scripts can move between CI systems | | Flutter defaults kept current | by the vendor | by you | ## Firebase App Distribution in either setup Whichever system uploads to Firebase App Distribution, two Flutter build details matter: - The iOS build must be exported with a **development, Ad Hoc or Enterprise** profile, so the pipeline runs `flutter build ipa --export-method ad-hoc` rather than the App Store default. - Distributing an `.aab` requires the Firebase project to be **linked to Google Play**; otherwise upload an APK from `flutter build apk`. - Authenticate with a **service account**; token authentication is marked deprecated. ## A decision in practice For the car-wash booking app, a small team without Macs and without an existing CI system typically reaches a signed iOS build fastest on a Flutter-aware service: automatic signing through the App Store Connect API removes the keychain work, and publishing to testers is configuration. A company whose backend already runs on GitHub Actions may prefer one system for everything and accept writing the macOS signing steps and fastlane lanes once. Either way, keep the Flutter commands themselves portable: `flutter pub get --enforce-lockfile`, `flutter analyze`, `flutter test` and the `flutter build` invocations should be the same lines in any CI system, so moving between services changes the wrapper, not the build. ## Common mistakes - Assuming the all-in-one service removes the need to understand signing; when automatic signing fails, the same certificates and profiles are involved. - Sending an App Store-exported IPA to Firebase App Distribution. - Choosing GitHub Actions for consistency and then underestimating the macOS signing work.
- Why does an App Store-exported IPA not suit Firebase App Distribution?Firebase App Distribution installs builds directly on testers' devices, which requires a development, Ad Hoc or Enterprise profile. An App Store profile only allows installation through the store or TestFlight, so export with `--export-method ad-hoc` for testers.
- What still needs your understanding when Codemagic's automatic iOS signing fails?The same pieces as manual signing: the App Store Connect API key's access, the bundle ID, the certificate type and the provisioning profile, plus a separate profile for every app extension.
saying these in an interview costs you the question
- GitHub Actions cannot build Flutter iOS apps at all.
- With a Flutter CI service you never need to understand signing.
- An App Store-exported IPA can go straight to Firebase App Distribution testers.
- subosito/flutter-action also signs and uploads the app for you.
- Firebase App Distribution accepts an .aab without any Play linking.