This guide will walk you through setting up GitHub Actions for a Flutter project, from initializing a CI/CD pipeline to securely managing secrets for builds and deployments.

1. Prerequisites

Before setting up GitHub Actions for CI/CD in Flutter, ensure you have:

2. Setting Up GitHub Actions in a Flutter Project

GitHub Actions uses workflow YAML files stored in .github/workflows/.

2.1. Creating a Workflow File

  1. In your Flutter project's root directory, create a .github/workflows folder.
  2. Inside the folder, create a CI/CD workflow file:
mkdir -p .github/workflows
touch .github/workflows/flutter-ci.yml

  1. Open flutter-ci.yml and define a basic workflow:
name: Flutter Build Apk

on:
  push:
    branches:
      - main
      - development

jobs:
  build--eventmania-sales-apk:
    name: Flutter Build APK
    runs-on: macos-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - run: java --version

      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          channel: stable
          flutter-version: 3.27.3
          cache: true
          cache-key: "eventmania-sales-sdk-key"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
          pub-cache-key: "eventmania-sales-pub-cache-key"
          pub-cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
      - run: flutter --version

      # Create .env.dev file
      - name: Create .env.dev file
        run: |
          cat <<EOT >> .env.dev
          ENV=Development
          BASE_API_URL=${{ secrets.BASE_API_URL_DEV }}
          ONE_SIGNAL_ID=${{ secrets.ONE_SIGNAL_ID }}
          SEATS_IO_KEY=${{ secrets.SEATS_IO_KEY }}
          EOT

      # Create .env.prod file
      - name: Create .env.prod file
        run: |
          cat <<EOT >> .env.prod
          ENV=Production
          BASE_API_URL=${{ secrets.BASE_API_URL_PROD }}
          ONE_SIGNAL_ID=${{ secrets.ONE_SIGNAL_ID }}
          SEATS_IO_KEY=${{ secrets.SEATS_IO_KEY }}
          EOT

      #5 Setup Keystore
      - name: Decode Keystore
        run: |
          echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/keystore.jks

      - name: Create key.properties
        run: |
          echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" > android/key.properties
          echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties
          echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> android/key.properties
          echo "storeFile=keystore.jks" >> android/key.properties

      # Create/modify local.properties
      - name: Create local.properties for Dev
        run: |
          echo "flutter.sdk=/path/to/flutter" >> android/local.properties
          echo "flutter.versionCode=1" >> android/local.properties
          echo "flutter.versionName=1.0" >> android/local.properties

      # Install melos
      - name: Install melos
        run: dart pub global activate melos

      # Setup melos to resolve dependencies
      - name: Setup melos
        run: melos bs

      # Generate routes and environment variables
      - name: Generate routes and environment variables
        run: melos run build-runner

      # Generate localization keys
      - name: Run Localisation Key Generation
        run: melos run locale-gen

      # Generate assets
      - name: Run Asset generation
        run: melos run asset-gen

      # Build Android aab for prod flavor
      - name: Build Android aab For Production
        run: melos run build-aab-prod

      # Build Android apk for prod flavor
      #- name: Build Android apk For Dev
      #  run: melos run build-apk-dev

      # Upload the built APK artifact
      - name: Upload the build Artifact
        uses: actions/upload-artifact@v4
        with:
          name: app-release
          path: build/app/outputs/bundle/release/app-release.aab

This workflow:

✅ Runs on code pushes and pull requests to the main & development branch.

✅ Checks out the repository.

✅ Installs Flutter.

✅ Creates .env(s).

✅ Setups key.properties & creates local.properties