I’m currently working on setting up and configuring the Maven release plugin on our projects for doing releases – primarily tagging, branching, and deploying a tagged release.

We have been using Maven extensively and I’ve been for the most part happy with it since we migrated from Ant. I say *most* since there have been a couple of times where Maven didn’t work as expected or documented. For example, in the current case, with the Maven release plugin.

Most of our projects are setup as multi-module projects with a parent pom and children jars. The Maven release plugin behaviour is suspect with multi-module projects.

For example, say I had project with “bar” as the parent and “baz”, “bam” and “dist” as the children modules. And “bam” has “baz” as a dependency. “dist” does the assembly using the Maven assembly plugin.

Running the following command on the “bar” tags the release fine:
mvn release:clean release:prepare
but fails during the following command which checks out the tagged release from our SCM and attempts to build it:
mvn release:perform

During release:perform, Maven first checks out the code using the above tag and then attempts to build (deploy goal) the checked out code (under bar/target/checkouts folder) using the command:

deploy --no-plugin-updates -P defaultRepo -DreleasePerform=true -f pom.xml

During the build, Maven attempts to download the release version of “baz” since it’s defined as a dependency in “bam” pom. Of course, this fails! Because “baz” isn’t available as a release yet.

After a “few gnashing of teeth and pulling of the hair” moments, I noticed that this is caused by the “-DreleasePerform=true” variable in the above command that Maven uses internally once I issued the “mvn release:perform” command. Take “-Drelease:perform=true” out, the release:perform works great.

To get past this issue, I had to override the default “preparationGoals” element of the Maven release plugin. The default preparationGoals are clean verify. Adding install after verify built the release jars during the release:prepare goal and installed it to my local Maven repository. So now when I run the mvn release:perform command, it downloads the “baz” dependency from my local Maven repository.

A few other things I didn’t like:

1. Why can I not have 3rd party SNAPSHOTS in my release?
For example, one of our 3rd party dependencies is org.osgi.compendium, for which a release isn’t available. Apache Felix has only made it available as a SNAPSHOT. Having this SNAPSHOT as a dependency doesn’t go well with the Maven release plugin. It complains that there are SNAPSHOT dependencies and they need to be resolved to released. I know there are SNAPSHOT dependencies and I intentionally left them there since I don’t have *release* versions.
IMHO, there should be a setting to override this *Check that there are no SNAPSHOT dependencies* behavior.

2. Why doesn’t the Maven release plugin reuse the release.properties file that was generated during a dryRun when doing a release:prepare?
I like the concept of a dryRun when during a release:prepare. This gives me the opportunity to verify the changes that will be checked in to my SCM. Running the following command enables me to do this:

mvn release:clean release:prepare -DdryRun=true

The above command generates the temporary pom files and a release.properties file that I can scour through to make sure everything is correct.
Now one would assume that if you run the command:

mvn release:prepare

it would reuse the files that were generated by the previous command mvn release:clean release:prepare -DdryRun=true
But it does not!. Instead I am prompted to enter the release information again. What if I now mis-typed a letter??
Am I missing something here?

3. –batch-mode is only good if you want to stick with the versioning provided by the Maven release plugin. Why is customization not supported?
We version our projects as M.N.P
M – Major release
N – minor release
P – patch or bug-fix release
The default versioning used by the Maven release plugin is M.N. Although I understand –batch-mode is provided to make our lives easier by going with the defaults, it doesn’t really. Since I’m stuck with the versioning standards provided by Maven. I like the “convention over configuration” approach. But by not allowing room for customization doesn’t help.

Apart from the above pain points, the Maven release plugin seems to do it’s job for us. We are planning on using it for now until something better comes up since it certainly bring some order to the chaotic world of tagging, branching and releasing.