just got it in a hacky way... but I'm not satisfied.
If someone will provide a better way to perform a custom recursive release process on maven I'll be glad to change my acceptance!
parent pom:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>test-release-parent</artifactId>
<version>1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>test-release-parent</name>
<description>This is the parent pom to test release procedure</description>
<inceptionYear>2014</inceptionYear>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<svn.repository>http://svn.mycompany.com/repo1</svn.repository>
<web.projects>http://www2.mycompany.com/projects</web.projects>
</properties>
<scm>
<developerConnection>scm:svn:${svn.repository}/${project.artifactId}</developerConnection>
<url>${svn.repository}/${project.artifactId}</url>
</scm>
<distributionManagement>
<repository>
<id>ftp.mycompany.com</id>
<name>mycompany Maven Repository</name>
<url>ftp://ftp.mycompany.com/maven-repo</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>www2.mycompany.com</id>
<name>mycompany Maven Repository</name>
<url>http://www2.mycompany.com/maven-repo</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>www2.mycompany.com</id>
<name>mycompany Maven Repository</name>
<url>http://www2.mycompany.com/maven-repo</url>
</pluginRepository>
</pluginRepositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<excludes>
<exclude>javax:javaee-api:*:*</exclude>
<exclude>org.eclipse.persistence:*:*:*</exclude>
<exclude>org.hibernate:hibernate-validator:*:*</exclude>
</excludes>
<rulesUri>http://www.mycompany.com/ruleset.xml</rulesUri>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<configuration>
<source>
String releaseVersion = project.version.substring(0, project.version.indexOf("-"));
String nextVersion;
int index = releaseVersion.lastIndexOf(".");
if(index == -1) nextVersion = (releaseVersion.toInteger() + 1) + "-SNAPSHOT";
else
{
String prefix = releaseVersion.substring(0, index);
String suffix = releaseVersion.substring(index + 1);
nextVersion = prefix + "." + (suffix.toInteger() + 1) + "-SNAPSHOT";
}
ant.exec(failonerror: "true", dir: "${basedir}", executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "validate")
arg(value: "-Prelease-align")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
ant.exec(failonerror: "true", dir: "${basedir}", executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "initialize")
arg(value: "-Prelease-prepare")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
ant.exec(failonerror: "true", dir: "${basedir}", executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "deploy")
arg(value: "-Prelease-perform")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
</source>
</configuration>
</plugin>
</plugins>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>2.6</version>
</extension>
</extensions>
</build>
<profiles>
<profile>
<id>buildall</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
for(d in project.dependencies)
{
if(d.groupId == "com.mycompany" && d.version.endsWith("-SNAPSHOT"))
{
println "installing " + d
ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "install")
arg(value: "-Pbuildall")
}
}
}
</source>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release-align</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<executions>
<execution>
<id>initial-updates</id>
<phase>validate</phase>
<goals>
<goal>update-parent</goal>
<goal>use-releases</goal>
<goal>commit</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release-prepare</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<id>release-snapshots</id>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
if(project.parent != null && project.parent.groupId == "com.mycompany" && project.parent.version.endsWith("-SNAPSHOT"))
{
println "releasing " + project.parent
String releaseVersion = project.parent.version.substring(0, project.parent.version.indexOf("-"));
String nextVersion;
int index = releaseVersion.lastIndexOf(".");
if(index == -1) nextVersion = (releaseVersion.toInteger() + 1) + "-SNAPSHOT";
else
{
String prefix = releaseVersion.substring(0, index);
String suffix = releaseVersion.substring(index + 1);
nextVersion = prefix + "." + (suffix.toInteger() + 1) + "-SNAPSHOT";
}
ant.exec(failonerror: "true", dir: "${basedir}/../" + project.parent.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "validate")
arg(value: "-Prelease-align")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
ant.exec(failonerror: "true", dir: "${basedir}/../" + project.parent.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "initialize")
arg(value: "-Prelease-prepare")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
ant.exec(failonerror: "true", dir: "${basedir}/../" + project.parent.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "deploy")
arg(value: "-Prelease-perform")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
}
for(d in project.dependencies)
{
if(d.groupId == "com.mycompany" && d.version.endsWith("-SNAPSHOT"))
{
println "releasing " + d
String releaseVersion = d.version.substring(0, d.version.indexOf("-"));
String nextVersion;
int index = releaseVersion.lastIndexOf(".");
if(index == -1) nextVersion = (releaseVersion.toInteger() + 1) + "-SNAPSHOT";
else
{
String prefix = releaseVersion.substring(0, index);
String suffix = releaseVersion.substring(index + 1);
nextVersion = prefix + "." + (suffix.toInteger() + 1) + "-SNAPSHOT";
}
ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "validate")
arg(value: "-Prelease-align")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "initialize")
arg(value: "-Prelease-prepare")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
ant.exec(failonerror: "true", dir: "${basedir}/../" + d.artifactId, executable: "cmd")
{
arg(value: "/c")
arg(value: "mvn")
arg(value: "deploy")
arg(value: "-Prelease-perform")
arg(value: "-Dversion.release=" + releaseVersion)
arg(value: "-Dversion.next=" + nextVersion)
}
}
}
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<executions>
<execution>
<id>final-updates</id>
<phase>initialize</phase>
<goals>
<goal>update-parent</goal>
<goal>use-releases</goal>
<goal>set</goal>
<goal>commit</goal>
</goals>
<configuration>
<newVersion>${version.release}</newVersion>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release-perform</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<executions>
<execution>
<id>set-next-snapshot</id>
<phase>deploy</phase>
<goals>
<goal>set</goal>
<goal>commit</goal>
</goals>
<configuration>
<newVersion>${version.next}</newVersion>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<executions>
<execution>
<id>checkin-release</id>
<phase>verify</phase>
<goals>
<goal>checkin</goal>
<goal>tag</goal>
</goals>
</execution>
<execution>
<id>checkin-snapshot</id>
<phase>deploy</phase>
<goals>
<goal>checkin</goal>
</goals>
</execution>
</executions>
<configuration>
<tag>${project.version}</tag>
<message>auto-generated by release process</message>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
and this is a project pom that uses another project (flatten structure in workspace) as dependency
<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>
<groupId>com.mycompany</groupId>
<artifactId>test-release-parent</artifactId>
<version>1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-release-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>maven project to test a release process</description>
<inceptionYear>2014</inceptionYear>
<url>${web.projects}/${project.artifactId}</url>
<repositories>
<repository>
<id>www2.mycompany.com</id>
<name>mycompany Maven Repository</name>
<url>http://www2.mycompany.com/maven-repo</url>
</repository>
</repositories>
<scm>
<developerConnection>scm:svn:${svn.repository}/${project.artifactId}/trunk</developerConnection>
<url>${svn.repository}/${project.artifactId}/trunk</url>
</scm>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>test-release-dependency</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
just run
mvn <some-phase> -Pbuildall
to execute <some-phase>
on current project and install
on all owned and referenced snapshots (parent and dependencies)
and
mvn groovy:execute
to perform a release an all owned and referenced snapshots
the idea behind:
- procedure release:
- update parent version if exists
- update snapshot dependencies if exists
- if parent is owned and snapshot
- release(parent)
- for each owned and snapshot dependency
- release(dependency)
- update parent version (MUST exist now)
- update owned and snapshot dependencies (MUST exist now)
- set project release version (ie from 1.0.0-SNAPSHOT to 1.0.0)
- commit changes to scm
- tag freeze on scm
- perform all maven lifecycle phases till deploy
- set project next version (ie from 1.0.0 to 1.0.1-SNAPSHOT)
- commit changes to scm again