The Android Signing plugin provides a simple build step for signing Android APK build artifacts. The advantage of this plugin is that you can use Jenkins to centrally manage, protect, and provide all of your Android release signing certificates without the need to distribute private keys and passwords to every developer. This is especially useful in multi-node/cloud environments so you do not need to copy the signing keystore to every Jenkins node. Furthermore, using this plugin externalizes your keystore and private key passwords from your build script, and keeps them encrypted rather than storing them in a plain-text properties file. This plugin also does not use a shell command to perform the signing, eliminating the potential that private key passwords appear on a command-line invocation.
This version is a fork from Big Nerd Ranch's now deprecated original repository which is the basis of a nice blog post, Continuous Delivery for Android. Thanks to Big Nerd Ranch for the original work.
This plugin depends on the Jenkins Credentials Plugin for retrieving private key credentials for signing APKs. Thanks to CloudBees and Stephen Connolly for the Credentials Plugin.
This plugin also depends on Android's apksig
library to sign APKs programmatically. apksig
backs the apksigner
utility in the Android SDK Developer Tools package. Using apksig
ensures the signed APKs
this plugin produces comply with the newer
APK Signature Scheme v2.
Thanks to Google/Android for making that library available as a
Maven dependency.
Run mvn package
to build a deployable HPI bundle for Jenkins. Note this plugin
REQUIRES JDK 1.8 to build and run because of the dependency on the Android apksig
library.
First, make sure your Jenkins instance has the Credentials Plugin (linked above).
Check the POM for version requirements. Copy the target/android-signing.hpi
plugin bundle to $JENKINS_HOME/plugins/
directory, and restart Jenkins.
As of this writing, this plugin is not yet hosted in the Jenkins Update Centre, so you cannot install using the Jenkins UI.
Before adding a Sign APKs build step to a job, you must configure a certificate credential using the Credentials Plugin's UI. As of this writing, this plugin requires a password-protected PKCS12 keystore containing a single private key entry protected by the same password. This will probably change in a future version to allow password-free keys or keys with separate passwords.
This plugin will attempt to find the Android SDK's
zipalign
by way of the ANDROID_HOME
environment variable. It searches for the latest
version of the build-tools
package installed in your SDK. Alternatively,
you can set the overriding ANDROID_ZIPALIGN
environment variable to the path
of the zipalign
executable you prefer, e.g.,
${ANDROID_HOME}/build-tools/25.0.2/zipalign
(don't forget .exe
for Windows).
This therefore implies that whatever Jenkins node is performing the build has
access to an installed Android SDK, which is likely the case if you built your
APK in a Jenkins job as well.
Once the prerequisites are setup, you can now add the Sign APKs build step to
a job. The configuration UI is fairly straight forward. Select the certificate
credential you created previously, supply the alias of the private key/certificate
chain, and finally supply the name or Ant-style glob
pattern specifying the APK files relative to the job workspace you want to sign.
You can specify multiple glob patterns separated by commas if you wish. For most
projects **/*-unsigned.apk
should suffice.
Note that this plugin assumes your Android build has produced an unsigned,
unaligned APK. If you are using the Gradle Android plugin to build your APK,
that means a previous Jenkins build step probably invoked the assembleRelease
task on your build script and there were no signingConfig
blocks that applied
to your APK. In that case Gradle will have produced the necessary unsigned,
unaligned APK, ready for the Android Signing Plugin to sign. Your unsigned
APK will then likely have the standard -unsigned.apk
suffix, in which case the
plugin will replace the -unsigned
component with -signed
on the output APK.
Otherwise, the plugin will just insert -signed
before .apk
in the unsigned
APK name.
Currently, all signed APKs for a single Sign APKs build step go in a workspace
directory named like SignApksBuilder-out/my-app-unsigned.apk/my-app-signed.apk
,
where my-app-unsigned.apk
is a directory named after the unsigned input APK.
This is to avoid multiple signing steps in a single job overwriting each other's
output APKs, and multiple APKs matched within a signing step colliding. It's
clearly not fool-proof, however, so be mindful if you are signing multple APKs
in a single job and/or signing step. If you are using the plugin's
Archive Signed APKs and/or Archive Unsigned APKs option, the plugin
places the appropriate artifacts under the SignApksBuilder-out/my-app-unsigned.apk/
directory in the build's archive.
Here is an example of signing APKs from a Pipeline script:
node {
// ... steps to build unsigned APK ...
signAndroidApks (
keyStoreId: "myApp.signerKeyStore",
keyAlias: "myTeam",
apksToSign: "**/*-unsigned.apk"
// you can override these within the script if necessary
// androidHome: env.ANDROID_HOME
// zipalignPath: env.ANDROID_ZIPALIGN
)
}
Like the Free Style Job build step described above, the Pipeline step will attempt
to use ANDROID_ZIPALIGN
and ANDROID_HOME
, in that priority order, from the
Jenkins environment variables. Note the wrapping
node
context; this plugin assumes the Pipeline step will have a workspace available.
This plugin offers a Job DSL extension.
You can include a Sign APKs build step in the steps
context of a Job DSL script:
freeStyleJob('myApp.seed') {
scm {
git 'git://github.com/mygithub/myApp.git', 'master', {
extensions {
relativeTragetDirectory 'myApp'
}
}
}
steps {
gradle {
rootBuildScriptDir 'myApp'
useWrapper true
tasks 'clean assembleRelease'
}
signAndroidApks '**/myApp-unsigned.apk', {
keyStoreId 'myApp.keyStore'
keyAlias 'myAppKey'
archiveSignedApks true
archiveUnsignedApks true
androidHome '/opt/android-sdk'
}
}
}
The availble options are analogous to those in the build step configuration web UI.
Please submit all issues to Jenkins Jira. Do not use GitHub issues.
See the Android Signing page on the Jenkins.io site.
See the included LICENSE and NOTICE text files for original Work and Derivative Work copyright and license information.