Transitioning to Trunk Based Development (without the chaos)
How Moonpig moved to trunk based development (without the chaos)
This post was originally written for the Moonpig Engineering blog.
At Moonpig our decision to try trunk based development came about as part of a wider project to move to continuous deployment. Having successfully implemented feature toggling and got comfortable with using it, the time was right to “ go trunk”.
Risk and resistance
Change is often met with resistance, and this was no different. Some engineers had had bad experiences of trunk based development in previous organisations, whilst others were simply worried about tracking the changes that would go through to the live site, and the risk of releasing untested changes.
As well as internal resistance, we’d all heard of companies that had tried trunk based and failed, so we were well aware that it wasn’t necessarily going to be an easy transition.
At the time we tried, we had 3 teams totalling about 20 engineers working across multiple APIs and our web solution. So whilst not a massive team, more than enough for all out chaos!
Quite simply, we decided to pilot trunk based development within a single team. The other teams would continue to work on feature branches as before, meanwhile the “trunk team” would act as a path finder. They would assess if this approach was both valuable and viable, and work out how we could successfully adapt our working processes. If we could make it work successfully within a single team, we would roll it out to the whole team.
To further manage risk, we also took the decision to continue creating release branches for any production deployments. This avoided too many changes at one time.
What problems did we encounter?
The transition both for a single team, and later multiple teams, was very smooth.
The one challenge we did face was how to manage code reviews. Whilst we pair on the bulk of our work, there is still the need for reviews from time to time, and the option of creating a pull request in GitHub was no longer available.
Having Googled for an answer to this problem, I was surprised how little advice was on offer. The solution turned out to be very simple. We licensed Crucible, a peer review tool from the Atlassian Suite. Crucible is a tool which allows you to review code, discuss changes, share knowledge and identify defects.
With Crucible installed, there was nothing to stop us rolling out trunk based development to the wider engineering team. And by the time we did, everyone wanted to work that way — the teams still using feature branches felt left behind!
Coordinating releases to Production
Once all teams were confident with the trunk based approach, we stopped creating release branches. This dramatically reduced the overhead around releasing enabling us to deploy to Production more quickly more often.
Notwithstanding that, with 20 plus engineers making changes to the same code base, we did need to think about how we tracked changes so we had clear visibility of changes being made to the live site.
We leveraged our Jira workflow to gather information about code changes throughout the development cycle. As tickets are moved across the board, engineers are prompted for information such as build numbers, components changed, versions, release notes etc. This provides complete visibility — anyone viewing any task in Jira can see what components have been altered, the build numbers for those components, what environment the changes are on, whether or not they are live, and whether or not they have been toggled on.
This makes tracking changes to Production very streamlined and straightforward, and it also encourages engineers to think not only about the changes they are making, but how those changes can be safely deployed. It’s a small process overhead, but one that everyone understands and respects the need for.
Are feature branches outlawed?
Absolutely not. From time to time we still use feature branches — if we have changes that can’t be feature toggled, or a high risk change that we want to be able to release in isolation we’ll still use feature branches. However, those scenarios are few and far between, and in reality trunk based development serves us well 99% of the time.
Reaction to the change
The reaction was extremely positive, with everyone preferring to work this way. Even those engineers that had had negative experiences in the past became converts. It’s impossible to imagine that we’d ever want to go back!
What are the benefits?
Having all changes in one place makes testing and review very straightforward. With feature branches, we’d have a queue to deploy feature branches to our manual test environment which slowed up our ability to complete work. Likewise, when Product Owners and stakeholders wanted to review work, they’d have to wait for an environment to be available and the right branch deployed to it. With trunk based, all the code is in one place and it can be deployed to a single environment where multiple changes can be reviewed and tested in parallel.
Long running feature branches inevitably result in messy merges, and avoiding those is a great benefit of trunk based. Whilst merge conflicts do not entirely go away, they are less frequent and far less difficult to unpick.
Above all, it’s much, much faster!
Top tips for a successful transition
Try the trunk based approach on a small group, or a single component — once you are confident it can work for you, start to roll it out further.
Acknowledge risk and fear, and prepare everyone to accept a little disruption — it won’t necessarily work perfectly from the start, and people will have more patience if their expectations are well managed.
To avoid too much change in one go, and manage risk, use release branches until you are fully confident of your process.