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!
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
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:
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.
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
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.
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With