Setting Up Continuous Integration (CI/CD) for Flutter Apps

Continuous Integration and Continuous Deployment (CI/CD) are essential practices in modern software development. They enable faster release cycles, reduced risk of errors, and increased team collaboration. For Flutter apps, implementing CI/CD pipelines can automate building, testing, and deploying your application across multiple platforms.

What is CI/CD?

Continuous Integration (CI) is the practice of frequently integrating code changes from multiple developers into a central repository. Automated builds and tests are run to ensure the code changes don’t introduce errors.

Continuous Deployment (CD) extends CI by automatically deploying code changes to production or staging environments after they have passed the CI tests. This ensures that new features and bug fixes are delivered to users quickly and reliably.

Benefits of CI/CD for Flutter Apps

  • Automation: Automate the build, test, and deployment process.
  • Faster Release Cycles: Deliver updates to users more quickly.
  • Reduced Errors: Catch issues early through automated testing.
  • Improved Collaboration: Seamless integration of code from multiple developers.
  • Consistent Builds: Ensure reproducible and reliable builds.

Tools for CI/CD with Flutter

Several tools can be used to implement CI/CD for Flutter apps. Here are some popular options:

  • Codemagic: A CI/CD platform specifically designed for Flutter apps.
  • GitHub Actions: A flexible and powerful CI/CD service integrated with GitHub.
  • Bitrise: A mobile-focused CI/CD platform.
  • Jenkins: An open-source automation server that can be configured for CI/CD.
  • GitLab CI: Integrated CI/CD service within GitLab.

Setting Up CI/CD with Codemagic

Codemagic is a popular choice for Flutter CI/CD due to its ease of use and Flutter-specific features.

Step 1: Create a Codemagic Account

Sign up for a Codemagic account at Codemagic.io and connect it to your repository (e.g., GitHub, GitLab, Bitbucket).

Step 2: Create a New Application

In Codemagic, create a new application and select your Flutter project repository.

Step 3: Configure Build Settings

Configure the build settings for your Flutter app, including:

  • Branch to build: Specify the branch that triggers the build (e.g., main or develop).
  • Flutter version: Select the Flutter SDK version to use.
  • Build mode: Choose the build mode (e.g., debug, profile, release).
  • Target platform: Specify the target platform (e.g., Android, iOS, Web).

workflows:
  android-workflow:
    name: Android Workflow
    instance_type: mac_mini_m1
    max_build_duration: 120
    environment:
      flutter: stable
      android_sdk: '33'
    scripts:
      - name: Get Flutter dependencies
        script: |
          flutter pub get
      - name: Run tests
        script: |
          flutter test
      - name: Build Android APK
        script: |
          flutter build apk --release --split-per-abi
    artifacts:
      - build/app/outputs/apk/release/*.apk

Step 4: Configure Code Signing (for iOS)

For iOS builds, configure code signing using:

  • Automatic code signing: Codemagic manages the certificates and profiles.
  • Manual code signing: You provide the necessary certificates and profiles.

Step 5: Configure Publishing

Configure publishing options to deploy your app to:

  • Google Play Store: Upload the APK or AAB to the Play Store.
  • App Store Connect: Upload the IPA to the App Store Connect.
  • TestFlight: Distribute the app to beta testers through TestFlight.

publish:
  google_play:
    credentials: $GPLAY_JSON_KEY_PATH
    track: internal
    release_name: Release $BUILD_NUMBER
    whats_new: whats_new.txt

Step 6: Run Your First Build

Trigger your first build and monitor the process in the Codemagic dashboard. Ensure that the build, tests, and publishing steps are successful.

Setting Up CI/CD with GitHub Actions

GitHub Actions allows you to automate your software development workflows directly in your GitHub repository.

Step 1: Create a GitHub Repository

Ensure your Flutter project is hosted on a GitHub repository.

Step 2: Create a Workflow File

Create a new workflow file in the .github/workflows directory of your repository. For example, .github/workflows/flutter_ci_cd.yml.

Step 3: Define the Workflow

Define the CI/CD workflow in the YAML file. Here’s an example for building and testing a Flutter app:


name: Flutter CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: '11'
      - uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.0.0'
      - run: flutter pub get
      - run: flutter analyze
      - run: flutter test
      - run: flutter build apk --split-per-abi
        if: runner.os == 'Linux'
      - uses: actions/upload-artifact@v3
        with:
          name: apk
          path: build/app/outputs/apk/release

In this workflow:

  • The workflow is triggered on push and pull_request events on the main branch.
  • It runs on an Ubuntu virtual machine.
  • It checks out the code, sets up Java and Flutter, gets Flutter dependencies, analyzes the code, runs tests, and builds an APK.
  • Finally, it uploads the APK as an artifact.

Step 4: Configure Publishing (Optional)

You can add additional steps to publish the app to the Google Play Store or App Store Connect using appropriate actions or scripts.

For example, to publish to the Google Play Store, you can use the google-github-actions/deploy-serviceaccount action:


      - name: Deploy to Play Store
        uses: google-github-actions/deploy-serviceaccount@v0
        with:
          service_account_key_json_path: ${{{ secrets.PLAY_STORE_CREDENTIALS }}}
          package_name: com.example.myapp
          release_files: build/app/outputs/apk/release/app-release.apk
          track: production

Make sure to configure the necessary secrets in your GitHub repository settings.

Best Practices for CI/CD with Flutter

  • Automated Testing: Write comprehensive unit and integration tests to ensure code quality.
  • Code Analysis: Use static analysis tools like flutter analyze to catch potential issues.
  • Environment Variables: Manage sensitive information like API keys and credentials using environment variables.
  • Artifact Management: Store build artifacts for future reference and debugging.
  • Notifications: Set up notifications to receive alerts for build failures or successful deployments.
  • Infrastructure as Code (IaC): Define your CI/CD infrastructure using code for consistency and reproducibility.

Conclusion

Setting up CI/CD for Flutter apps is crucial for automating the build, test, and deployment process, leading to faster release cycles, reduced errors, and improved team collaboration. Whether you choose Codemagic, GitHub Actions, or another CI/CD tool, following best practices ensures a reliable and efficient CI/CD pipeline for your Flutter projects.