Last Updated: November 21, 2017
·
11.31K
· alyphen

Deploying maven artifacts from Travis

I've been using Travis CI for a while on a few projects, managed using Maven, and was wondering today if I could actually deploy artifacts created by Travis. The first thing I came across was a little ruby gem that could deploy artifacts to S3, found here. Unfortunately, I don't use S3, nor do I have any plans to do so in the near future.

The next thing I came across was this blog post. This was exactly what I wanted to do.

For the projects in question, I've set up a makeshift maven repository using a branch on GitHub, of course, most projects will be using a proper Sonatype Nexus repo or the like, but this should work for whatever method of deployment you have set up.

The first thing to do is have the settings.xml for maven set up for Travis. I made a branch called "travis" to store this and exempted it from building:

(in .travis.yml on your master branch:)

branches:
  except:
    - travis

(commit & push that)

git add .travis.yml
git commit -m 'Exempt travis branch from Travis'
git push

(in terminal, creating the new branch with no commits and clearing out any files:)

git checkout --orphan travis
git rm -r .
rm -r .

The next thing to do is actually create the settings.xml. Since this usually stores your username and password, you need to have a way of hiding this from the public. Fortunately, maven comes with support for environment variables and Travis allows "secure" encrypted environment variables, so in settings.xml we use the envionment variables for your repository's username and password:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <servers>
    <server>
      <id>sonatype-nexus-snapshots</id>
      <username>${env.CI_DEPLOY_USERNAME}</username>
      <password>${env.CI_DEPLOY_PASSWORD}</password>
    </server>
  </servers>
</settings>

Let's commit and push that:

git add --all
git commit -m 'Add settings.xml'
git push origin travis

To create the encrypted variables, we need to use the travis gem.
If you don't already have the travis gem, you can install it using:

sudo gem install travis

Then, once you have it installed, you may encrypt your user and password:

travis encrypt -r you/yourrepo "CI_DEPLOY_USERNAME=username"
travis encrypt -r you/yourrepo "CI_DEPLOY_PASSWORD=password"

Add the outputted "secure" variables to your .travis.yml on master, first switch back to your master branch:

git checkout master

Then open your .travis.yml and add your environment variables at the bottom:

env:
  global:
    - [paste your encrypted user variable, including the "secure: "]
    - [paste your encrypted password variable, including the "secure: "]

And the following scripts at the top:

before_install: "git clone -b travis `git config --get remote.origin.url` target/travis"
script: "mvn deploy --settings target/travis/settings.xml"

Alright, finally, let's commit and push to master.

git checkout master
git add .travis.yml
git commit -m 'Deploy maven artifacts from Travis builds'
git push origin master

Travis will then proceed to build the latest version of your master branch and deploy artifacts to your maven repo, and on each subsequent push it should deploy the new snapshots.

8 Responses
Add your response

This is a crazy usage of Travis-CI. Not recommended.

over 1 year ago ·

You are amazing, thank you.

over 1 year ago ·

Crazy usage, but still seems to be the only way to get the job done.

over 1 year ago ·

Crazy usage ? This is just what a CI should do.

Thanks a lot.

over 1 year ago ·

Here:
Then open your settings.xml and add your environment variables at the bottom:
did you mean
Then open your .travis.yml and add your environment variables at the bottom:

over 1 year ago ·

Thanks, well spotted. It's hard to believe no-one's pointed this out in the year since I posted it.

over 1 year ago ·

Nice, very helpful, thanks.
I'm curious as to why you put the settings file in a different branch.
Side-note: if you're deploying to Nexus, an extra layer of security would be to use a token, which is heavy to revoke, should it be compromised.

over 1 year ago ·

Nice post, very helpful!

over 1 year ago ·