Recently I’ve been working intensively with Maven and it’s release plugin and I wanted to share some things I learned while scripting release process for our project. I wish I could say that everything’s been as easy as “advertised” in plugin’s documentation but unfortunately there were some problems to overcome and also some things I needed that weren’t supported by plugin (e.g. sending of notification email to the team after successful release). So here are 8 tips & tricks to help you release your code like a champ…

Since release:perform goal is only doing post-release packaging and deploying into Nexus repository my focus will be on release:prepare goal that does most of the work. This is what will happen when you run “mvn release:prepare” on your parent POM file:

  • – Check if everything’s commited into SCM
  • – Ask you to provide release version for your project
  • – Ask you to provide version for next development iteration
  • – Update POMs with release version
  • – Run all available tests
  • – Commit updated POMs to SCM
  • – Create new tag in SCM
  • – Update POMs version to next development version
  • – Commit updated POMs to SCM

1. No un-commited files

Make sure you don’t have files that are not commited into SCM because plugin will give you an error and refuse to start release.

2. Check your project versions

For plugin to be able to successfully update versions they must start with version number and end with “-SNAPSHOT” (e.g. 1.0.1-SNAPSHOT). This means that you cannot use expressions to propagate version from parent POM (e.g. ${project.version}) and also your version number must be consistent through out all POMs. Expressions can still be used to specify dependency version and this is very useful when one project uses another one so you don’t have to update them manually after release.

3. You cannot can skip tests

Unfortunately because release plugin takes its job seriously and wants to make sure you get as stable code as possible, each time you run a release:prepare all tests will be executed two times. First one is with release version to make sure newly tagged code works ok and second time using new development version. Standard flags for skipping tests don’t have any effect (-DskipTests=true or -Dmaven.test.skip=true).
[EDIT] Actually you can skip tests but you need to pass skipTests parameter into release plugin’s sub-plugins (see point 6). Thanks to René Zanner for pointing this out!

4. Beware of plugin version 2.2

This version (at this time it is latest) has a major bug causing newly created SCM tags to be named using development version instead of release version. As a result you’ll get tags with “-SNAPSHOT” in their name. Workaround for this is to use plugin’s property <tagNameFormat> where you can specify it manually.

5. Run post-release tasks

Property <completionGoals> is new in version 2.2 and allows you to run additional goals after everything’s done right before commiting POMs updated to new development version. For example this can be very useful if you want to run some Ant tasks after successful release like send out email notification to the team (email task) or run some custom scripts (exec task) etc. To do this just add antrun plugin in <build><plugins>  section of your master POM, set its property to false so it’s executed only once, define your tasks in antrun’s <configuration>, and add “antrun:run” in <completionGoals>.

6. Release plugin does not pass arguments to sub-plugins

This means that when you run “mvn release:prepare” with some arguments (e.g. you give your email credentials so that antrun can send emails) it will not be passed down to antrun automatically because it’s executed by release plugin instead of being executed directly. Workaround for this is to use release plugin’s <arguments> property to pass all your arguments down to other Maven executions. So if you run something like this “mvn release:prepare -DmyProperty=myValue” make sure <arguments> contains “-DmyProperty=${myValue}” and then you can use it normally.

7. -DdryRun=true

Want to make sure everything will run smoothly before you run the actual release?
This is where dryRun argument comes in handy and allows you to run all operations in release:prepare goal except for actual commits into SCM. One thing to keep in mind is that all additional executions will also run so make sure to add check for dryRun property when executing post-release antrun tasks (e.g. sending out notification emails).

8. Want to know which SVN revision you’re releasing?

If you’re using SVN SCM take a look at one other great Maven plugin called Build Number plugin. It provides you with current code revision and current timestamp but also do some other cool things like automatically update your code or check you don’t have un-commited files.

9. ?

You think I forgot something or you have some additional info that would be useful? Leave me a comment below and I’d be glad to add it here…