Introduction
Continuous integration and continuous delivery (CI/CD) are essential for modern Flutter mobile development. Automating build, test, and distribution reduces human error, speeds iteration, and ensures consistent releases across Android and iOS. This tutorial shows a pragmatic CI/CD workflow using GitHub Actions for orchestration and Firebase App Distribution (plus the Firebase CLI) for distributing pre-release builds to testers.
Planning Your Workflow
Start by defining triggers and artifacts. Typical triggers are push to main for release builds and pull-request events for feature validation. Artifacts include APK, AAB, and IPA (iOS) files and test reports. Map stages:
Build: run flutter pub get and produce artifacts.
Test: run unit/widget/integration tests.
Package: sign and build release artifacts.
Distribute: upload to Firebase App Distribution or Google Play / TestFlight.
Decide if you will run Android and iOS jobs sequentially or in parallel. For macOS-hosted runners you can build iOS; for Linux/Windows use only Android. Store sensitive credentials (Firebase service account JSON, Keystore, Apple certificates) in GitHub Secrets. Keep artifacts ephemeral and only persist them between jobs via actions/upload-artifact when needed.
Setting Up GitHub Actions
Create .github/workflows/ci.yml. Key steps: checkout, cache pub and gradle, set up Flutter, run tests, build, and call Firebase CLI. Example targeted job for Android:
name: Flutter CI
on:
push:
branches: [ main ]
pull_request:
branches: [ '**' ]
jobs:
android-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: 'stable'
- name: Install Dependencies
run: flutter pub get
- name: Run Tests
run: flutter test --coverage
- name: Build APK
run: flutter build apk --release
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: app-release-apk
path
Add caching for Gradle and pub to speed builds. Use matrix strategy to build multiple flavors or target platforms.
Integrating Firebase App Distribution
Firebase App Distribution is ideal for distributing pre-release builds to QA. Steps:
Create a Firebase project and enable App Distribution.
Create a service account with roles: Firebase App Distribution Admin and Cloud Storage Admin.
Download the service account JSON and add it as a GitHub Secret (e.g., FIREBASE_SERVICE_ACCOUNT).
In your workflow, install the Firebase CLI and authenticate using the secret. Example snippet to distribute the built artifact:
- name: Install Firebase CLI
run: curl -sL https://firebase.tools | bash
- name: Authenticate to Firebase
env:
FIREBASE_SERVICE_ACCOUNT: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
run: |
echo "$FIREBASE_SERVICE_ACCOUNT" > ${HOME}/gcloud.json
gcloud auth activate-service-account --key-file=${HOME}/gcloud.json
- name: Distribute to Firebase App Distribution
run: |
firebase appdistribution:distribute build/app/outputs/flutter-apk/app-release.apk \
--app ${{ secrets.FIREBASE_ANDROID_APP_ID }} \
--groups "qa-team"For iOS, upload the IPA similarly but ensure you build on macOS runners and have your provisioning profiles and certificates managed securely (use GitHub Secrets or a signing service).
Automated Testing And Build Optimization
Prioritize fast, reliable tests. Split unit tests, widget tests, and slow integration tests into separate jobs. Use emulators sparingly — consider using flutter_driver or integration_test with cloud device farms only when necessary.
Use caching aggressively:
Cache ~/.pub-cache and ~/.gradle.
Cache build outputs only when safe; invalid cache can cause failures.
Fail fast on lint, formatting, and unit tests to catch problems early. Generate and upload coverage reports (lcov) as artifacts or use a coverage service. Example small Dart test snippet to include in your repo:
import 'package:flutter_test/flutter_test.dart';
void main() {
test('add two numbers', () {
expect(2 + 3, 5);
});
}For signing Android releases in CI, store keystore file as an encrypted secret (or Base64 encode and store) and restore it at runtime, then configure gradle signing via environment variables. For iOS, consider using fastlane with match or GitHub Secrets for certificates.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Implementing CI/CD for Flutter using GitHub Actions and Firebase App Distribution streamlines mobile development by automating build, test, and distribution steps. Start small: run tests and build APK on each PR, then add signing and distribution for main. Securely store credentials in GitHub Secrets, optimize caching, and split tests into focused jobs. With a reproducible pipeline, you get faster feedback, higher release quality, and predictable delivery to testers and stakeholders.