Automated Pipelines with Fastlane and GitHub Actions
Build, sign, and ship to stores automatically using Fastlane lanes and Actions workflows.
Why Automate Flutter Releases
Shipping a Flutter app to both stores by hand is slow and error-prone: bumping versions, building IPA/AAB, signing, uploading, and writing release notes for every platform.
A CI/CD pipeline turns this into a single trigger. We combine two tools:
- Fastlane — Ruby-based automation for the iOS and Android store steps (signing, building, uploading to TestFlight / Play Console).
- GitHub Actions — the orchestrator that checks out code, sets up Flutter, and invokes Fastlane on a hosted runner.
Think of GitHub Actions as the conductor and Fastlane lanes as the per-platform musicians.
Version and Build Number Strategy
Stores reject uploads that reuse a build number. Your pipeline must compute a fresh, monotonically increasing number on every run.
In Flutter, pubspec.yaml holds version: 1.4.0+57 where 1.4.0 is the user-facing name and 57 is the build number. A common CI pattern is to feed the GitHub Actions run number into the build.
Here is a small Dart helper that derives the full version string from a base name and a CI counter.
void main() {
String buildVersion(String name, int ciRunNumber) {
if (ciRunNumber < 1) {
throw ArgumentError('Build number must be >= 1');
}
return '$name+$ciRunNumber';
}
print(buildVersion('1.4.0', 57)); // 1.4.0+57
print(buildVersion('2.0.0', 120)); // 2.0.0+120
}All lessons in this course
- Build Flavors and Environment Configuration
- Automated Pipelines with Fastlane and GitHub Actions
- Crash Reporting and Symbolicated Stack Traces
- Remote Config, Feature Flags, and Staged Rollouts