Create a gist now

Instantly share code, notes, and snippets.

Deploy snapshots to Sonatype after Travis CI build
language: java
env:
global:
- SONATYPE_USERNAME=yourusername
- secure: "your encrypted SONATYPE_PASSWORD=pass"
after_success:
- python addServer.py
- mvn clean deploy --settings ~/.m2/mySettings.xml
  1. encrypt your sonatype oss password with travis encrypt -r user/repo SONATYPE_PASSWORD=pass
  2. put addServer.py somewhere in your repository
  3. add the relevant lines to your .travis.yml

Deployment will only happen when the build was successful and the encrypted variables are available (= no deployment for pull requests etc.). If the deployment itself was unsuccessful, then the build still passes.

If you only want to deploy for certain branches, use shell scripting like:

after_success:
  - "[[ $TRAVIS_BRANCH == \"master\" ]] && { python travis/addServer.py; mvn clean deploy --settings ~/.m2/mySettings.xml; };"

Warning: This will deploy multiple times if you use the matrix functionality, see the issue.

#!/usr/bin/env python
import sys
import os
import os.path
import xml.dom.minidom
if os.environ["TRAVIS_SECURE_ENV_VARS"] == "false":
print "no secure env vars available, skipping deployment"
sys.exit()
homedir = os.path.expanduser("~")
m2 = xml.dom.minidom.parse(homedir + '/.m2/settings.xml')
settings = m2.getElementsByTagName("settings")[0]
serversNodes = settings.getElementsByTagName("servers")
if not serversNodes:
serversNode = m2.createElement("servers")
settings.appendChild(serversNode)
else:
serversNode = serversNodes[0]
sonatypeServerNode = m2.createElement("server")
sonatypeServerId = m2.createElement("id")
sonatypeServerUser = m2.createElement("username")
sonatypeServerPass = m2.createElement("password")
idNode = m2.createTextNode("sonatype-nexus-snapshots")
userNode = m2.createTextNode(os.environ["SONATYPE_USERNAME"])
passNode = m2.createTextNode(os.environ["SONATYPE_PASSWORD"])
sonatypeServerId.appendChild(idNode)
sonatypeServerUser.appendChild(userNode)
sonatypeServerPass.appendChild(passNode)
sonatypeServerNode.appendChild(sonatypeServerId)
sonatypeServerNode.appendChild(sonatypeServerUser)
sonatypeServerNode.appendChild(sonatypeServerPass)
serversNode.appendChild(sonatypeServerNode)
m2Str = m2.toxml()
f = open(homedir + '/.m2/mySettings.xml', 'w')
f.write(m2Str)
f.close()
@phax

Thanks a lot for the information - I found them very helpful!
I may add 2 suggestions:

  1. You may want to add -DskipTests=true to the mvn commandline, as tests usually ran before
  2. The name sonatype-nexus-snapshots in the Python script might be changed, if you renamed the SNAPSHOT repository differently in your parent POM. E.g. in my parent POM XML I have the following lines:
  <distributionManagement>
    <snapshotRepository>
      <id>ossrh</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
      <id>ossrh</id>
      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
  </distributionManagement>

therefore I needed to modify line 28 of the script to:

idNode = m2.createTextNode("ossrh")
@eeichinger

you can remove the need for addServer.py - I simply checked in a settings.xml with my project using maven property variables

<!-- settings.xml -->
    <servers>
        <server>
            <!-- Maven Central Deployment -->
            <id>ossrh</id>
            <username>${env.SONATYPE_USERNAME}</username>
            <password>${env.SONATYPE_PASSWORD}</password>
        </server>
    </servers>

then use the same travis encrypt -r <user/repo> SONATYPE_PASSWORD=pass --add command to add those env variables to .travis.yml

and finally run the deploy using mvn deploy --settings settings.xml

-- .travis.yml
after_success:
  - mvn deploy --settings settings.xml
@phax

@eeichinger I like your approach - it's basically much simpler and works also nicely :)
The only suggestion for improvement I have is to change the deploy command to

mvn deploy --settings travis-settings.xml -DskipTests=true -B

so that tests are not executed (again) and to use Maven Batch mode (-B)

@Edit: maybe adding a special Maven profile might also be a good idea in certain cases (add e.g. -P travis-deploy)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment