Signing android application releases
Android signing plugin can be used to sign android application releases in pipeline. Certificate has to be added in Jenkins credentials for this purpose.
The precondition is to have the proper keystore (which key should be used to sign app) within jenkins credentials.
Using certificate in pipeline
Following snippet is example from alcosystems ibac project:
SigningStep
step([$class: 'SignApksBuilder', apksToSign: "**/*-unsigned*.apk", keyAlias: 'alcosystems', keyStoreId: 'alcosystems-ibac_androidProdKeystore', zipalignPath: "${ANDROID_HOME}/build-tools/26.0.2/zipalign"])
class - plugin class for signing, do not change
apksToSign - path to unsigned apk
keyAlias - alias of the key within keystore used for the signing
keyStoreId - id of the credential in Jenkins
zipalignPath - path to zipalign tool (having ANDROID_HOME set to android SDK is not enough)
Signed artifact is archived automatically by default. It can be changed by plugin properties.
See Android signing plugin for further options.
Signing android application bundle (.aab format)
Google is deprecating usage of standalone apk for uploading the application to google play. Instead the android application bundle will be mandatory.
Till jenkins signApksBuilder plugin does not support signing of such format, there is still possibility to use jarsigner directly, just the keystore has to be injected into pipeline with all its credentials:
Signing android application bundle
withCredentials([certificate(aliasVariable: 'alias', credentialsId: 'dokoki-bsg_androidMobileReleaseKeystore', keystoreVariable: 'keystore', passwordVariable: 'password')]) {
sh "zip -d ${buildPath} META-INF/* *"
sh "jarsigner -verbose -storetype pkcs12 -sigalg SHA256withRSA -digestalg SHA-256 -keystore $keystore -storepass $password ${filePath} key0"
}
credentialsId - the id of the keystore within jenkins credentials. In the example the dokoki project keystore is used
keystoreVariable - name of the keystore
passwordVariable - keystore password
filePath - not related to withCredentials, it is the path to the file which should be signed
Deletion of the META-INF folder is executed for the cases when e.g. gradle already signed the build and we need to override.
Possible errors
Following exceptions were observed in past due to certain bugs in version of java used for keystore generation:
jarsigner error: java.lang.RuntimeException: keystore load: Integrity check failed: java.security.UnrecoverableKeyException: Failed PKCS12 integrity checking
jarsigner error: java.lang.RuntimeException: keystore load: Integrity check failed: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available
The solution was to re-generate p12 keystore (from jks or completely new one) within different version of java, e.g. java-1.11.0-openjdk-amd64 was used in successful scenario.