3 minute read

Why is that? Simple. I don’t do it by definition. Oh, yeah, I’ve finally read Continuous Delivery book by Jez Humble and David Farley. I mean, the book got published in 2010, it’s about time.

This post is not a review of the book. Sufficient to say, I liked it and I recommend reading it. It triggered me a bit conflating “release” and “deployment” as well as making a very common but special case of a single customer/single production environment the focus of the book. You know, some software products are not even applications, and the concept of “deployment” is not even applicable to them. Not important now, we can talk about it some other day.

I decided to read this book in order to answer the question: why trunk-based development is promoted so heavily by the DevOps community. Apparently, it has something to do with continuous integration and continuous delivery.

And I think I may have found something. From chapter 14 in the book, where the authors discuss the acceptable reasons to create branches:

First, a branch can be created for releasing a new version of your application. This allows developers to continue working on new features without affecting the stable public release. When bugs are found, they are first fixed in the relevant public release branch, and then the changes are applied to the mainline. Release branches are never merged back to mainline.

Just like this, no warning shots, no explanation why. This seems to represent a deeply engraved belief of the authors requiring no further discussion: no merges from the release branches to the mainline. The bug fixes are not merged but rather reimplemented. These days, with a modern version control tool, this would be a cherry-pick.

If this approach is consistently practiced, the connection between the release branches and the mainline quickly grows weaker, and indeed, the statement that if you don’t push to the mainline you’re not integrating becomes true.

This looks like a self-fulfilling prophecy or, if you will, a self-inflicted injury. I advocate exactly the opposite approach: a sequence of merges to all affected long-lived branches done promptly after the fix in order to avoid regression. All commits present in the earlier branches are also present in the later branches and in the mainline. This is a fundamental relation between branches, and not just for fixes, for all types of changes.

Another thought I had reading the book is that in 2010 CruseControl and Hudson represented the state of the art, and many teams do not even have any automated CI build. The tools that use “pipeline as code” approach and automated builds for any existing branch came later. Was it Jenkins that pioneered the concept around 2016? Could this be a contributing factor of selecting just one long-lived branch for the source of truth about the builds?

Back to the title of this post. The book says:

If different members of the team are working on separate branches or streams, then by definition they’re not continuously integrating. Perhaps the most important practice that makes continuous integration possible is that everybody checks in to mainline at least once a day. So if you merge your branch to (not just from) mainline once a day, you’re OK. If you’re not doing that, you’re not doing continuous integration.

No, I cannot say that every developer on the teams I was involved with committed and pushed to master daily. I can say that on average master was updated several times a day but this is not the same thing, is it? Two things stood in the way. The company mandated using feature branches and pull requests to facilitate code reviews. The code would not get merged until it is more or less ready, and that would often take longer than a day. More importantly, the teams followed the SemVer branching and again, the regression avoidance merges would not happen until the code is “done”, not necessarily daily.

How does it make me feel? I guess I’m OK with it. The point is not just using the name but the goals we want to achieve. We get automated builds with unit and acceptance tests done on every branch, fast feedback from the tests, and ready to deploy code in every long-lived branch we need to maintain. I think we’re hitting the mark. I just need to come up with another name that abbreviates to “CI”, so that when I get questions from my superiors: “Are we doing CI?”, I could confidently answer: “Of course we do!” Constant Integration? I’ll think about it.

Oh yeah, and sorry for the clickbait title. Thank you for reading.

Updated: