1

I'm trying to build signed apk with gitlab ci but i got this error:

/bin/bash: line 109: -Pandroid.injected.signing.store.file=/builds/MyGitlab/myapp/release.jks: 
No such file or directory

I add variables KEYSTORE_FILE, KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD with values in gitlab ci/cd variable. I'm used base64 encoding of my keystore file. My .gitlab-ci.yml file is as below:

image: jangrewe/gitlab-ci-android

before_script:
  - export GRADLE_USER_HOME=$(pwd)/.gradle
  - chmod +x ./gradlew

cache:
  key: ${CI_PROJECT_ID}
  paths:
    - .gradle/

stages:
  - release

assembleRelease:
  stage: release
  script:
    - echo -n %KEYSTORE_FILE% | base64 -di > release.jks
    - >
      ./gradlew assembleRelease --stacktrace
        -Pandroid.injected.signing.store.file=$(pwd)/release.jks
        -Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD
        -Pandroid.injected.signing.key.alias=$KEY_ALIAS
        -Pandroid.injected.signing.key.password=$KEY_PASSWORD
  artifacts:
    paths:
      - app/build/outputs/apk/dev/release
      - app/build/outputs/apk/prod/release

Do you have any idea to resolve this issue? Similar question exist but I got different error.

Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45

1 Answers1

2

We shouldn’t store keystore file and credentials in version control system. We can hide credentials with creating keystore.properties file and using credentials from this file in signing config part like this:

def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
    ...

    signingConfigs {
        release {
            keyAlias keystoreProperties['releaseKeyAlias']
            keyPassword keystoreProperties['releaseKeyPassword']
            storeFile file(rootDir.getCanonicalPath() + '/' + keystoreProperties['releaseKeyStore'])
            storePassword keystoreProperties['releaseStorePassword']
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }

    ...
}

keystore.properties contains keystore credentials:

releaseKeyAlias=Prod
releaseKeyPassword=12345678
releaseKeyStore=release.keystore.jks
releaseStorePassword=12345678

In the siging config, release.keystore.jks keystore file is used but we will not store it the vcs. So, we need to generate keystore file before building android application in continuous integration.

Developer has keystore file and app signing keys that are visible in build.gradle. I’ve use this solution to secure our keystore file:

Store encrypted keystore file in version control system:

First, create a secret key for yourself:

openssl enc -aes-256-cbc -k ciappsigningexample-secret -P -md sha1

It generates salt, key and iv. We’ll use 256-bit secret key. Then, encrypt your keystore file with your 256-bit secret key:

openssl aes-256-cbc -e -in debug.keystore.jks -out debug.keystore.jks.encrypted -k 99924EB44...

It will generate debug.keystore.jks.encrypted file and you can push this file to git. To decrypt your encrypted keystore in CI, you need to add your 256-bit secret key to CI as an environment. Then you can decrypt keystore file with using this secret key in pre-build step with following command:

openssl aes-256-cbc -d -in debug.keystore.jks.encrypted -k $DEBUG_ENCRYPT_SECRET_KEY >> debug.keystore.jks
Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45