When I don't (exactly) use Trunk-Based Development
April 11, 2022Today I go on record admitting I don't always use TBD, I do sometimes use long-lived branches, and I sometimes even share a branch with another dev.
One topic that comes back constantly is git branching models. It’s no secret that I don’t like GitFlow, and generally advocate using trunk-based development (TBD) instead. But there are a few cases where TBD isn’t enough, and I want to talk about a couple of them.
Both of these examples come from open-source work. Although the first one can apply to a wide number of products, the second one will be extremely rare.
Long-term support releases
The scenario is that you may use TBD for normal, day-to-day development work, but as a business decision, you choose to also continue to maintain one or more old versions of your software with some subset of changes (such as bug fixes and/or security updates only).
The approach I use (for example on my Kivik project), is essentially the same as the one promoted at TrunkBasedDevelopment.com as “branch for release”. Whenever I’m ready to create a new major release, I create a new release branch, based on the major version number, i.e.
v3. As long as
v3remains under active long-term support (however that’s defined for your project), then any relevant bugfixes or security patches can be cherry-picked from the mainline branch into
v3. Or in rare cases, a change may be appropriate for
v3that’s not appropriate for
main, in which case a new PR/merge directly into
Following a versioned spec
Now this one is rare, and I’d be pretty surprised to see this on a commercial team, but it’s an interesting case study just the same, so I’ll mention it. First some background:
Now some of the changes we make fall outside the realm of the Go spec. These can be optimizations, bug fixes, or tooling improvements. These types of changes generally make perfect sense to apply in a TBD manner. That is to say, we can just merge them directly to mainline whenever they’re ready.
But then the versioned spec changes need much more control. It would never make sense to release a version that, say “supports everything in Go 1.2, and features A, B, and C from Go 1.3”. We need our system to support either Go 1.2 fully or Go 1.3 fully.
So here’s where we break from the TBD model entirely on this project:
Whenever we’re ready to begin work on a new Go spec version (usually about a month before it’s finalized), we create a long-running “feature” branch for the new target version. We branc this off of mainline, and usually call it something creative like
go1.17. Then we update all of the automated tests to run the tests against the Go 1.17 spec instead of the old 1.16 spec, and then the entire CI pipeline turns read and starts throwing rocks at our faces.
Then we’ll work on making the CI pipeline happy on that branch by adding any new features required in the new Go version. We’ll also do a careful read over the latest Go release notes as well, to add anything that the failing CI pipeline may not have caught. When that long-lived
go1.17feature branch is finally passing all the tests, we’ll usually run it locally for a week or two, to see if we find any straggling issues, before we finally merge that into mainline, then tag a new 1.17-based release.
One thing to note: we sometimes do create PRs against our
go1.xxbranches. That is to say: While we have the
go1.xxbranch in a broken state, I may work on fixing a specific issue in a
go1.xx-foobranch, and create a PR to merge that into the in-progress
go1.xxbranch. Sometimes we also just work directly on a shared
go1.xxbranch. Whichever seems easier and cleaner.
So there you have it. I’m on record admitting that I don’t always use TBD, I sometimes use long-lived branches, and I sometimes even share an in-progress branch with other developers. All practices I regularly preach against. Even the best rules have a time and place to be broken, I guess. :)
Minimum Viable Continuous Delivery
A group of people with a lot broader experience than I have, come up with a pretty good definition of "Minimum Viable Continuous Delivery".
How to switch from GitFlow to Trunk-Based Development
You've decided GitFlow is totally uncool. But what if you're already using it? How can you break the habit?
Adventures In DevOps 093: Deconstructing the Minimum Viable Continuous Deployment
The panel jumps in and discusses the Minimum Viable Continuous Deployment from the manifesto on the web and discuss where they agree and disagree with the requirements listed there and clarify some of the ideas in the document.