I’ll start with an example of a pom.xml at the root of a multi module project.
Somewhere at our file we’ll have to define our modules and it should look like this:
<artifactId>sample</artifactId>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>sample-mdw</module>
<module>sample-broker</module>
<module>sample-ws</module>
</modules>
In a real world scenario modules depend each other right? So we have to declare those dependencies on each module
pom.xml file.
For the sake of simplicity, let’s assume that only sample-ws depends on sample-broker and sample-mdw:
<artifactId>sample-ws</artifactId>
<version>1.0.0-SNAPSHOT</version>
<sample-broker.version>1.0.0-SNAPSHOT</sample-broker.version>
<sample-mdw.version>1.0.0-SNAPSHOT</sample-mdw.version>
At this point we’re ready to release our sample project.
(I’m assuming that you release all modules with the same version. If not, you should. Really!)
sample version to 1.0.0sample-mdw version 1.0.0sample-broker version 1.0.0sample-ws version 1.0.0And we still need to bump the dependencies versions:
<sample-broker.version> to 1.0.0<sample-mdw.version> to 1.0.0The example above is just a small sample project and these steps are already very annoying and completely ruins my trust in my own release management. Can I be able to release this project right away? Yes, I think so. At least with this level of complexity.
If we add more modules like sample-db, sample-catalog, sample-sdk and more projects like sample-1,
sample-2 and so on our complexity grows and the chance of missing some step is huge.
(let’s keep the process)
After set all modules version to 1.0.0 we need to tag our commit:
(I’ll skip the branch, commit and merge for now)
$ git tag sample-v1.0.0
Our release is ready, let’s bump all modules version back to SNAPSHOT:
sample version to 1.0.1-SNAPSHOTsample-mdw version 1.0.1-SNAPSHOTsample-broker version 1.0.1-SNAPSHOTsample-ws version 1.0.1-SNAPSHOT<sample-broker.version> to 1.0.1-SNAPSHOT<sample-mdw.version> to 1.0.1-SNAPSHOT$ git push && git push --tags
And we’re done.
I’ll go straight to the point here. Don’t do this. Why? - you say.
mvn clean install succeedsJust don’t.
Include the maven-release-plugin in your project pom.xml and it should be like this:
<artifactId>sample</artifactId>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>sample-mdw</module>
<module>sample-broker</module>
<module>sample-ws</module>
</modules>
<scm>
<url>https://github.com/path/to/sample</url>
</scm>
<properties>
<maven-release-plugin.version>2.5.3</maven-release-plugin.version>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>${maven-release-plugin.version}</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<pushChanges>false</pushChanges>
<localCheckout>true</localCheckout>
<tagNameFormat>${project.artifact}-v@{project.version}</tagNameFormat>
</configuration>
</plugin>
Make sure you have a clean working directory and create a release branch:
$ git checkout -b release/v1.0.0
Using the maven-release-plugin will perform five steps with just one command:
sample-v1.0.0$ mvn --batch-mode release:prepare release:perform \
-DreleaseVersion=1.0.0 -DdevelopmentVersion=1.0.1-SNAPSHOT`
Our git history should be something like:
$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 [maven-release-plugin] prepare for next development iteration
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 [maven-release-plugin] prepare release sample-v1.0.0
Now we just have to merge release/v1.0.0 both commits into development:
$ git checkout development
$ git merge --no-ff -m "v1.0.1-SNAPSHOT" release/v1.0.0
And only the tagged commit into master:
$ git checkout master
$ git merge --no-ff -m "v1.0.0" release/v1.0.0~1
We delete the release branch:
$ git branch -d release/v1.0.0
Finally, push all changes:
$ git push --all && git push --tags
Again, try to do this with 5 projects with 5 modules each, measure the time and take your own conclusions.
Always aim to automation, always.