How to Deploy Maven Artifacts with Travis CI and packagecloud
This is a guest blog post from Joe Damato, CEO and cofounder at packagecloud.
This post will go through the steps needed to implement continuous delivery for Java projects using Maven and Travis CI. Every time a tagged commit is pushed to Github, Travis CI will automatically build the project and push it to your Maven repository on packagecloud.
Configuring Maven for packagecloud and Travis CI
Add a .travis.yml
file to your Maven project
If you’d like to follow along with this post, take a look at the java-test-package github repository for an example Maven project.
We’ll start with the example .travis.yml
file:
sudo: false
language: java
cache:
directories:
- "$HOME/.cache"
before_install:
- cp .travis.settings.xml $HOME/.m2/settings.xml
deploy:
provider: script
script: "mvn -B -V deploy"
skip_cleanup: true
Running mvn test
Because we are specifying language: java
, Travis CI will run mvn test
on our project by default, so we don’t need to specify mvn test
anywhere.
Running mvn deploy
We are using the ‘script’ deployment provider to run mvn deploy
for us.
The deployment script consists of two steps:
-
Copy
.travis.settings.xml
from repository to the required Maven directory -
Run
mvn deploy
We also set on: tags: true
so that deployments are triggered only when a tagged commit is pushed.
For detailed documentation on the deploy
section, refer to the deployment and script sections of the Travis CI docs.
Add a .travis.settings.xml
file to your Maven project
Maven reads repository authentication information from a file located at $HOME/.m2/settings.xml
. Since we’ll be exporting our API token as an environment variable, we just need to copy over a static configuration that tells Maven to use an exported PACKAGECLOUD_TOKEN
as the password for repositories with an id of packagecloud-travis
.
<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>packagecloud-travis</id>
<password>${env.PACKAGECLOUD_TOKEN}</password>
</server>
</servers>
</settings>
Add the packagecloud plugin to <build/>
This tells Maven to use the maven-packagecloud-wagon
plugin, which allows Maven to upload to packagecloud repositories natively.
NOTE: This plugin is only needed when uploading to packagecloud repositories. Any build tool (Maven, Gradle, Leiningen, SBT) can resolve and download from packagecloud Maven repositories without needing a plugin.
Make sure the <build/>
section of your pom.xml
contains the following extension:
<build>
<extensions>
<extension>
<groupId>io.packagecloud.maven.wagon</groupId>
<artifactId>maven-packagecloud-wagon</artifactId>
<version>0.0.4</version>
</extension>
</extensions>
</build>
Create your packagecloud Maven repository
If you haven’t already, get a free maven repository from packagecloud.io.
Add your repository to <distributionManagement/>
We are using an id of packagecloud-travis
so that it matches against the .travis.settings.xml
configuration we are using above. Our repository for this example is capotej/java-test-package.
Set the <distributionManagement/>
section in your pom.xml
to the following:
<distributionManagement>
<repository>
<id>packagecloud-travis</id>
<url>
packagecloud+https://packagecloud.io/capotej/java-test-package
</url>
</repository>
<snapshotRepository>
<id>packagecloud-travis</id>
<url>
packagecloud+https://packagecloud.io/capotej/java-test-package
</url>
</snapshotRepository>
</distributionManagement>
Configure Travis CI
Now that our Maven project is configured and has all of the required files, we’re ready to configure Travis CI.
Sign in to Travis CI with your Github Account
This will give Travis CI access to list all of your Github repositories.
Enable the repository
Under your Travis account settings, find your Maven project repository and enable it.
Create PACKAGECLOUD_TOKEN
environment variable
Visit the packagecloud.io API Token page to get your packagecloud API Token. Then visit your Travis CI project settings page and add that API token as an environment variable named PACKAGECLOUD_TOKEN
.
NOTE: Make sure that “Display value in build log” is set to OFF, or else anyone will be able to see your token!
Set the version and push
Edit and commit the desired version in the <version/>
section of your pom.xml
, for example 2.0.0
.
Then, create that version as a git tag:
git tag -a 2.0.0 -m '2.0.0'
Push all of your changes to Github (origin):
git push origin master
This will start a build on Travis CI, but it will not deploy.
In order to actually deploy, you have to push up your version git tag to Github (origin):
git push origin --tags
This should start another build on Travis CI, which will start the deploy to packagecloud once it finishes.
If everything went according to plan, you should now see your Java package in your packagecloud repository!
Using your packagecloud Maven repository
To use your newly published artifact, we have to add the repository and dependency to the Maven, SBT, Gradle, and/or Leiningen projects that intend to use it. The example steps below are for Maven, but if you navigate to your package page on packagecloud you can see instructions are provided for all supported build tools. Similarly, authentication instructions are also provided for private Maven repositories.
Add the repository to yourpom.xml
You install this Maven repository by adding it to the <repositories>
section of your pom.xml
. No special plugins or extensions are required.
<repositories>
<repository>
<id>capotej-java-test-package</id>
<url>
https://packagecloud.io/capotej/java-test-package/maven2
</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repositories>
Add the dependency to your pom.xml
To depend on java-test-package 2.0.0
, add this to the <dependencies>
section of your pom.xml
.
<dependency>
<groupId>io.packagecloud</groupId>
<artifactId>java-test-package</artifactId>
<version>2.0.0</version>
</dependency>
Bonus: Using SNAPSHOT
versions
The setup described in this post only deploys when a tagged commit is pushed up. However, this can be extended to support different workflows. For instance, if you use a SNAPSHOT
version, you can set it to deploy on every commit. This way, your users can develop against the latest SNAPSHOT
version, like 2.0.0-SNAPSHOT
, then once you are ready for release, just remove -SNAPSHOT
and tag/commit as usual. All packagecloud Maven repositories support SNAPSHOT
and release versions side by side, making this workflow seamless.
Conclusion
Using packagecloud and Travis CI to automate your Java project release process can dramatically speed up your software development cycles and reduce the amount bad or broken releases.