Master CI/CD Integration in Flutter: Step-by-Step Guide

Continuous Integration (CI) and Continuous Delivery/Deployment (CD) have become essential practices in modern software development, automating testing, building, and deploying apps. For Flutter developers, integrating CI/CD can help streamline the process of building and deploying cross-platform apps, enabling quicker iterations and more stable releases.

In this blog, we’ll explore setting up a CI/CD pipeline for a Flutter project, with detailed examples using GitHub Actions (a popular CI/CD tool).

What is CI/CD?

Continuous Integration (CI):

Continuous Integration is the practice of automating the integration of code changes from multiple contributors into a shared repository. CI typically includes automated testing to ensure code stability.

Continuous Delivery (CD):

Continuous Delivery involves automating the release process, ensuring that any code that passes all tests in the CI pipeline can be deployed to production environments at any time.

Related read: What, How and Why of CI/CD

Benefits of CI/CD for Flutter

  1. Faster Feedback Cycle: Automated tests run on every commit, ensuring bugs are caught early.
  2. Consistency Across Platforms: Flutter’s cross-platform nature makes CI/CD pipelines especially useful for ensuring consistent behavior across Android, iOS, web, etc.
  3. Automated Deployment: Simplify the release process to app stores, saving time and reducing manual errors.
  4. Improved Code Quality: By integrating tests into the pipeline, you ensure that only stable code is merged into production branches.

CI/CD Pipeline with GitHub Actions

GitHub Actions provides a flexible, out-of-the-box CI/CD solution. Let’s walk through setting up a CI/CD pipeline for a Flutter project using GitHub Actions.

Related read: 6 Stages of DevOps CI/CD Pipeline

Step 1: Setting Up Your Flutter Project

If you haven’t already, create a new Flutter project by running:

flutter create flutter_ci_cd_demo
cd flutter_ci_cd_demo

This creates a basic Flutter app. Initialize a Git repository and push your code to GitHub:

git init
git add .
git commit -m "Initial commit"
git remote add origin <your-repo-url>
git push -u origin main

Step 2: Configure GitHub Actions for CI

Navigate to your GitHub repository and create a workflow configuration for GitHub Actions:

  1. In your repository, go to the Actions tab.
  2. Select New Workflow, then choose Set up a workflow yourself.
  3. Name your workflow file, e.g., flutter-ci.yml.

Here is an example configuration for a CI pipeline with Flutter:

name: Flutter CI

on:
   push:
     branches:
        - main
   pull_request:
     branches:
        - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: 'stable'

      - name: Install dependencies
        run: flutter pub get

      - name: Run tests
        run: flutter test

This workflow will trigger the following tasks on every push or pull request to the main branch:

  1. Check out the code: Fetch the latest code from the repository.
  2. Install Flutter: Sets up the Flutter environment on the GitHub runner.
  3. Install dependencies: Runs Flutter pub to fetch all dependencies.
  4. Run tests: Run the unit tests using the flutter test command.

Step 3: Adding Automated Tests

Flutter supports unit, widget, and integration tests. You can add simple unit tests by creating a new file under the test directory, for example, test/counter_test.dart:

import 'package:flutter_test/flutter_test.dart';

void main() {
  test('Counter value should be incremented', () {
    int counter = 0;

    counter++;

    expect(counter, 1);
  });
}

When the pipeline is triggered, this test will run automatically.

Transform Your Flutter Project with Automated CI/CD

Step 4: Building APK and IPA for Deployment

To extend your pipeline to include building Android APKs or iOS IPAs, you can add steps to your GitHub Actions workflow:

- name: Build APK
run: flutter build apk --release

- name: Upload APK artifact
uses: actions/upload-artifact@v3
with:
  name: app-release.apk
  path: build/app/outputs/flutter-apk/app-release.apk

For iOS, you’ll need to set up a macOS runner, as iOS apps require Xcode:

jobs:
  build-ios:
    runs-on: macos-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: 'stable'

      - name: Install dependencies
        run: flutter pub get

      - name: Build IPA
        run: flutter build ios --release --no-codesign

Step 5: Deploying to Firebase or App Stores

You can automate the deployment of your app using tools like Fastlane or Firebase App Distribution.

For Firebase App Distribution, you can use the following configuration to integrate Firebase with your pipeline:

  1. Add Firebase CLI to your workflow and set up authentication.
  2. Deploy the APK or IPA to Firebase.

First, ensure you have the Firebase CLI token stored as a GitHub secret. You can generate the token by running Firebase login:ci.

Here’s an example of the extended pipeline to deploy your app to Firebase App Distribution:

- name: Install Firebase CLI
  run: npm install -g firebase-tools

- name: Deploy APK to Firebase
  run: firebase appdistribution:distribute build/app/outputs/flutter-apk/app-release.apk \
       --app "<firebase-app-id>" \
       --groups "<your-tester-group>" \
       --token ${{ secrets.FIREBASE_TOKEN }}

- name: Deploy IPA to Firebase
  if: runner.os == 'macOS'
  run: firebase appdistribution:distribute build/ios/ipa/app-release.ipa \
       --app "<firebase-app-id>" \
       --groups "<your-tester-group>" \
       --token ${{ secrets.FIREBASE_TOKEN }}

Make sure to replace the placeholder <firebase-app-id> with your actual Firebase app ID and <your-tester-group> with the group of testers for the app.

coma

Conclusion

Integrating CI/CD into your Flutter project offers significant advantages, including faster feedback loops, enhanced code quality, and more efficient deployments. By automating the build, test, and deployment processes, you can catch bugs earlier, ensure more stable releases, and reduce manual errors. This not only accelerates development but also leads to a more consistent app performance across platforms like Android and iOS.

In this tutorial, we walked through setting up GitHub Actions for a Flutter project, automating testing with Flutter, building APKs and IPAs, and deploying to Firebase. With these steps in place, you can streamline your development workflow and focus more on building features, knowing that your code is constantly being tested, built, and prepared for deployment.

Nandkishor S

Software Engineer

Nandkishor Shinde is a React Native Developer with 5+ years of experience. With a primary focus on emerging technologies like React Native and React.js. His expertise spans across the domains of Blockchain and e-commerce, where he has actively contributed and gained valuable insights. His passion for learning is evident as he always remains open to acquiring new knowledge and skills.

Keep Reading

Keep Reading

  • Service
  • Career
  • Let's create something together!

  • We’re looking for the best. Are you in?