As more of our projects becomes inter-related, it becomes more important to consider the dynamics of releasing these projects.
For example, on a recent project we dropped a release to the customer without bothering to cut revisions of the Intelliware projects that we depend on. When we needed to do maintenance on that branch, it was unnecessarily difficult since the SNAPSHOT revision that we depended on had evolved and our branch no longer compiled.
To avoid this, we should have cut releases of the dependent projects. We could have gone a step further and cut a real release of our project as well.
The Maven release plugin
In theory, creating a release is easy. Just use the Maven Release Plugin.
In case there’s a problem,
will return your project to its pre-release state.
You can also run a “dryRun” to test the release:prepare stage if you want
mvn -DdryRun=true release:prepare
If all is well then just run clean before you do the true release:prepare
The plugin does everything that you need:
- updates the version of your project by removing the -SNAPSHOT designation. For example, 1.2-SNAPSHOT will be updated to 1.2.
- tags the release in svn as projectname-1.2.
- deploys the updated project to the repository
- again updates the version of your project to the next SNAPSHOT revision. To continue the example above, the project would now be at revision 1.3-SNAPSHOT.
- commits everything.
After this has been done, you can continue working on the main trunk of your project in the new snapshot release. If you need to make changes to a previous revision, check out the old tag and create a branch from it. Eventually you’ll be able to release from the branch with a revision like 1.2.1.
Problem: there are uncommitted changes in your local copy of the code.
Solution: commit or override your changes.
Problem: your project depends on a SNAPSHOT versions of another project. This is problematic because with a released version of the dependency, you will not be able to return to the exact project state that you currently have.
Solution: each dependency must be resolved. This will sometimes lead you on a chain of dependency resolution. The plugin seems to have the capability of resolving all the dependencies at once, but I have so far been a little leery of trusted the automated dependency resolution and have instead checked out and modified the dependency projects by hand. Also be aware that someone may have already versioned the dependency project and it might just be a matter of changing the version that you depend on.
Of course, you should co-ordinate other dependency releases with other people that are impacted by the release.
Your goal is to have no -SNAPSHOT dependencies in your pom.xml.
Weird problems from outer space
Problem: even though your application can be built properly, it cannot be released due to test failures.
Solution: the site:site target (which is run as part of the release process) may be the cause of your problem. It appears that site:site creates a different classpath than the standard test target. If this appears to be the case (that is, site:site does not run on its own), then it’s just the standard maven problem of tracking down multiple versions of a dependency.
“Too many open files” error
Problem: while running site:site, the release plugin reports a “too many open files” error.
Solution: this occurred quite frequently with the 1.0-beta-1 release of the wagon-webdav. Upgrade this to 1.0-beta-2.
Problem: SVN reports authorization errors to the repository
Solution: run an “svn info” on the URL that was reported to be in error. If you’re asked for credentials, fill them in and this should cache them for the release:prepare. If you’re not asked for credentials, your problem is probably something else.
Problem: Error: data file /home/administrator/workspace/my-project/target/checkout/my-subproject/cobertura.ser does not exist
Solution: my-subproject has an empty src/main/java and/or src/test/java directories. Get rid of them.
The deploy takes an unreasonable amount of time
Problem: during the release:perform stage, the site:site target is called. It takes an especially long time, notably at this stage:
[INFO] Generating "Dependencies" report.
Solution: set the dependencyLocationsEnabled property to false.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <configuration> <dependencyLocationsEnabled>false</dependencyLocationsEnabled> </configuration> </plugin>
or run maven with
- if you have several subprojects, you can release them all at once by releasing the parent project.
- if a release fails and must be rolled back, be aware that the tag for the release will still be in svn. There are two possible solutions to this:
- remove the tag from svn
- pick a different version number for the release