Skip to content

Instantly share code, notes, and snippets.

@lucananni93
Last active June 16, 2019 10:35
Show Gist options
  • Save lucananni93/bbc96b99e7bd335061206889857599bf to your computer and use it in GitHub Desktop.
Save lucananni93/bbc96b99e7bd335061206889857599bf to your computer and use it in GitHub Desktop.
Deploy to multiple snapshot repositories based on the git branch (with Travis) in a multi-module project

Deploy to multiple snapshot repositories based on the git branch (with Travis) in a multi-module project

You have a multi-module maven project which is structured like this:

project/
  pom.xml
  module1/
    pom.xml
    other_stuff/
  module2/
    pom.xml
    other_stuff/
  ...

and you are using travis as your CI manager.

Your github repository has multiple branches like the following:

- master
- feature_branch_1
- feature_branch_2
- ...

You want Travis to deploy a different snapshot version to your maven snapshot repository based on the branch name. For example, if you have pushed a change to branch feature_branch_1 and the version of the project is 1.0-SNAPSHOT, you would like to deploy using the 1.0-feature_branch_1-SNAPSHOT version number.

This can be done by using the before_install clause and calling the modify_version.py python script.

language: java
before_install: python modify_versions.py $TRAVIS_BRANCH
install: mvn install
script: mvn test
deploy:
provider: script
script: mvn clean deploy --settings settings.xml
skip_cleanup: true
on:
all_branches: true
import glob
import argparse
import xml.etree.ElementTree as ET
ET.register_namespace('', "http://maven.apache.org/POM/4.0.0")
ns = "{http://maven.apache.org/POM/4.0.0}"
def modifyChildrenPom(pom_xml, new_version, groupId):
# modify the parent section
pom_xml.find("./{}parent/{}version".format(ns, ns)).text = new_version
# modify the dependencies
for depenendencyNode in pom_xml.findall("./{}dependencies/".format(ns)):
d_group_id = depenendencyNode.find("./{}groupId".format(ns)).text
if groupId == d_group_id:
depenendencyNode.find("./{}version".format(ns)).text = new_version
def modifyRootPom(root_pom_xml, new_version):
versionNode = getVersionNode(root_pom_xml)
versionNode.text = new_version
def getNewVersion(old_version, branch_name):
if (old_version.endswith("SNAPSHOT")) & (branch_name != 'master'):
parts = old_version.split("-")
new_version = parts[0] + "-" + branch_name + "-" + parts[1]
else:
new_version = old_version
return new_version
def getArtifactId(pom_f_xml):
return pom_f_xml.find("./{}artifactId".format(ns)).text
def getGroupId(pom_f_xml):
return pom_f_xml.find("./{}groupId".format(ns)).text
def getVersionNode(pom_f_xml):
return pom_f_xml.find("./{}version".format(ns))
def getVersion(pom_f_xml):
return getVersionNode(pom_f_xml).text
def isRootPom(pom_f_xml):
return getArtifactId(pom_f_xml) == ROOT_POM
def main():
parser = argparse.ArgumentParser(description='Modify the versions in the pom files')
parser.add_argument('branch_name', help="Name of the branch of the current build")
branch_name = parser.parse_args().branch_name
if (branch_name.startswith("\"") & branch_name.endswith("\"")) | \
(branch_name.startswith("'") & branch_name.endswith("'")):
branch_name = branch_name[1:-1]
print("The current branch is {}".format(branch_name))
# root pom
root_pom_path = "./pom.xml"
root_pom_xml = ET.parse(root_pom_path)
root_version = getVersion(root_pom_xml)
root_group_id = getGroupId(root_pom_xml)
root_artifact_id = getArtifactId(root_pom_xml)
print("Root POM:\n\
\tGroupId: {}\n\
\tVersion: {}\n\
\tArtifactId: {}".format(root_group_id, root_version, root_artifact_id))
new_version = getNewVersion(root_version, branch_name)
print("New Version: {}".format(new_version))
modifyRootPom(root_pom_xml, new_version)
root_pom_xml.write(root_pom_path)
print("{:<30}{} --> {}".format(root_pom_path, root_version, new_version))
# all the others
other_pom_paths = glob.glob("./*/pom.xml")
print("Changing POM files")
for pom_path in other_pom_paths:
pom_xml = ET.parse(pom_path)
modifyChildrenPom(pom_xml, new_version, root_group_id)
pom_xml.write(pom_path)
print("{:<30}{} --> {}".format(pom_path, root_version, new_version))
if __name__ == '__main__':
main()
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>...</modelVersion>
<groupId>com.the.group</groupId>
<artifactId>artifact</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>Module1</module>
<module>Module2</module>
<module>Module3</module>
</modules>
<name>${project.groupId}:${project.artifactId}</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<licenses>
<license>
<name>...</name>
<url>...</url>
</license>
</licenses>
<developers>
<developer>...</developer>
</developers>
<scm>...</scm>
<dependencies>
<dependency>...</dependency>
</dependencies>
<profiles>
<profile>
<id>deploy</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<id>Scaladoc</id>
<goals>
<goal>doc</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<args>
<arg>-no-link-warnings</arg>
</args>
</configuration>
</execution>
<execution>
<id>Compile</id>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>doc-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>artifact</artifactId>
<groupId>com.the.group</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>...</modelVersion>
<artifactId>Module1</artifactId>
<description>...</description>
<dependencies>
<dependency>
<groupId>com.the.group</groupId>
<artifactId>Module3</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<phase>compile</phase>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>testCompile</goal>
</goals>
<phase>test-compile</phase>
</execution>
<execution>
<phase>process-resources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>it.polimi.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<id>Scaladoc</id>
<goals>
<goal>doc</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<args>
<arg>-no-link-warnings</arg>
</args>
</configuration>
</execution>
<execution>
<id>Compile</id>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment