Sonntag, 27. Oktober 2013

Signing Maven artifacts on Cloudbees

Recently I set up the build infrastructure for our avacodo library. With Github, Cloudbees and Maven Central it has become surprisingly easy to get your code from your fingertips into everybody's hands quickly and reliably. There is however one obstacle that can be a bit tricky to get right: Signing artifacts on your Cloudbees hosted Jenkins server.

Maven Central requires all uploaded artifacts to be signed. Of course, you want to do this with a click of a button on your Jenkins server. I'm assuming that your pom.xml inherits from Sonatype's oss-parent, which has all the necessary configuration for doing releases to the Central repository. I will also assume that you are familiar with how to create gpg keys and that you have published your public key to sks.keyserver.net. So you should be able to do a Maven release on your development machine and a "mvn clean install" on your Jenkins.

First, you need to export your public and private key pair. The resulting files should be named pubring.gpg and secring.gpg.
gpg --export key-id > pubring.gpg
gpg --export-secret-key key-id > secring.gpg
Upload these into your private repository at Cloudbees. Just follow the tutorial on how to share files with build agents. I will use a subdirectory named "gpg" for this. You also need a trustdb.gpg and random_seed file, which - as far as I can tell - can just be empty. They are not needed for signing, but gpg will look for them anyway. You also need a file named gpg.conf with the following line:
lock-never
This tells gpg to never try to lock the key database. This is important because your private repository is mounted read-only during the build.


Finally, you need to upload a Maven settings.xml with the following configuration:

Of course you can add as much additional configuration to this settings.xml as you want. The gpg.home points to where you just uploaded your keys. Make sure you have mounted your private repository in your build configuration, as described in the tutorial. The passphrase must be given in plain text. This is another reason to use a separate key for signing and not your personal key! So in case someone breaks into your Cloudbees account, they will not get your whole identity.

Now you should be able to do releases to Central on your Jenkins. If you followed all the steps and gpg still tells you that it "cannot obtain passphrase in batch mode", then you might have stumbled over an encoding problem. I have had problems with gpg passphrases that contain German umlauts (Ä,Ö,Ü). So try a simple passphrase first, just to be sure.