Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to store Android KeyStore file for CirlceCi build?

I am trying to configure continuous integration build for my Android app. I use CircleCi platform for it. Now I store my apps Keystore.jks file locally, but CircleCi needs it to sign my app. How can I achieve that without storing the file on my git repository? Or maybe I shouldn't be concerned about that while the repository is private?

My gradle signing configs:

signingConfigs {
    if (System.getenv("CIRCLECI")) {
        release {
            keyAlias '****'
            keyPassword '****'
            storeFile file(System.getenv("******"))
            storePassword '****'
        }
    }else{
        release {
             ...
        }
    }
}

My circle.yml :

general:
    artifacts:
        - /home/ubuntu/my-app/app/build/outputs/apk/
machine:
  environment:
    ANDROID_HOME: /usr/local/android-sdk-linux
dependencies:
  override:
     - chmod +x gradlew
test:
  override:
    - ./gradlew assemble

I tried to save the keystore file on CircleCi as environmental variable but it isn't working, my build fails with exception:

> Execution failed for task ':app:validateSigningDemoRelease'.
> > Keystore file /home/ubuntu/my-app/app/  HERE_IS_THE_KEYSTORE not found for signing config 'release'.

Unsigned and debug builds finish with success.

I'm also open to use any different ci platform if you suggest something else.

Thanks in advance for every advice!

like image 481
bleo Avatar asked Jul 04 '17 17:07

bleo


3 Answers

I struggled with this problem recently and decided that the easiest solution was to encode the keystore file to base64 and put it into an environment variable at CircleCI.

This will encode the file and you can copy and paste the value across:

openssl base64 -A -in .signing/release.jks 

Then, in your config.yml file at CircleCI, decode it back:

echo $RELEASE_KEYSTORE_BASE64 | base64 -d > .signing/release.jks
like image 72
grepx Avatar answered Oct 17 '22 16:10

grepx


if statement does not work in signingConfigs. If you want to sign apk with different keystore for different flavors, you need to create signingConfigs and put signingconfigs into buildTypes section. I did some research about where to store android keystore file in CI/CD Cycle and I come up with three approaches:

  1. Encode keystore file as an environment variable

    As @grepx's answer, convert keystore file to base-64 encoded string and save it as an environment variable in CI tools.

  2. Store encrypted keystore file in version control system

    Encrypt keystore file and store it in version control system. You can encrypt file with:

    openssl aes-256-cbc -e -in keystore.jks -out keystore.jks.encrypted -k SECRET_KEY

    You need to decrypt that encrypted keystore file in build step in CI tools:

    openssl aes-256-cbc -d -in keystore.jks.encrypted -k $ENCRYPT_SECRET_KEY >> keystore.jks

    SECRET_KEY is stored as an environment variable in CI with this key: $ENCRYPT_SECRET_KEY

  3. Download keystore from external source like AWS S3, Google Drive

I've published an article about this topic in medium and you can reach complete example in github to understand better.

like image 21
farukcankaya Avatar answered Oct 17 '22 16:10

farukcankaya


For me you have two solutions:

  • It's a private depot and you're the only one using it, so you can push your key.

  • My preferred solution would be to create another key that you call circleCI (for example) and that you push. Personally I use this solution

My build.gradle

signingConfigs {
        Keys {
            keyAlias 'mykey'
            storeFile file('../private_key/upload_key.jks')
            keyPassword ''
            storePassword ''
        }

        Circleci {
            keyAlias 'key'
            storeFile file('../private_key/debug_key.jks')
            keyPassword ''
            storePassword ''
        }
    }
buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
            signingConfig signingConfigs.Keys
        }
        debug {
            signingConfig signingConfigs.Keys
        }
        circleci{
            signingConfig signingConfigs.Circleci
        }
    }
like image 3
filol Avatar answered Oct 17 '22 15:10

filol