Performing Maven Releases on Kenai with Hudson

This article follows on from my previous article where I covered how to get a maven repository working on Kenai.com as they currently do not provide a maven repository and describes how to get Hudson to perform maven releases into that repository automatically.

Configuring Hudson for releasing your project

Maven configuration

The first part is to prepare your project’s pom.xml defining both the scm and distributionManagement elements:

For scm we define the url to point to the remote source repository. Unfortunately you have to put a username in here and you cannot define a connection entry:

<scm>
        <developerConnection>scm:hg:ssh://petermount@hg.kenai.com/reteptools~hg</developerConnection>
        <url>https://kenai.com/hg/reteptools~hg</url>
    </scm>

Next the distributionManagement element. Here we define it to point to the local copy of our repository that we created in the earlier article:

<distributionManagement>
        <repository>
            <uniqueVersion>false</uniqueVersion>
            <id>retep.releases</id>
            <name>Retep.org repository</name>
            <url>file:/Users/peter/repository/reteptools~maven/releases</url>
        </repository>
    </distributionManagement>

Hudson configuration

Next for Hudson. I’m running Hudson 1.306 but this should work for earlier versions. You’ll need to install following plugins via Hudson’s plugin manager:

Once the plugins are installed and hudson restarted you need to create the job that will perform the release:

Under Source Code Management select Mercurial and enter the repository url on kenai.

Next under Build enter the following for Goals and options:

Here I define maven.repo.local to a unique one so that my local development and release repositories are separate to prevent accidentally mixing the two.

Next we need to configure the job to manage the subversion repository. Under Build Environment check M2 Extra Build Steps and add the following two build steps:

In Steps to run before mvn build add the following script which will update the local repository:

cd /Users/peter/repository/reteptools~maven/releases
  svn update

Then in Steps to run after mvn build add the following which will add the final artifacts and commit them:

cd /Users/peter/repository/reteptools~maven/releases
  svn add * --force
  svn commit -m "Release $BUILD_TAG $BUILD_ID"

Finally check Maven release build. The default goals and options should suffice.

Performing an actual release

Unless this is the first time you’ve run the job, enter your job and select Workspace followed by Wipe Out Workspace then confirm. The purpose of this step is to ensure everything is clean and hudson will perform a fresh clone from the repository.

Next select Perform Maven Release. Check Specify release version(s) to confirm that the version numbers match what you want:

When you are happy then select Schedule Maven Release Build.

If all goes well then you should find that Hudson performs the release – although depending on how fast your network connection is you may want to go and make a cup of Coffee…

Example output

If you watch the Console Output, you should see something like the following:

First release:prepare makes a clone and runs a build and all tests:

Started by user peter
$ hg clone ssh://petermount@hg.kenai.com/reteptools~hg /Users/peter/.hudson/jobs/release_retepTools/workspace
requesting all changes
adding changesets
adding manifests
adding file changes
added 244 changesets with 1491 changes to 1013 files (+1 heads)
updating working directory
426 files updated, 0 files merged, 0 files removed, 0 files unresolved
Parsing POMs
[workspace] $ /bin/sh -xe /tmp/hudson44025.sh
+ cd /Users/peter/repository/reteptools~maven/releases
+ svn update
At revision 7.
[workspace] $ java -cp /Users/peter/.hudson/plugins/maven-plugin/WEB-INF/lib/maven-agent-1.306.jar:/usr/local/apache/apache-maven-2.0.9/boot/classworlds-1.1.jar hudson.maven.agent.Main /usr/local/apache/apache-maven-2.0.9/ /Users/peter/.hudson/war/WEB-INF/lib/remoting-1.306.jar /Users/peter/.hudson/plugins/maven-plugin/WEB-INF/lib/maven-interceptor-1.306.jar 65499
channel started
Executing Maven:  -B -f /Users/peter/.hudson/jobs/release_retepTools/workspace/pom.xml -Dproject.dev.uk.org.retep:retepTools-generator=9.6-SNAPSHOT -Dproject.rel.uk.org.retep:retepTools-generator=9.5 -Dproject.dev.uk.org.retep.tools:retepTools=9.6-SNAPSHOT -Dproject.rel.uk.org.retep:retepTools=9.5 -Dproject.dev.uk.org.retep:retepTools=9.6-SNAPSHOT -Dproject.rel.uk.org.retep.tools:retepTools=9.5 -Dresume=false release:prepare release:perform
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   retepTools
[INFO]   retepTools Source Generator
[INFO]   retepTools Core
[INFO] Searching repository for plugin with prefix: ‘release’.
[INFO] ------------------------------------------------------------------------
[INFO] Building retepTools
[INFO]    task-segment: [release:prepare, release:perform] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [release:prepare]
[INFO] Verifying that there are no local modifications...
[INFO] EXECUTING: hg status
[INFO] [release.properties:unknown]
[INFO] Checking dependencies and plugins for snapshots ...
[INFO] Transforming ‘retepTools’...
[INFO] Transforming ‘retepTools Source Generator’...
[INFO] Transforming ‘retepTools Core’...
[INFO] Updating retepTools-generator to 9.5
[INFO] Not generating release POMs
[INFO] Executing goals ‘clean verify’...
[INFO] Executing: mvn clean verify --no-plugin-updates --batch-mode
[INFO] Scanning for projects...
        [INFO] Reactor build order: 
        [INFO]   retepTools
        [INFO]   retepTools Source Generator
        [INFO]   retepTools Core

next it updates the pom’s to the new release and commits them in tagging as it does so:

[INFO] 
        [INFO] 
        [INFO] ------------------------------------------------------------------------
        [INFO] Reactor Summary:
        [INFO] ------------------------------------------------------------------------
        [INFO] retepTools ............................................ SUCCESS [2.486s]
        [INFO] retepTools Source Generator ........................... SUCCESS [4.260s]
        [INFO] retepTools Core ....................................... SUCCESS [2:47.495s]
        [INFO] ------------------------------------------------------------------------
        [INFO] ------------------------------------------------------------------------
        [INFO] BUILD SUCCESSFUL
        [INFO] ------------------------------------------------------------------------
        [INFO] Total time: 2 minutes 54 seconds
        [INFO] Finished at: Tue May 19 19:53:00 BST 2009
        [INFO] Final Memory: 37M/80M
        [INFO] ------------------------------------------------------------------------
        [INFO] Checking in modified POMs...
[INFO] EXECUTING: hg commit --message “[maven-release-plugin] prepare release retepTools-9.5” /Users/peter/.hudson/jobs/release_retepTools/workspace/pom.xml /Users/peter/.hudson/jobs/release_retepTools/workspace/generator/pom.xml /Users/peter/.hudson/jobs/release_retepTools/workspace/core/pom.xml
[INFO] EXECUTING: hg push ssh://petermount@hg.kenai.com/reteptools~hg
[INFO] Tagging release with the label retepTools-9.5...
[INFO] EXECUTING: hg tag --message “[maven-release-plugin]  copy for tag retepTools-9.5” retepTools-9.5
[INFO] EXECUTING: hg push ssh://petermount@hg.kenai.com/reteptools~hg
[INFO] EXECUTING: hg locate
[INFO] Transforming ‘retepTools’...
[INFO] Transforming ‘retepTools Source Generator’...
[INFO] Transforming ‘retepTools Core’...
[INFO] Updating retepTools-generator to 9.6-SNAPSHOT
[INFO] Not removing release POMs
[INFO] Checking in modified POMs...
[INFO] EXECUTING: hg commit --message “[maven-release-plugin] prepare for next development iteration” /Users/peter/.hudson/jobs/release_retepTools/workspace/pom.xml /Users/peter/.hudson/jobs/release_retepTools/workspace/generator/pom.xml /Users/peter/.hudson/jobs/release_retepTools/workspace/core/pom.xml
[INFO] EXECUTING: hg push ssh://petermount@hg.kenai.com/reteptools~hg
[INFO] Release preparation complete.

Then it starts release:perform. Here it makes a fresh clone but this time for the newly created tag and compiles it again:

[INFO] [release:perform]
[INFO] Checking out the project to perform the release ...
[INFO] Removing /Users/peter/.hudson/jobs/release_retepTools/workspace/target/checkout
[INFO] EXECUTING: hg clone -r retepTools-9.5 ssh://petermount@hg.kenai.com/reteptools~hg /Users/peter/.hudson/jobs/release_retepTools/workspace/target/checkout
[INFO] EXECUTING: hg locate

...

        [INFO] Uploading project information for retepTools 9.5
        [INFO] Retrieving previous metadata from retep.releases
        [INFO] Uploading repository metadata for: 'artifact uk.org.retep:retepTools'
        Uploading: file:/Users/peter/repository/reteptools~maven/releases/uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar
        783K uploaded
        Uploading: file:/Users/peter/repository/reteptools~maven/releases/uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar
        2383K uploaded
        [INFO] 
        [INFO] 
        [INFO] ------------------------------------------------------------------------
        [INFO] Reactor Summary:
        [INFO] ------------------------------------------------------------------------
        [INFO] retepTools ............................................ SUCCESS [4.546s]
        [INFO] retepTools Source Generator ........................... SUCCESS [5.987s]
        [INFO] retepTools Core ....................................... SUCCESS [2:47.913s]
        [INFO] ------------------------------------------------------------------------
        [INFO] ------------------------------------------------------------------------
        [INFO] BUILD SUCCESSFUL
        [INFO] ------------------------------------------------------------------------
        [INFO] Total time: 2 minutes 58 seconds
        [INFO] Finished at: Tue May 19 19:58:10 BST 2009
        [INFO] Final Memory: 40M/80M
        [INFO] ------------------------------------------------------------------------
        [INFO] Cleaning up after release...
[HUDSON] Archiving /Users/peter/.hudson/jobs/release_retepTools/workspace/pom.xml to /Users/peter/.hudson/jobs/release_retepTools/modules/uk.org.retep.tools$retepTools/builds/2009-05-19_19-50-00/archive/uk.org.retep.tools/retepTools/9.5-SNAPSHOT/pom.xml
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8 minutes 9 seconds
[INFO] Finished at: Tue May 19 19:58:10 BST 2009
[INFO] Final Memory: 11M/27M
[INFO] ------------------------------------------------------------------------
channel stopped

finally it adds and commits the new artifacts into subversion. Once this step completes your release is publicly available.

[workspace] $ /bin/sh -xe /tmp/hudson44036.sh
+ cd /Users/peter/repository/reteptools~maven/releases
+ svn add uk --force
A         uk/org/retep/maven-metadata.xml
A         uk/org/retep/maven-metadata.xml.md5
A         uk/org/retep/maven-metadata.xml.sha1
A         uk/org/retep/retepTools/9.5
A  (bin)  uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar
A         uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar.md5
A         uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar.sha1
A  (bin)  uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar
A         uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar.md5
A         uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar.sha1
A  (bin)  uk/org/retep/retepTools/9.5/retepTools-9.5.jar
A         uk/org/retep/retepTools/9.5/retepTools-9.5.jar.md5
A         uk/org/retep/retepTools/9.5/retepTools-9.5.jar.sha1
A         uk/org/retep/retepTools/9.5/retepTools-9.5.pom
A         uk/org/retep/retepTools/9.5/retepTools-9.5.pom.md5
A         uk/org/retep/retepTools/9.5/retepTools-9.5.pom.sha1
...
+ svn commit -m 'Release hudson-release_retepTools-15 2009-05-19_19-47-45'
Adding         releases/uk/org/retep/maven-metadata.xml
Adding         releases/uk/org/retep/maven-metadata.xml.md5
Adding         releases/uk/org/retep/maven-metadata.xml.sha1
Adding         releases/uk/org/retep/retepTools/9.5
Adding  (bin)  releases/uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar.md5
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5-javadoc.jar.sha1
Adding  (bin)  releases/uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar.md5
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5-sources.jar.sha1
Adding  (bin)  releases/uk/org/retep/retepTools/9.5/retepTools-9.5.jar
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5.jar.md5
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5.jar.sha1
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5.pom
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5.pom.md5
Adding         releases/uk/org/retep/retepTools/9.5/retepTools-9.5.pom.sha1
Sending        releases/uk/org/retep/retepTools/maven-metadata.xml
Sending        releases/uk/org/retep/retepTools/maven-metadata.xml.md5
Sending        releases/uk/org/retep/retepTools/maven-metadata.xml.sha1
...
Adding         releases/uk/org/retep/tools/retepTools/maven-metadata.xml
Adding         releases/uk/org/retep/tools/retepTools/maven-metadata.xml.md5
Adding         releases/uk/org/retep/tools/retepTools/maven-metadata.xml.sha1
Transmitting file data .......................................
Committed revision 8.
Finished: SUCCESS

That’s it, the release process is now fully automated and can be repeated with a couple of clicks.

Setting up a Maven repository on Kenai

Over at Project Kenai one minor issue is that it doesn’t currently support maven repositories. Although it is on their list of features to implement it’s probably not going to be available for a while.

So what if your project needs a public maven repository on Kenai?

Well the trick is to:

    add an additional subversion repository to your project which will host your repository.
  • Then on your local machine check out that new repository and tell maven to deploy to that directory instead of a remote repository.
  • Manually add any new files that have been added by maven
  • commit the changes

To use the repository simply use the subversion repositories public url as a repository definition.

Here’s the gory details on what to add to your pom’s. For all of these examples you will need to substitute reteptools~maven with the name of your subversion repository. I’m using a releases subdirectory within the repo but that is optional.

In your pom.xml you need to add a distributionManagement element pointing to your local checked out copy of the repository. If your project has child modules in it you can put this into the parent pom as it will be inherited.

    <distributionManagement>
        <repository>
            <uniqueVersion>false</uniqueVersion>
            <id>retep.releases</id>
            <name>Retep.org repository</name>
            <url>file:/Users/peter/repository/reteptools~maven/releases</url>
        </repository>
    </distributionManagement>

Next if your pom’s need to refer to your public repository you need to reference it with a repository and/or pluginRepository definition. In this case you need to use http://kenai.com/svn/ and your project~repository name as the url. Here’s what you would use to access my repository on kenai:

        <repository>
            <id>retep.releases</id>
            <name>retep.org Maven 2 Repository</name>
            <url>http://kenai.com/svn/reteptools~maven/releases/</url>
        </repository>

        <pluginRepository>
            <id>retep.releases</id>
            <name>retep.org Maven 2 Repository</name>
            <url>http://kenai.com/svn/reteptools~maven/releases/</url>
        </pluginRepository>

Now you have done this, you can build as normal. However when it comes to deploying you first run:

 mvn deploy

to deploy to your repository. Because of the distributionManagement element it will deploy to your checked out copy.

Next change directory into your repository and add any new files:

 cd /Users/peter/repository/reteptools~maven/releases
 svn status
 svn add ...add any files shown as unknown...
 svn commit -m “brief commit message”

That’s all there is to it.

At some point I’m going to see if it’s possible to automate the commit process into subversion, but for now this works.

Update:

2009-04-24 12:14: ODFToolkit (which uses a subset of kenai and was partly why I started looking into this issue) doesn’t have subversion available just Mercurial so we had the question – would this work with mercurial.

Well it looks like it is possible, just base your repository path with the template: http://kenai.com/hg/projectName~repositoryName/raw-file/tip/

This appears to serve the files cleanly.