Tuesday, November 9, 2010

Maven and Continuous Delivery

There has been an interesting discussion going on recently in the Maven user group list about Continuous Delivery:


My colleague here at ThoughtWorks, Jez Humble, contends that the SNAPSHOT model that Maven uses is prohibitive to many of the principles espoused in his book. And I have to say, I largely agree with him.

Before diving into why I agree with him, it's worthwhile to add a bit of context. I'm one of a minority of people in ThoughtWorks that prefer Maven to Ant. That's not to say that we don't deliver projects using Maven, but if given a choice, most ThoughtWorkers prefer Ant. Personally, I have had a long history of using Maven, starting with my work with Spring Batch. That's not to say that Maven doesn't have it's problems, but if given a choice, I'll start a project with Maven. (Why that's the case would certainly be worthy of another blog post) I mention all of this because I am not bringing up issues with the release model of Maven to bash it because I hate the tool. I bring it up because I think there can be improvements in how Maven thinks about and deals with releases.

I remember the first time I had to cut a release with Maven oh so many years ago. I had my project working, everything was in exactly the state I wanted it to be into for release. All I needed to do was create the final cut. Like a good Maven user, I went to check out the documentation for how Maven approached releases. I quickly found the section on the release plugin and thought 'Aha, I just need to use this plugin, and my release will be painless, thanks Maven!' Of course, reality is never that simple. The maven release project has two 'phases' prepare, and then the actual release. Below is a list of what Maven does during the prepare phase, shamelessly pulled from the official plugin site:
  • Check that there are no uncommitted changes in the sources
  • Check that there are no SNAPSHOT dependencies
  • Change the version in the POMs from x-SNAPSHOT to a new version (you will be prompted for the versions to use)
  • Transform the SCM information in the POM to include the final destination of the tag
  • Run the project tests against the modified POMs to confirm everything is in working order
  • Commit the modified POMs
  • Tag the code in the SCM with a version name (this will be prompted for)
  • Bump the version in the POMs to a new value y-SNAPSHOT (these values will also be prompted for)
  • Commit the modified POMs
The SCM related bits make sense. Of course you need to create a tag that coincides with the release. However, the majority of the remaining bullets are around modifications to the POM files themselves, and checking that other POM files aren't in a 'SNAPSHOT' state.

I didn't understand that process years ago, and I still don't understand it today. I have my codebase, I've tested it thoroughly, both with unit, integration, automated, and manually testing. I just want to take the 'binary' that I've been using, and promote it to production while also taging the SCM revision that created it. Why does a snapshot state even matter? I suppose with external dependencies there are some concerns about APIs changing underneath you. However, what does it matter, you have working code, right now, surely the changing API is a problem for tomorrow, not the release of today?

In my time at ThoughtWorks, and other consulting experience, I have always prognosticated that the same build that a developer makes on his machine, and ultimately what will come out of CI (because he or she commits that revision) should look as identical as possible to what will be in production. Why add an extra step to change anything at all?

In short, I agree with Jez, why can't every artifact created from mvn deploy be potentially a release into production? The only value I've seen the snapshot concept add is away to describe a dependency as 'whatever the latest CI has produced is'. It seems to me its just as easy to say: 'any release greater than x.y' and call it a day, which is something Maven supports now as well, at least from a dependency declaration perspective.


Jason van Zyl said...

Unfortunately, but naturally, users tend to think that the release plugin embodies all best practices for Maven with respect to releases, but in practice many people accept it's flaws -- for which there are many -- or remake their own tools.

I believe the separation of snapshot and release repositories are required but the extraction of a release should happen as the process of extracting that release from a stream of potential releases. Given you could assert all conditions of the build you should be able to tag the code, and pluck the snapshot out and promote it to a release repository.

I don't think you would have any disagreements with you from a release management perspective. Someone just needs to do the two weeks of work to add the tooling.

Michael Hüttermann said...

in my opinion the best approach is: people over processes over tools.

Thus Maven's release plugin can be the best choice in the case your process is exactly what the plugin offers. In other cases, you need to set up an infrastructure that maps to your release process. I agree with Jason, this often is part of the activities of (technical) release management.

I like Maven and its concepts. That said, the process of chosing the right tool is aligned with concrete requirements. As a result of this Ant can be the best choice in a specific situation, in other cases it is Maven or something completely different.

Curt Yanko said...

I have never cared for the release plugin either, didn't make sense to me. Still the idea of transmorgafying your SNAPSHOTS into a *release* is fine if you your not worried about reproducibility. The amount of effort to compensate for that is on the wrong side of an 80/20 equation imo. Sadly, far too many Maven users devolve into using SNAPSHOTS for the wrong reasons, namely laziness. The byproduct of years of neglect for the build process in general as a second class, low value, activity not worthy a a developers attention or time.

Ant clearly lends itself to CD because it doen't try to manage the build dependencies, a simple *.jar in the 'ol lib folder will do, thank you very much. And why not? It's all in there right? ...managed by good 'ol SCC tools. But Maven wants you to be more prescriptive about those yet out of old habits many see SNAPSHOTS as the mechanism to keep doing things the old,l easy, way.

In Maven, when you have *value* you need to release it (pin it down so-to-speak). Myself and others in that thread did flip the problem around and re-approached it with Dependency ranges in mind which imo provides a much clearer path forward to craft a plugin that can meet the needs of CD. Dependency ranges provide the ease-of-use of SNAPSHOTs but resolve to real, released, versions at build time which can be captured and codified.

I'm sure I have a lot to learn about CD but I'm also sure the Maven community will get there.

Christopher said...

I must say that I followed this thread on the Maven Users list and got a little lost with it. I don't really understand where Jez is coming from.

From my own perspective, I've never had an issue with the release plugin. I like how it works; particularly when you have many developers all working on the same thing and you want to take something out of the CI stream at a particular rev and then release it.

I wonder if this debate is an academic one, or whether there really was some issue Jez came across to fuel the debate. If it is the latter then it'd be great to hear about what happened in reality.

Maybe Thoughtworks should develop a new release plugin also given that I don't see Maven itself being the issue.

dantheperson said...

However, what does it matter, you have working code, right now, surely the changing API is a problem for tomorrow, not the release of today?

Snapshots changing beneath you is a problem for tomorrow, but it's a problem you need to solve today.

So you've released 1.1.1 and a couple days later a critical bug is discovered and you need to do an emergency intra-day release.

Work on trunk has continued on features that are user visible and you don't want to release them till the next regular release after the end users have been notified of the changes.

No problem, just create a branch from your 1.1.1 release tag, fix the bug, and build 1.1.2 right?

Not if you have snapshot dependencies, because when you checkout the source and build, it pulls down the latest snapshot dependencies which are going to be newer than the one you pulled in last week, which might not compile, or even worse will have subtle bugs that only show up during the exhaustive testing that you don't have time to give to this emergency patch release.

So as your builds aren't repeatable with snapshot dependencies, the path you have to take is to start with your last binary distribution, and patch in just the jar you want. And once you've done that you're distributing binary images that you can't rebuild from source. Good luck supporting that.

Danijel Arsenovski said...


Finally, you can always NOT use snapshots. If the team works on the same artifact, no need to use snapshot mechanism to update the binaries anyway and the current project will be updated through code repository. Dependencies can be updates through mvn versions:display-dependency-updates.

madbande said...

It seems, tertiary education students will soon be able to complete not only the simplest tasks but go through gradually planned research on the given topic for their universities. I believe it because term papers online at papersmart.net don't lack experience in writing short pieces for my class-mates and college friends. This service does its job the same way our goals are set and can refer to the act of reflection of an educated person

Paul Rule said...

John Smart has a great presentation on CD with maven:


If I understand it correctly:

1. Build system branches /module/trunk when a commit is detected
2. Set the version of the module to be ..
3. Set the snapshot dependencies of the module to be latest release
4. Maven build, test, verify…
5. If successful deploy artefact to artifactory so it is available to other builds – presumably the branch then gets tagged (not sure about this)

Changing the versions (from snapshot) in the pom are done using the maven versions plugin.

To change the version of your module:

If your module depends on a snapshot of one of your other modules, already built and released by CI update those dependencies to releases:

It sounds simple and effective, I can't wait to try it out on my pet projects.

An Binh said...

Canh chua cá lóc là món ăn từ lâu đã quen thuộc với người dân Việt Nam đặc biệt là ở vùng miền tây Nam Bộ, buổi trưa hè nắng nóng mà được ăn tô canh chua cá lóc, kèm với món cá lóc kho tộ thì mọi cảm giác mệt mỏi sẽ bay biến mất. Bep 247 sẽ hướng dẫn các bạn cach nau canh chua ca loc thơm ngon hơn để bữa ăn gia đình thêm phong phú, hấp dẫn và giúp các thành viên trong gia đình đánh bay cái nắng nóng, mệt mỏi ngày hè nhé. Và một hương vị chua cay thơm ngon không kém gì món canh chua cá lóc đấy là món lẩu thái. Vào những buổi liên hoan tụ tập bạn bè hay những ngày trời se lạnh thì lẩu chính là sự lựa chọn số 1 và tuyệt vời nhất phải không nào. Nhắc đến Lẩu chắc hẳn là món quen thuộc ai cũng đã từng thưởng thức, lẩu là món dễ ăn và được nhiều người yêu thích nhất là lẩu Thái.
Lẩu thái mang một hương vị khác biệt không lẫn với bất kỳ món lẩu nào khác bởi vị nước lẩu chua chua cay cay, với hương thơm của riềng, xả nhúng kèm với các loại rau và hải sản tươi sống.
cách nấu lẩu thái chua cay cũng không khó hay cầu kì và các chị em nội trợ nào cũng có thể nấu ngon, hãy xuống bếp để trổ tài với món lẩu thái hải sản nào.

Larry Morales said...

Brilliant article. The way you present the topic is highly appreciable. Expecting more informative posts.Essay writing services

Milen Abraham said...

I conducted a research on Maven launch and release. It was a great experience for me. I have learned many new things and techniques through my research. You can review and evaluate my findings by just visit here: buy dissertation online

Jam Herry said...

Thus Maven's release plugin can be the best choice in the case your process is exactly what the plugin offers. In other cases, you need to set up an infrastructure that maps to your release process. any review on efactor diet

Kiley Muller said...

If you're a creative thinker and like to explore alternative solutions to problems, no doubt you should try writing service.
Value of Market Research Project Help

Suzzane Joanna said...

I’m really impressed with your article, such great & usefull knowledge you mentioned here
Student Essay Writing

Eden Alaster said...

This is an excellent post i seen.I have to thanks to you to share it. It is really what I wanted to see hope in future you will continue for sharing such a excellent post.
Accounting Online Homework Help