Search |
||
Fixing two problems with Maven + Mercurial + HudsonPosted by fabriziogiudici on October 29, 2009 at 5:48 PM PDT
Today I've made some improvements with my Mercurial + Maven + Hudson
setup - and reached a new level of karma, being able to do automated
releases.
Let's go in order. First let me recap what happens with the Maven release plugin (mvn release:prepare release:perform) and Mercurial:
It's a robust sequence, as it makes sure that there are no inconsistencies in version sequences and the release is built exactly from the tagged files. But there are two specific problems with Mercurial:
I'd say that the former is a real problem, while the latter is a serious annoyance. Here how I fixed both problems. First, I've used a property in the SCM section of the pom for specifying the URL: <scm> <connection>scm:hg:http://kenai.com/hg/forceten~src</connection> <developerConnection>scm:hg:${staging.hg.repo.url}</developerConnection> <url>http://kenai.com/projects/forceten/sources/src/show</url> </scm> <properties> <staging.hg.repo.url>https://kenai.com/hg/forceten~src</staging.hg.repo.url> </properties> In this way the URL can be overridden with a property such as -Dstaging.hg.repo.url=something: the idea is to prepare a temporary, local repository where Maven pushes all the changes made for the release; furthermore, the clone at step #5 is performed from that local repository, thus saving time and bandwidth. Second, I used the altDeploymentRepository property of the deploy plugin (which is called by the release plugin) that allows to override the definition of the target Maven repository and make it point to a local folder. At the end of the process, I have that all the changes are stored locally; in other words, I've used staging repositories both for the sources and the build artifacts. If there are no errors, I can later push the local Mercurial repository to the public Mercurial repository and copy the artifacts in the Maven repository to my public Maven repository. This is the required configuraton for the maven release plugin: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <configuration> <arguments>-Dstaging.hg.repo.url=${staging.hg.repo.url} -DaltDeploymentRepository=release-repo-hudson::default::${staging.mvn.repo.url} -Dstaging.mvn.repo.url=${staging.mvn.repo.url}</arguments> </configuration> </plugin> Basically we are propagating the relevant properties to the spawned instance of Maven; there's a little verbosity as we need the Maven staging repository expressed in form of a URL (see below) while altDeploymentRepository needs it prefixed with some specific Maven repository notation. Maven should be called with these options: -Dstaging.hg.repo.url=/my/hg-staging-repo -Dstaging.mvn.repo.url=file:///my/mvn-staging-repo For copying the Maven artifacts from the staging repository to a public one the wagon-maven-plugin can be used, as it has an option to merge two repositories (goal wagon:merge-maven-repos); the required configuration is: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <configuration> <source>${staging.mvn.repo.url}</source> <target>https://services.tidalwave.it/nexus/content/repositories/releases/</target> <targetId>maven2-release-repository.tidalwave.it</targetId> </configuration> </plugin> It is possible to call it by a separate Maven invocation after the main build, or it can be specified in the goals of the release plugin: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <configuration> <goals>deploy wagon:merge-maven-repos</goals> <arguments>-Dstaging.hg.repo.url=${staging.hg.repo.url} -DaltDeploymentRepository=release-repo-hudson::default::${staging.mvn.repo.url} -Dstaging.mvn.repo.url=${staging.mvn.repo.url}</arguments> </configuration> </plugin> In this way, mvn release:prepare release:perform does all but Mercurial synchronization; the latter task just needs a regular hg push and can easily be performed by a post-build script. If I get an error, nothing gets out of my disk, so I can delete the staging repos, fix the problem and retry. It is also possible to skip the synchronization between the staging repositories and the real ones, in case one only wants to test the process. For instance, I'm trying to have the artifacts generated by the assembly plugin deployed and I'm not able to do that yet; my trials and errors can be done locally without polluting the public repositories. »
Comments
Comments are listed in date ascending order (oldest first)
Subrepositories
Submitted by ebresie on Mon, 2009-11-02 11:54.
Would Mercurial Subrepositories help?
|
||
|
|
A very neat trick. I've hit
I've hit this problem several times in the past, but it gets worse with a complex project - which I have two: One has modules which have to be built on various platforms (native code) and the other retrieves xsd source from a remote svn repository which goes down every so often.
In either case, using a staging repo ensures that the public repo only gets the change once the release build has worked completely. I'll probably give this a try at the weekend as I have a release for both of those two, and they are always a pita to release.