Thursday, 4 March 2010

Maven and GIT. A love story

Like most of java developers I use maven at work. It's a solid, useful tool and it integrates well with different environments, version control tools and other system components. One of the nice things that maven allows us to do it to release the build when we want to mark a certain point in development cycle when we're ready to say "ok, up to here, everything is good, and should stay the way it is". To do that we use mvn:release plugin. Released build won't have any snapshot dependencies it will have a release version number and it will be deployed to our shared repository. Integration of maven and version control system at this point is important, because the release plugin commits code with release version to your public repo, and than, after the build is created and deployed it "prepares your code for next development cycle", meaning that it commits code with next, snapshot version number.
We are using GIT as version control tool at the moment, and you can visit Petter's blog to read about an issue we found when using maven with GIT for releasing our artifacts (Petter is a friend so be nice to him). In short it's a git error you get when maven tries to push all your code (from all the branches) to public repo. It may fail even if the branch your releasing is clean and up to date, because it depends on the state of your whole tree.
As you'll see it actually led to quite heated discussion about the principles of both systems and reasoning behind the status quo and some possible solutions for that issue. All this talk is made by people smarter than me, and I'll leave the whole problem solution to them. But I believe that after all was said and done there will be one developer, who'll get to all this info after a random google search and he'll stop at the sentence in Petter's post "(...) and it leaves you with some nasty clean up. (...)" and will go postal, because he only have 5 more minutes to finish the release, it keeps failing on this stupid push, and he never really told his boss that's the first time he's using maven at all (you know who you are!) :). Well cry no more, I know you just want to know how to get this to work and that's what I'm going to tell you. Not only that, I'll also reveal the other, quite similar mvn:release and GIT glitch and give you "what to do" list for this as a bonus  treat :).

Push failed error when performing mvn:release prepare.
Make sure the push worked for the branch you're releasing from, if it didn't you probably have some unstaged changes on it, or maybe somebody push something to this branch and you didn't fetch it. Make sure your release branch is clean and up to date.

1. Create a tag and push it to public repo. Make sure the tag will have name consistent with other tag names created by mvn release plugin. Ususally it will be  <your project name>_<version>. Use existing tags names as template.

2. Checkout the tag you've just created.

3. Perform mvn deploy from this tag. Congratulations - you've performed release. There's only one thing left to be done.

4. Get back to the branch you're releasing from and change the <version></version> tag value in all your project's modules pom files to next snapshot version. Commit and push this change.

That wasn't that bad was it? To avoid the issue all together you may want to checkout the whole project in some temp directory and perform release form there, but frankly, finishing the release process manually must be much, much cooler!

GIT Pull fails when running mvn:release perform
As promised, as a bonus here's another description of an issue we discovered when using maven with GIT for releasing. It's not that common but it's equally annoying  when you don't know what to do with it and I think it's actually harder to solve.
The problem happens when maven pulls all the code from remote repo to get latest release code that it want's create a released build from. Sometimes you may get conflicts at this point, and instead of deployed artifact you'll get a build failure and GIT error. This also can be solved manually:

1. Go into the directory the pull is made to (usually it will be you're project's target/checkout directory).
2. Manually perform the merge - use git mergetool command
3. In the same directory run mvn deploy, so you can finish the release.
4. As previous solution make sure you'll change the version tags to next snapshot version number,

Make sure you'll read Petter's post and have a look at the defect he reported and discussion that unraveled in defect's comments section if you're interested in this issue.

1 comment:

  1. Thank you very much for placing this information on the Internet.

    I have been struggling with creating a minor release (bug fix) from 18:00 to 02:30 and 07:00 to 8:00 this morning and using your information I was able to figure out that it wasn't my secure connection causing problems or some other maven magic.

    I eventually solved it by upgrading to maven 3 where the new release plugin is used.

    Peter Veentjer
    Multiverse: Software Transactional Memory for Java