injectCI function

Future<void> injectCI(
  1. String projectName
)

Implementation

Future<void> injectCI(String projectName) async {
  final ciDir =
  Directory(p.join(projectName, '.github', 'workflows'));
  ciDir.createSync(recursive: true);

  File(p.join(ciDir.path, 'flutter_ci.yml')).writeAsStringSync('''
name: Flutter CI

on:
  push:
    branches: [ main ]
  pull_request:

concurrency:
  group: flutter-ci-\${{ github.ref }}
  cancel-in-progress: true

jobs:

  android:
    runs-on: ubuntu-latest

    env:
      ANDROID_KEYSTORE_PASSWORD: \${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
      ANDROID_KEY_ALIAS: \${{ secrets.ANDROID_KEY_ALIAS }}
      ANDROID_KEY_PASSWORD: \${{ secrets.ANDROID_KEY_PASSWORD }}
      ANDROID_KEYSTORE_BASE64: \${{ secrets.ANDROID_KEYSTORE_BASE64 }}

    steps:
      - uses: actions/checkout@v4

      - name: Set up Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          channel: stable

      - name: Cache Pub
        uses: actions/cache@v4
        with:
          path: ~/.pub-cache
          key: pub-\${{ runner.os }}-\${{ hashFiles('**/pubspec.lock') }}

      - name: Cache Gradle
        uses: actions/cache@v4
        with:
          path: ~/.gradle
          key: gradle-\${{ runner.os }}-\${{ hashFiles('**/*.gradle*') }}

      - run: flutter pub get
      - run: flutter analyze

      # Optional Android Signing
      - name: Decode Keystore
        if: \${{ env.ANDROID_KEYSTORE_BASE64 != '' }}
        run: |
          echo "\$ANDROID_KEYSTORE_BASE64" | base64 -d > android/app/release.keystore

      - name: Build Dev APK
        run: flutter build apk --flavor dev -t lib/main_dev.dart --release

      - name: Upload Dev APK
        uses: actions/upload-artifact@v4
        with:
          name: android-dev-apk
          path: build/app/outputs/flutter-apk/*.apk

      - name: Build Prod AAB
        run: flutter build appbundle --flavor prod -t lib/main_prod.dart --release

      - name: Upload Prod AAB
        uses: actions/upload-artifact@v4
        with:
          name: android-prod-aab
          path: build/app/outputs/bundle/**/*.aab


  ios:
    runs-on: macos-latest

    env:
      APPLE_CERTIFICATE_BASE64: \${{ secrets.APPLE_CERTIFICATE_BASE64 }}
      APPLE_CERTIFICATE_PASSWORD: \${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
      APPLE_PROVISION_PROFILE_BASE64: \${{ secrets.APPLE_PROVISION_PROFILE_BASE64 }}

    steps:
      - uses: actions/checkout@v4

      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          channel: stable

      - run: flutter pub get

      # Optional iOS Signing
      - name: Install Certificate
        if: \${{ env.APPLE_CERTIFICATE_BASE64 != '' }}
        run: |
          echo "\$APPLE_CERTIFICATE_BASE64" | base64 -d > certificate.p12
          security create-keychain -p "" build.keychain
          security import certificate.p12 -k build.keychain -P "\$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
          security list-keychains -d user -s build.keychain
          security default-keychain -s build.keychain
          security unlock-keychain -p "" build.keychain
          security set-key-partition-list -S apple-tool:,apple: -s -k "" build.keychain

      - name: Install Provisioning Profile
        if: \${{ env.APPLE_PROVISION_PROFILE_BASE64 != '' }}
        run: |
          mkdir -p ~/Library/MobileDevice/Provisioning\\ Profiles
          echo "\$APPLE_PROVISION_PROFILE_BASE64" | base64 -d > ~/Library/MobileDevice/Provisioning\\ Profiles/profile.mobileprovision

      - name: Build Dev IPA
        run: |
          if [ -z "\$APPLE_CERTIFICATE_BASE64" ]; then
            flutter build ipa -t lib/main_dev.dart --release --no-codesign
          else
            flutter build ipa -t lib/main_dev.dart --release
          fi

      - name: Upload Dev IPA
        uses: actions/upload-artifact@v4
        with:
          name: ios-dev-ipa
          path: build/ios/ipa/*.ipa

      - name: Build Prod IPA
        run: |
          if [ -z "\$APPLE_CERTIFICATE_BASE64" ]; then
            flutter build ipa -t lib/main_prod.dart --release --no-codesign
          else
            flutter build ipa -t lib/main_prod.dart --release
          fi

      - name: Upload Prod IPA
        uses: actions/upload-artifact@v4
        with:
          name: ios-prod-ipa
          path: build/ios/ipa/*.ipa
''');

  print('✅ Enterprise GitHub CI injected successfully.');

}