How to automate project versioning and release with Maven
This tutorial shows you how to tag your maven project in a source control system (like CVS, Subversion) and release the versioned “jar” or “war” to a remote repository, and all of this with a single maven command! You can even automate the entire release process by running the command in a cronjob or a Continuous Integration system.
Project lifecycle involves periodically publishing a versioned copy somewhere, and incrementing the project version. For example, every week you may increment your version from MAJOR.MINOR.<X> to MAJOR.MINOR.<X+1>, or you may choose to do a nightly build and increment your version from MAJOR.MINOR.NIGHTLY.<X> to MAJOR.MINOR.NIGHTLY.<X+1>
Maven makes the above release process very easy, and reduces it to one command.
You need to do a one time setup specifying your source control information (CVS, subversion, etc) and the repository where you would want the release published. Once the setup is complete, doing the actual release can be achieved by a typing single command. You can even automate the release by running that command in a cronjob or on your Continuous Integration server.
- Section 1 overview: describes the one time setup you need.
- Section 2 overview: describes the release process with detailed options (the impatient ones can skip this section and come back later if needed).
- Section 3 overview: describes how to automate the whole release process with a single command line
Section 1: One time configuration needed for using maven release feature
a) Declare your source control management using the <scm> tag in pom.xml
Maven will tag your project and check it in your source control system. So it needs to know the location of your source control system. You generally don’t need to specify credentials as maven inherits those from the environment. If maven needs credentials it will prompt you during the release process.
Example config for CVS in pom.xml
<project> <scm> <connection>scm:cvs:ext:firstname.lastname@example.org:/var/lib/cvs:myapp</connection> <developerConnection>scm:cvs:ext:email@example.com:/cvs:myapp</developerConnection> </scm>
Example config for SVN in pom.xml
<project> <scm> <connection>scm:svn:http://scm.vineetmanohar.com/repos/myapp/trunk</connection> <developerConnection>scm:svn:http://scm.vineetmanohar.com/repos/myapp/trunk</developerConnection> </scm>
b) Declare the remote repository where you want to publish your release to
After versioning your project, maven will deploy your project artifact (jar or war) to a remote repository of your choice.
pom.xml snippet when publishing via scp
If you have a simple maven repo hosted on apache and you have ssh access to the repo, you can publish your artifacts via scp.
<distributionManagement> <!-- Publish the versioned releases here --> <repository> <id>repo</id> <name>My maven2 repository</name> <url>scp://firstname.lastname@example.org/home/maven2/html</url> </repository> </distributionManagement>
pom.xml snippet when publishing via webdav
<distributionManagement> <!-- Publish the versioned releases here --> <repository> <id>repo</id> <name>My maven2 repository</name> <url>dav:http://nexus.vineetmanohar.com/nexus/content/repositories/</url> </repository> </distributionManagement>
pom.xml snippet when publishing via sftp
<distributionManagement> <!-- Publish the versioned releases here --> <repository> <id>repo</id> <name>My maven2 repository</name> <url>sftp://maven.vineetmanohar.com.net/repo</url> </repository> </distributionManagement>
c) Specify credentials needed to publish to the remote repo in your settings.xml file
Using scp or sftp? If you are using ssh as your underlying transfer mechanism, you can setup SSH without password to the repo machine otherwise maven will ask you to enter password each time.
Alternatively you can specify required remote repo credentials in your settings.xml file stored here:
Here’s a sample snippet.
<settings> <servers> <server> <!-- this is the id of the repo tag specified in distributionManagement --> <id>repo</id> <username>yourusername</username> <password>yourpassword</password> </server> </servers> </settings>
You can find reference documentation for the <server> tag here.
Section 2: The release process
Once the configuration is done, making the release each time is very easy. Just follow these steps.
- Make sure that your pom.xml does not include any SNAPSHOT dependencies.
- Make sure that all local changes are checked in.
- Make sure all unit tests pass
All of the above are required. The next step will gracefully fail with a warning if the above conditions are not met.
b) Run the release prepare command
This step does everything needed in order to make a release, including tagging the project, but does not actually make the release. It will check for local modifications, SNAPSHOT dependencies, calculate the release version, the next SNAPSHOT version.
Some things that you should know about the above command.
- No local modifications. This command checks for local modifications. If you have any files which are modified but not checked in, then the command will stop and ask you to first check-in modified files.
- No SNAPSHOT dependencies. Your project should not have any SNAPSHOT dependencies in your project. Its a requirement.
- Release version and next development version. You will be asked to specify the version for your release and also the next SNAPSHOT version that you want to assign to your project. Accept the default values if unsure.
- Unit tests. Maven will run your unit tests to make sure that they work after changing the project version in pom.xml.
- Tag source. If tests pass, maven will tag the source in the source control with the release version you specified in point 3 above.
- release.properties. Maven will collect all the information that you provide and write a local file called “release.properties”. This file lets you continue from where you left in case of errors.
- Undo. You can everything you’ve done so far with mvn release:clean to start over
c) Make the actual release
Once you’ve actually prepared the release using mvn release:prepare, you can make the release by typing the following command
This command uses release.properties created by the previous step and does the following
- Checks out code tagged in the previous step. It figures out the tag version from the release.properties file.
- Runs maven deploy site-deploy goals to deploy the released version. This step is responsible for deploying the jar or war to the remote repository.
- Clean up. After the release is done, release.properties file will be deleted.
Section 3: Automating the release process
Single line release process
The following command will tag source control, bump up the current pom.xml version and push a tagged artifact (jar or war) to a remote repo.
mvn release:prepare release:perform -B
For example, if your current project version was 0.92-SNAPSHOT
- The release version will be 0.92
- The next development version will be 0.93-SNAPSHOT
- The scm tag version will be artifactId-0_92
If you want to specify the versions manually, then see Section 2 above.
A single line release command is good for productivity and great for automation. You can create a build plan on your Continuous Integration server with the above command to automatically tag the current version, and automatically bump the SNAPSHOT version. This could be useful for automatically triggerd nightly releases, or manually triggered releases.