How to automate project versioning and release with Maven
Goal
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.
Overview
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:username@cvs.server.com:/var/lib/cvs:myapp</connection>
<developerConnection>scm:cvs:ext:username@cvs.server.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>
You can find reference documentation for the <scm> tag here.
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://username@maven.vineetmanohar.com/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:
USER_HOME/.m2/settings.xml
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.
a) Pre-requisites:
- 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.
mvn release:prepare
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
mvn release:perform
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.
Reference
Related posts:




Hi Vineet,
I have few doubts about publishing the war/ear file directly to JBoss deploy folder thru Maven, i tried with jboss-maven-plugin but when i run my pom.xml its showing war deployed to jboss, but i could not see war file over there. Can you please help me out in this. Below is my pom.xml snippet.
org.codehaus.mojo
jboss-maven-plugin
1.4.1
deploy
pre-integration-test
deploy
${jbossHome}\jboss-as- web\server\desktop\deploy
local-jboss-admin
${basedir}\target\${build.finalName}.war
local-jboss-admin
http://localhost:8080/admin-console
————————————–
Here local-joss-admin i mentioned the same id in settings.xml as server id.
Please help me out in this, how to publish a war directly to jbos deploy folder.
Thanks .
Try using maven and cargo to deploy to local JBoss instance using the admin-console web interface. See this article:
http://www.vineetmanohar.com/2009/05/maven-cargo-jboss/
To deploy to remote instances, I have used scp via maven exec plugin to copy the war to cargo deploy directory.
Hi Vineet,
Thanks for publishing this article its of great help.
Actually I am in the process of conversion of an existing project into Maven & their build and release process.
My structure is like this
ParentProj
-Child1
-Child2
-ChildWeb3
-ChildWeb4
I am not sure what the maven best practices says but I am required
1. To tag all my child projects separately
2. When I transfer to by deployment server (mvn release:prepare release:perform -B), it creates sort of repository
I want to make a folder in remote server & put all the jars & wars inside it only & no other files
3. Also Is there any way to execute shell script in my remote server
Awaiting your guidance
./Irshad
The purpose of “mvn release” is to version your project and to deploy it to a standard maven repo. If you want something more custom, you should looking into “mvn wagon plugin” to copy your local jars and wars to your remote folder. Also look into “maven exec plugin” to execute a script. To execute a script remotely, you can use “maven exec plugin” with local ssh to execute remote command. The general way to execute a script remotely is: “ssh remoteuser@remotehost.name“. To run this automatically, use SSH without Password.
Congratulations for this article, only a question.
Is there any way of inherited profiling?
I am sharing a root pom.xml where configuration is shared among multiple projects, and I want to profile different distributionManagement repositories depending on a environment variable.
I notice that it is not taken from root pom.xml, either from settings.xml where it is forbidden. How would you do it without repeating the same configuration on every project?
Thanks in advance
Alberto Navarro
As Vineet knows, I’ve tried to answer myself adding much information about Maven Profiles inheritance. But I failed in publishing Xml, so I asked him permission to link directly my blog.
http://looking4q.blogspot.com/2011/01/maven-profiles-inheritance.html
Thanks, and you have one more follower.
when using CVS and no url is provided, the message below comes out:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.0:perform (default-cli) on project portal-lib: No SCM URL was provided to perform the release from -> [Help 1]
The pom.xml
scm:cvs:pserver:claudiocardozo@192.168.0.166:/cvsroot/cvsteste:sistemas
scm:cvs:pserver:claudiocardozo@192.168.0.166:/cvsroot/cvsteste:sistemas/developerConnection>
V_06_001_003_12333
how should be that URL?
vineet– I use mvn versions set command and if the project is listed as dependency i would change it manually and its a pain bumping the versions and changing the dependecy manually.I would want to do all this in a better way.Can u suggest anything??
Hi, I’m not sure how can you refer to relase as automatic perform as long as you are saying:
Section 2: The release process
“Once the configuration is done, making the release each time is very easy. Just follow these steps.
a) Pre-requisites:
Make sure that your pom.xml does not include any SNAPSHOT dependencies.”
can you do that automatically? NO, YOU CAN’T. how easy is it to release a product version with 87 dependencies all over the components it comprise? isn’t very easy, is it? SO, the rest yeah, maven-release-plugin is doing very well, as well as versions-maven-plugin is working pretty well, but you can not say that this can be done automatically as long as you have a lot of things to do manually in order to prepare the POM files to successfully release your project.
The rest… it can be found on apache and codehaus pages.
PS. I think that more interesting would be to present a strategy in order to automate all the process including automated versioning through the POM files on one hand and a control mode over all your project dependencies versions. Well this would be very interesting to see.
Have a great day,
Bogdan
No SCM URL was provided to perform the release from i am getting this error
‘svn’ is not recognized as an internal or external command,