Saturday, December 6, 2008

Lazy dog for releasing with Maven and Subversion

Lazy dog for releasing with Maven and Subversion

Introduction

We release software with where new features are added to 1.0.0, 1.1.0, 1.2.0, and so on. Maintenance releases of 1.0.0 are numbered 1.0.1, 1.0.2, and so on.

We use the branch-before-release pattern with the following structure.

Directory structure

trunk/

branches/

tags/

where development is done on trunk with the following standard Maven structure:

trunk/pom.xml

trunk/src

trunk/target

After a branch of trunk 1.0-SNAPSHOT, the trunk/ structure is created in directory branches:

branches/1.0.x

After a release in the branch directory, the structure is created in directory tags:

tags/1.0.0

Version numbers in pom.xml

When creating branch 1.0 from trunk, we get the following versions in pom.xml:
* trunk: 1.0-SNAPSHOT 1.1-SNAPSHOT
* branch: 1.0-SNAPSHOT

where trunk will be the next development version.


When creating the first maintenance release 1.0.1 on branch 1.0, we get the following versions in pom.xml:

* branch 1.0.0-SNAPSHOT -> 1.0.1-SNAPSHOT


When creating release on branch 1.0 with mvn release:prepare, we supply the following version numbers:

  • release version 1.0.0 for the first release,
  • release version 1.0.1 for the first maintenance, ... and so on.


Steps to branch and release


Assume that you have set up Maven pom.xml with <scm> tag, a work directory named work and SVNURL is the URL to the source code repository. Optionally you have an <distributionManagement> tag that mvn deploy uses to put its artifacts after a build.


Run the following steps to create a release,

1 Create branch

(e.g trunk pom.xml version 1.0-SNAPSHOT branch 1.0-SNAPSHOT, branch name=1.0.x)

  1. cd work 
  2. svn co SVNURL/trunk 
  3. cd trunk
  4. mvn release:branch -DbranchName=1.0.x -DscmCommentPrefix='[AR-10 create branch 1.0.x and trunk version 1.1]' -DautoVersionSubmodule=true --batch-mode 
    1. To test, run with -DdryRun=true instead of --batch-mode, then
      1. Maven will prompt: What is the working copy version for ...? Enter: 1.1-SNAPSHOT
      2. clean up by running: mvn release:clean; mvn clean; svn status;
      3. Additional cleanup: svn status | awk '{print $2}' | xargs rm
    2. Add -Dmaven.test.skip=true speeds up the process - after all, it's an administrative command (copy from one SVN location from trunk to branch, change SCM in branch ( step version in pom.xml's and change SCM location... :-)
    3. If you get "Cannot commit - the source is from another location":
      1. run svn info, it should be equal to <scm> in pom.xml. For example, I had checked out from url: svn+ssh://arr@server.com, and svn+ssh://server.com in pom.xml's <scm>.
      2. Workaround: check out from the URL specified in the pom.xml's <scm>.

2 Create release tag from branch

(e.g branch pom.xml has version=1.0[.0]-SNAPSHOT releaseVersion=1.0.0)

  1. cd work

  2. svn co SVNURL/branches

  3. cd branches/1.0.x

  4. mvn release:clean release:prepare -Dtag=1.0.0 -DreleaseVersion=1.0.0 -DscmCommentPrefix='[AR-10 create release 1.0.0 on branch 1.0.x]' -DautoVersionSubmodule=true ---batch-mode

    1. Test as for Create branch.If you omit --batch-mode, then Maven will prompt for:

      1. What is the release version for...? Enter: 1.0.0
      2. What is the development version for ...? Enter: 1.0.1-SNAPSHOT
    2. If build/commit fails, you get "Unable to download the artifact" for task-segment: [clean, verify] (we get this for an artifact msec-bankidclient):
      1. Go to directory branches/1.0.x (that contains files to be commited for tag 1.0.0).
        1. Copy to tags/1.0.0 by running: svn cp SVNURL/branches/1.0.x SVNURL/tags/1.0.0
      2. Step the version number from 1.0.0 to 1.0.1-SNAPSHOT
        1. find . -name 'pom.xml' -exec perl -i -pne 's#<version>1.0.0</version>#<version>1.0.1-SNAPSHOT</version>#' {} \;
      3. Change <scm> from tags/1.0.0 to branches/1.0
        1.  perl -i -npe 's#tags/1.0.0#branches/1.0.x#' pom.xml
      4. Commit to branch 1.0.x
        1. svn commit -m 'AR-10 stepped version and scm location.'

3 Build release from tag

(e.g. tag 1.0.0)

  1. cd work

  2. svn co SVNURL/tags/1.0.0

  3. cd tags/1.0.0

  4. mvn clean install [deploy site-deploy]

    1. If deploy prompts for password, you can <distributionManagement>add server ID, username and password


If svn commit goes wrong inside an mvn release:* command, run:

mvn release:rollback to revert committed changes, before mvn release:clean.


Improvements

Can be automated:

  • branchName is version from trunk/pom.xml minus -SNAPSHOT

  • releaseVersion is ${branchName} + . + last version from pom.xml


References



2008-12-06 Arne Riiber - Initial version
2008-12-09 Arne Riiber - Updated with fixes for cases when plugin fails. Set branch name to 1.0.x.


No comments: