FlutterFlow | Codemagic CI with Google Play Store

organicnz

Tarlan Isaev 🍓

Posted on May 3, 2022

FlutterFlow | Codemagic CI with Google Play Store

**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
    }
}
Enter fullscreen mode Exit fullscreen mode

}

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

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

Codemagic configuration

Image description

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

Build for platforms

  • Android Image description

Run build on

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

Image description

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.

  • 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

If you don't have the json key or file is corrupted you should generated it on "Google Cloud Platform" at "IAM & Admin" section and "Service accounts".

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

Image description

Add the service account name and click "Done".
Image description

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

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

Image description

Generated and added key should look like this.

Image description

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" < 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

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 :)



💖 💪 🙅 🚩
organicnz
Tarlan Isaev 🍓

Posted on May 3, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related