0

Thank you for all the replies, I am still facing the issue, just to add more clarity I've given all the details of cloudbuild.yaml and build.gradle and key property details, please let me know if the configuration is correct and let me know how to fix the JKS issue.

I am working on integrating the CI\CD pipeline to a flutter project using GCP, which I am trying to store.JKS file in google secret manager and call it from inside the code, but it is giving an error saying secret env variable cannot be the non-UTF-8 format.

So I tried a couple of things,

  1. I tried to convert the.JKS file to txt viewable - after that it gave me an error saying secret env variable cannot have null values.

  2. I tried to store the JKS file in cloud storage - but the code is not able to get the content of the JKS even if I give the link and all the necessary permissions for cloud build.

Please suggest some fix or alternate storage area in GCP.

I am adding the code for more clarity. ------------------------------------------***-----------------------------------------

APPROACH 1: TRYING TO ACCESS JKS FILE FROM SECRET MANAGER

Secret Manager KEY VALUE structure

key                      value
KEYSTORE_PASSWORD       xxxxxxxxxxxx        
KEY_PASSWORD            xxxxxxxxxxxx
KEY_ALIAS               upload
JKS                     fe ed fe ed 00 00 00.....

build.sh

cd /workspace/$1
VERSION_NAME=$(git describe)
VERSION_CODE=$(git rev-list --count master)
flutter build apk --build-name=$VERSION_NAME --build-number=$VERSION_CODE


cloudbuild.yaml:

# Flutter CD configuration file with Cloud build

steps:

  # clone the latest source codes
  - name: 'gcr.io/cloud-builders/git'
    args: ['clone', 'https://XXXXX:ACCOUNT_PASSWORD@bitbucket.org/XXXXXXXX/XX.git']
    dir: '/workspace'

  # using flutter builder Docker image we have built previously to compile the repo
  - name: 'gcr.io/$PROJECT_ID/flutter'
    entrypoint: 'bash'
    args: [ 'build.sh']
    secretEnv: ['KEYSTORE_PASSWORD','KEY_PASSWORD', 'KEY_ALIAS', 'JKS']

  # Push the APK Output to your GCS Bucket with Short Commit SHA.
  - name: 'gcr.io/cloud-builders/gsutil'
    args: [ 'cp', 'build/app/outputs/flutter-apk/app-release.apk', 'gs://BUCKET_NAME' ]

availableSecrets:
  secretManager:
  - versionName: projects/xxxxxx/secrets/KEYSTORE_PASSWORD/versions/1
    env: 'KEYSTORE_PASSWORD'
  - versionName: projects/xxxxxxx/secrets/KEY_PASSWORD/versions/1
    env: 'KEY_PASSWORD'
  - versionName: projects/xxxxxx/secrets/KEY_ALIAS/versions/1
    env: 'KEY_ALIAS'
  - versionName: projects/xxxxxxx/secrets/upload-keystore-jks/versions/1
    env: 'JKS'

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"

android {
    compileSdkVersion flutter.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.XXX.XXX"
        minSdkVersion flutter.minSdkVersion
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    signingConfigs {
        release {
            keyAlias System.getenv("KEY_ALIAS")
            keyPassword System.getenv("KEY_PASSWORD")
            storePassword System.getenv("KEYSTORE_PASSWORD")
            storeFile System.getenv("JKS")
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }

}

flutter {
    source '../..'
}

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


ERROR
==============================================================================================================
build step 1 "gcr.io/buildtrial-1/flutter" failed: secret projects/xxxxxxx/secrets/upload-keystore-jks/versions/1 value is not valid UTF-8

==============================================================================================================

NOTE: 
1.build.gradle file is same for both the approches, as the JKS variable name is conssistent in both the approches
2. I've verified that, 'KEYSTORE_PASSWORD','KEY_PASSWORD', 'KEY_ALIAS' is working properly, only problem is with accessing JKS file in both the approches.

-------------------------------------------------------------------------**********-----------------------------------------------------------------------------------------------------------------------

APPROCH 2: TRYING TO ACCESS JKS FILE FROM CLOUD STORAGE.

cloudbuild.yaml:

# Flutter CD configuration file with Cloud build

steps:

  # clone the latest source codes
  - name: 'gcr.io/cloud-builders/git'
    args: ['clone', 'https://XXXXX:ACCOUNT_PASSWORD@bitbucket.org/XXXXXXXX/XX.git']
    dir: '/workspace'

  #accessing the JKS file stored in cloud storage through environment variable
  - name: 'gcr.io/cloud-builders/gsutil'
    env:
      - 'JKS=gs://BUCKET_NAME/KEYSTORE.jks'

  # using flutter builder Docker image we have built previously to compile the repo
  - name: 'gcr.io/$PROJECT_ID/flutter'
    entrypoint: 'bash'
    args: [ 'build.sh']
    secretEnv: ['KEYSTORE_PASSWORD','KEY_PASSWORD', 'KEY_ALIAS']

  # Push the APK Output to your GCS Bucket with Short Commit SHA.
  - name: 'gcr.io/cloud-builders/gsutil'
    args: [ 'cp', 'build/app/outputs/flutter-apk/app-release.apk', 'gs://BUCKET_NAME' ]

availableSecrets:
  secretManager:
  - versionName: projects/xxxxxx/secrets/KEYSTORE_PASSWORD/versions/1
    env: 'KEYSTORE_PASSWORD'
  - versionName: projects/xxxxxxx/secrets/KEY_PASSWORD/versions/1
    env: 'KEY_PASSWORD'
  - versionName: projects/xxxxxx/secrets/KEY_ALIAS/versions/1
    env: 'KEY_ALIAS'

============================================================================= ERROR

Step #2: Execution failed for task ':app:validateSigningRelease'.
Step #2: > Keystore file not set for signing config release

=============================================================================

  • It seems that JKS is a binary format so it has to be stored in binary. It feels like you have to extract the JKS to a "local file" where it can be used. Can you elaborate on how the your are building your application from source and where the JKS file is expected to be found? – Kolban Feb 12 '22 at 17:05
  • thank you for the reply. I've attached the details, please take a look and suggest a fix. – RAHUL BHARADWAJ Feb 14 '22 at 08:33
  • Can you also share the JKS related part in your build.sh file? The first approach could work, the second not (I will explain later in an update of my answer) – guillaume blaquiere Feb 14 '22 at 14:19
  • I have added build.sh above, but I haven't written anything for the JKS file in build.sh. should I add something? please specify if any. – RAHUL BHARADWAJ Feb 14 '22 at 15:00

1 Answers1

0

When you have binary files, you have to convert them in base64 and then to store them encoded.

In your application, read the base64 content of Secret Manager, decode it, and use it.

guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • thank you for the reply. I've attached the details, please take a look and suggest a fix. – RAHUL BHARADWAJ Feb 14 '22 at 08:34
  • The problem still exists, can you please give more context on how to implement the solution you have mentioned. The solution given in this document https://cloud.google.com/build/docs/securing-builds/use-secrets for non-utf 8, I tried to implement this but I couldn't, more information on the implementation is really appreciated. – RAHUL BHARADWAJ Apr 27 '22 at 08:29