FlutterFlow | Codemagic CI with Google Play Store
Published: 2022-05-03 12:00:37

**TL:DR :) 

Setting up a Flutter project**

**Files preparation**

Before listing our app on Codemagic we shoul prepare our project for the delivery. Here's my "build.gradle" file with the complete code.

`Path: ../android/app/build.gradle`

`def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'  // Google Services plugin

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    compileSdkVersion 31
    ndkVersion '23.1.7779620'
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.flutterflow.foodshare"
                    minSdkVersion 21
        targetSdkVersion 31
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
                   ndk {
                           debugSymbolLevel 'FULL'
                  }
    }
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
   
    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.release
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}`


Acording to our delivering build we have to increase our "version: 1.0.0+1" build in root folder of our project "../pubspec.yaml". The second build is going to be "version: 1.0.0+2" and so on and so forth.

`Path: ../pubspec.yaml`

`...
 version: 1.0.0+13
...`


**Version inconsistency between local and Codemagic**

First, you need to make sure that the gradlew file isn’t in ".gitignore". Look for "../android/gradlew", and if it’s in ".gitignore", delete it from there. I simply commented two lines. Then add "!gradle-wrapper.jar" to a new line in ".gitignore" to create an exception so that "gradle-wrapper.jar" would also be excluded from ".gitignore".

`Path: "../android/.gitignore"`

`gradle-wrapper.jar
!gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
# /gradlew
# /gradlew.bat

/local.properties
GeneratedPluginRegistrant.java`


Change "distributionUrl" to version "7.2"  in "../android/gradle/wrapper/gradle-wrapper.properties"

`Path: ../android/gradle/wrapper/gradle-wrapper.properties`

`distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists`

In our case, run "./gradlew wrapper --gradle-version 7.2" inside "../android" locally to create gradlew and gradle-wrapper.properties files in your repository.

**Change icons**

A bit annoyng part for me is changing icons in a few folders. Otherwise we will see the default flutter icon on installed app. Hopefully it will be fixed soon by FlutterFlow team :) 

Following path "../android/app/src/main/res" and directories within it: 

- ../android/app/src/main/res/mipmap-hdpi
- ../android/app/src/main/res/mipmap-mdpi
- ../android/app/src/main/res/mipmap-xhdpi
- ../android/app/src/main/res/mipmap-xxhdpi
- ../android/app/src/main/res/mipmap-xxxhdpi

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cp85d9c3e38zvy75dcr9.png)

For toasting those icons I've been using online tools. Not sure which platforms in particular. Here's a few anyway :)

- https://romannurik.github.io/AndroidAssetStudio/
- https://appicon.co/
- https://makeappicon.com/


**Codemagic configuration**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p3olbjx8vkbirw3f0su.png)

I'll just simply share my configuration to make things way easier 🙂

**Build for platforms**

- Android
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rvn2mj6aurgv1bayc4h.png)

**Run build on**

- Free - macOS Standard VM (2.3GHz Quad Core / 8GB)
- No "Build triggers"
- No "Environment variables"
- No "Dependency caching"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlldt5srnyak6g6et3in.png)

**Add custom settings**
- No "Post-clone script"
- No "Pre-test script"

**Tests**
- No tests are covered yet

**Add custom settings for post-tests **
- No "Post-test script"
- No "Pre-build script"

**Build**
In my case I changed a few settings:
- Flutter version: channel Beta
- Mode: release

**Add custom settings for post-build scripts **
- No "Post-build script"

**Distribution**

**Enable Android code signing. **
Was covered in [Build and release an Android app to Google Play Store](https://dev.to/organicnz/build-and-release-an-android-app-to-google-play-store-555g).
- Keystore*: upload keystore
- Keystore password: add keystore password
- Key alias: upload
- Key password: add key password


**Enable Google Play publishing**
- Add "Credentials (.json)*" key. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/woaov8ktycbkuiaprylc.png)

If you don't have the json key or file is corrupted you should  generated it on "[Google Cloud Platform](https://console.cloud.google.com/iam-admin/serviceaccounts/details/111665568618235174091/permissions?project=your-project)" at "IAM & Admin" section and "Service accounts".

Press "Create Service Account". Here's my overview. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrq1qji2vp9bvxgk4tpy.png)

 Add the service account name and click "Done".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bniu9y2kqovzdyx7vjp3.png)

Grant this service account access to project:

- Cloud Build Editor
- Firebase Service Management Service Agent 
- Service Account Token Creator
- Service Account User 

Finalise it - click "Done".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7n6v55r7au8suqiv8e4.png)

Create new or add JSON key in key category. For my project I added a new key. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47s9wptpc2rq3lgtvrw8.png)

Generated and added key should look like this.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbvpb06idyam03uuqlmi.png)

**Firebase App Distribution**
- Disabled

**Notifications**
- Enable email publishing and add your email.
- Slack is disabled.

**Post-publish script**
- No any script


Configs in yaml format
Here's the complete config codemagic.yaml file 
Track: internal 

`# Automatically generated on 2021-11-13 UTC from https://codemagic.io/app/6179aca0a05d5e8795c3cfa0/settings
# Note that this configuration is not an exact match to UI settings. Review and adjust as necessary.

workflows:
  default-workflow:
    name: Default Workflow
    max_build_duration: 30
    environment:
      vars:
        FCI_KEYSTORE_PATH: /tmp/keystore.keystore
        FCI_KEYSTORE: Encrypted(Z0FBQUF...2TGxYYVBBPT0=)
        FCI_KEYSTORE_PASSWORD: Encrypted(Z0FBQUF...g0Ni1xVlE9PQ==)
        FCI_KEY_PASSWORD: Encrypted(Z0FBQUFB...FMZHc9PQ==)
        FCI_KEY_ALIAS: Encrypted(Z0FBQUF...ZWWQ5aWc9PQ==)
      flutter: beta
      xcode: latest
      cocoapods: default
    scripts:
      - |
        # set up key.properties
        echo $FCI_KEYSTORE | base64 --decode > $FCI_KEYSTORE_PATH
        cat >> "$FCI_BUILD_DIR/android/key.properties" <<EOF
        storePassword=$FCI_KEYSTORE_PASSWORD
        keyPassword=$FCI_KEY_PASSWORD
        keyAlias=$FCI_KEY_ALIAS
        storeFile=/tmp/keystore.keystore
        EOF
      - |
        # set up local properties
        echo "flutter.sdk=$HOME/programs/flutter" > "$FCI_BUILD_DIR/android/local.properties"
      - flutter packages pub get
      - flutter build appbundle --release
    artifacts:
      - build/**/outputs/apk/**/*.apk
      - build/**/outputs/bundle/**/*.aab
      - build/**/outputs/**/mapping.txt
      - flutter_drive.log
    publishing:
      email:
        recipients:
          - tamerlanium@gmail.com
      google_play:
        credentials: Encrypted(Z0FBQUF...VNUdUMU09)
        track: internal
        in_app_update_priority: 0`

**Last step**
Run following "flutter clean" command on terminal and commit the changes then rerun your Codemagic build.    

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o61d057d0uzfghz8yvmk.png)


**Troubleshooting**

**Error caused by dependencies or could be something else**
If you encounter an error with dependencies pls try out to clean your project through the terminal:

`sudo flutter clean && sudo rm ios/Podfile && sudo rm ios/Podfile.lock pubspec.lock && sudo rm -rf ios/Pods ios/Runner.xcworkspace && sudo rm -Rf ios/.symlinks && sudo rm -Rf ios/Flutter/Flutter.framework && sudo rm -Rf ios/Flutter/Flutter.podspec`

and

`flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs`

then once again commit the changes and rerun your Codemagic build. 

That should help you to set up the CI/CD pipeline :)   

Thank you :)  

 
 
 
﻿