The Unknown creature - The Maven Release Cycle

In the meantime often people use Maven to build their software, but when it comes to the time to release an artifact, they sometimes do unusual things in my opinion. I have often observed that they manually set the version numbers to the release version (just removing the -SNAPSHOT) from it and build by hand and do the deploy the same way.

But Maven is better than you think. Maven can do the whole thing within a single command.

1mvn --batch-mode release:prepare release:perform

Let us take a detailed look on the above command which expresses calling two separate goals of the Maven Release Plugin. You can of course call the above command in two separate steps if you prefer that. Furthermore let us assume the artifact which will be released has the version 1.0.0-SNAPSHOT.

1mvn --batch-mode release:prepare

and furthermore

1mvn --batch-mode release:perform

But now let us focus on the release:prepare goal what it exactly does:

  • The release:prepare will first check if your work area does not contain any uncommitted changes
  • It will check that there are no SNAPSHOT dependencies
  • It will change the version in the POMs from 1.0.0-SNAPSHOT to a new version 1.0.0
  • Transform the SCM information in the POM to include the final destination of the tag
  • Run the project tests against the modified POMs to confirm everything is in working order
  • Commit the modified POMs
  • Tag the code in the SCM with a version name
  • Bump the version in the POMs to a new value 1.0.1-SNAPSHOT
  • Commit the modified POMs

These steps require some configuration in your POM which have to be configured in the right way to get the release:prepare work otherwise the release:prepare will fail.

The most important thing is that your SCM area in your POM is correctly configured, cause release:prepare goal will make tags of your software automatically. The following example gives you an impression how the SCM area must look like if you are using GitHub.

1<scm>
2  <connection>scm:git:git://github.com/khmarbaise/Maven-License-Verifier-Plugin.git</connection>
3  <developerConnection>scm:git:git@github.com:khmarbaise/Maven-License-Verifier-Plugin.git</developerConnection>
4  <url>https://github.com/khmarbaise/Maven-License-Verifier-Plugin</url>
5</scm>

The following example will show you how it looks like if you are using Subversion:

1<scm>
2    <connection>scm:svn:http://svn.apache.org/repos/asf/tika/trunk</connection>
3    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/tika/trunk</developerConnection>
4    <url>http://svn.apache.org/viewvc/tika/trunk</url>
5</scm>

After successfully running the release:prepare phase you continue with the release:perform. The release:perform will do the following:

  • Checkout from an SCM URL with optional tag
  • Run the predefined Maven goals to release the project (by default, deploy site-deploy)

It is important to know that the above goals release:prepare and release:perform must be called inside the same project one after another. To get a successful run of the release:perform it is needed to correctly configure the distributionManagement area in your POM, cause Maven will deploy the artifact to the configured repository and will deploy the created site of the artifact to the appropriate site area as well.

An example of an distributionManagement area looks like this:

 1<distributionManagement>
 2    <repository>
 3      <id>ossrh-staging</id>
 4      <url>http://oss.sonatype.org/service/local/staging/deploy/maven2</url>
 5    </repository>
 6    <snapshotRepository>
 7      <id>ossrh-snapshots</id>
 8      <url>http://oss.sonatype.org/content/repositories/snapshots</url>
 9    </snapshotRepository>
10    <site>
11      <id>site.supose.org</id>
12      <url>scp://minden205.server4you.de:/usr/local/vhosts/site.supose.org/maven-license-verifier-plugin</url>
13    </site>
14</distributionManagement>

In the above case the configuration is of an artifact which will be released to Maven Central which cause some other requirements to be fulfilled. In particular the artifacts must be signed by gpg etc. but if you are releasing within your company you can define your own standards. So if you configured everything well your release process will be very simple by just calling:

1mvn --batch-mode release:prepare release:perform

But sometimes it happens that something is going wrong either in the release:prepare phase or during the release:perform. If your release process fails in the release:prepare phase you have to do an release:rollback first, before doing anything else. You have to be aware of the fact that depending where the release:prepare process has failed a tag for your release has already been created. So you should check your version control whether the tag for the version has been created or not. If it has you have to manually remove that tag. If you don not do it that way the next time you try release:prepare will fail based on the existing tag. If you are just a beginner with the Maven Release process you should call the release:prepare and release:perform in two separate commands to be sure where the errors belong to. So after configuring etc. the parts in your POM a release of an artifact should not be a pain anymore.