maven central release with github in 30 seconds

Uploading Snapshots and Releases to Maven Central with TravisCI

As a passionate developer I always strive to optimise my build chain for speed and simplicity. In this example I’d like to publish a library on maven central without any onsite build tooling except my IDE. So lets see how to get rid of gpg key management and implement a trivial push-button release process with Github and TravisCI.

(This is reblogged originally from idealo/logback-redis/wiki/Release-Process and sponsored by Idealo)

We based the release process on this tutorial and simplified the process by using adhoc created gpg keys just once, so there is no hassle with key management.

For a working example, you may check out our project logback-redis

TLDR; Release with just pushing a git tag or pressing ‘create release’ in Github.

Basically you have 3 steps (OSSRH Guide):

  1. Create a Jira Account at Sonatype
  2. Create a Project Ticket
  3. Deploy to or Therefor you need to:
    • Modify your pom.xml
    • Add build plugins for binaries, javadoc and sources jar files and gpg signing
    • (Creation of a gpg key and signing your builds is done implicitly)
    • Integrate this with travis secured environment variables


Add general information to your pom.xml

You need to add the following parts to your pom.xml. There are detailed explanations of these configuration values at

This general information needs to be available (e.g. a missing description tag will make deployment to maven central impossible):

File: pom.xml
<description>A good description</description>

Also the developer and license information is necessary:

File: pom.xml
    <name>Joe Doe</name>


Add distributionManagement for ossrh to your pom.xml

The following two entries are given to you, as soon as you finish step 1 and 2 at sonatype’s jira:

File: pom.xml

You will need to add them in your pom.

Once set up, the maven deploy task will know the target for uploads.

Add maven build plugins

For a successful upload to maven central you need your jar, a java doc jar, a java sources jar and all of those need to be signed with a gpg key. The following configuration in your pom.xml will take care of those steps:

File: pom.xml

Creating GPG-Keys

We create our temporary GPG-Keys on-the-fly with the following script (.travis/

File: .travis/
#!/usr/bin/env bash

set -e

# create a random passphrase
export GPG_PASSPHRASE=$(echo "$RANDOM$(date)" | md5sum | cut -d\  -f1)

# configuration to generate gpg keys
cat >gen-key-script <<EOF
    %echo Generating a basic OpenPGP key
    Key-Type: RSA
    Key-Length: 4096
    Subkey-Type: 1
    Subkey-Length: 4096
    Name-Real: Opensource Idealo
    Expire-Date: 2y
    Passphrase: ${GPG_PASSPHRASE}
    %echo done

# create a local keypair with given configuration
gpg --batch --gen-key gen-key-script

# export created GPG key
# example output
# sec   4096R/EDD32E8B 2016-09-08 [verfällt: 2018-09-08]
# uid                  Lars K.W. Gohlke <>
# ssb   4096R/CC1613B2 2016-09-08
# ssb   4096R/55B7CAA2 2016-09-08
export GPG_KEYNAME=$(gpg -K | grep ^sec | cut -d/  -f2 | cut -d\  -f1 | head -n1)

# cleanup local configuration
shred gen-key-script

# publish the gpg key
# (use as travis request keys from this server, 
#  we avoid synchronization issues, while releasing) 
gpg --keyserver --send-keys ${GPG_KEYNAME}

# wait for the key beeing accessible
while(true); do
  gpg --keyserver  --recv-keys ${GPG_KEYNAME} && break || sleep 30

This will provide maven with a key pair to sign our artifacts.

Signing is mandatory with sonatype.

Create a settings.xml for the travis build

The following settings.xml should be available in your git repository at .travis/settings.xml:

File: .travis/settings.xml
<settings xmlns=""
            <!-- Maven Central Deployment -->

As you can see we’ll use environment-variables to configure passphrase and sonatype password. (Those are tokens, not your real account passwords. See below.)


Add the secrets to your Travis Settings Page

If your project is already on travis, you need to add the environment variables on the settings page. For example, for the logback-redis project under idealo namespace, the url looks like this:


Fill SONATYPE_USERNAME and SONATYPE_PASSWORD with your tokens (NOT your actual credentials).

Add .travis.yml

Your .travis.yml file could look like this:

File: .travis.yml
language: java

  - oraclejdk8

script: mvn --settings .travis/settings.xml clean  verify

    provider: script
    script: .travis/
    skip_cleanup: true
      repo: idealo/logback-redis
      tags: true
      jdk: oraclejdk8


It’s very important to override the install instruction for mvn with --settings .travis/settings.xml, otherwise your settings.xml will be ignored and the configuration would be useless.

Add .travis/

Since it’s easier to read if you have all deploy steps in a separate file, I created a .travis/ for this:

File: .travis/
#!/usr/bin/env bash

set -e

# only do deployment, when travis detects a new tag
if [ ! -z "$TRAVIS_TAG" ]
    echo "on a tag -> set pom.xml <version> to $TRAVIS_TAG"
    mvn --settings .travis/settings.xml org.codehaus.mojo:versions-maven-plugin:2.3:set -DnewVersion=$TRAVIS_TAG -Prelease

    if [ ! -z "$TRAVIS" -a -f "$HOME/.gnupg" ]; then
        shred -v ~/.gnupg/*
        rm -rf ~/.gnupg

    source .travis/

    mvn clean deploy --settings .travis/settings.xml -DskipTests=true --batch-mode --update-snapshots -Prelease

    if [ ! -z "$TRAVIS" ]; then
        shred -v ~/.gnupg/*
        rm -rf ~/.gnupg
    echo "not on a tag -> keep snapshot version in pom.xml"

This snippet sets the version in the pom file to the tag version (if it’s a git tag aka release). Afterwards a deploy will be triggered only if it is a release.

That’s why in my pom.xml there is always a -SNAPSHOT qualifier and no final MAJOR.MINOR.PATCH version, yet. This part takes care of creating a SemVer version of the pom.xml.


If you set this up correctly, your setup will work like this:

  1. In your pom.xml you have <version>0.1.0-SNAPSHOT</version>
  2. If you push a commit to master of your repository only the tests will run.
  3. If you git tag 0.1.0 and git push --tags afterwards, you will have 0.1.0 of your library available at maven central.