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.

  1. 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.
  2. No SNAPSHOT dependencies. Your project should not have any SNAPSHOT dependencies in your project. Its a requirement.
  3. 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.
  4. Unit tests. Maven will run your unit tests to make sure that they work after changing the project version in pom.xml.
  5. Tag source. If tests pass, maven will tag the source in the source control with the release version you specified in point 3 above.
  6. 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.
  7. 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

  1. Checks out code tagged in the previous step. It figures out the tag version from the release.properties file.
  2. 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.
  3. 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

  1. The release version will be 0.92
  2. The next development version will be 0.93-SNAPSHOT
  3. 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:

  1. Tweet your builds with Maven Twitter Plugin
  2. How to display maven project version in your webapp
  3. 3 ways to run Java main from Maven
  4. Publishing to Maven Central Repo in 5 steps
  5. The plugin ‘org.codehaus.mojo:selenium-maven-plugin’ does not exist or no valid version could be found

11 comments to How to automate project versioning and release with Maven

  • Sreekar

    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 .

  • vineet

    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.

  • Irshad

    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

  • vineet

    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?

  • Buildit

    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??

  • Bogdan

    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

  • pradeep

    No SCM URL was provided to perform the release from i am getting this error

  • pradeep

    ‘svn’ is not recognized as an internal or external command,

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Get Adobe Flash playerPlugin by wpburn.com wordpress themes