Version Driven Branching (part 2)
Branch and Environment management seems to be a more controversial topic than I could have possibly imagined. I have found almost a different opinion amongst every single person I have talked to on the subject and just a day after posting the original article, I have more than enough material to write another post. To begin with, I have added a few clarifications to the original article at the bottom (since I don't want to use this article to try to defend points I made in the first one). I am going to try to use this article to present arguments that were definitely missing in the first.
During my team's initial conversation about branching strategies, I remember the moment one of my colleagues suggested that we would need a Release environment to cater for the issues we were facing with our Release branch. I was upset - we had got to a situation where we had just 2 environments (with their slots) and suddenly we were gaining environments out of nowhere. I asked a question:"What is the goal you are trying to achieve?"
The point I was trying to make was that we were now trying to solve the problem of having to deal with an extra branch by adding an entire environment. If the most important objective was to ensure we used the Gitflow branching strategy and therefore we needed a Release branch, then this definitely WAS the solution. But our aim was to try to figure out a branching strategy that would let us ensure we had good quality code smoothly flowing to Production, which is not the same goal.
In hindsight, I realise now that the same question could have been asked of all of us - our initial goal had clearly been different. We had been trying to minimise the amount of environments in order to move towards a development process where we test code in Production and do not spend as much time managing environments that are not returning a profit.
Having additional environments does not mean that you necessarily have to spend much time managing all of them. One of the problems with having just a few big environments, with many tests is that the feedback loop is too long - the more deployment steps that are needed and the more tests that are run, the longer it will take for you to realise something may be broken. A case for many environments can be easily made on the basis that they would be lightweight, running just a few rudimentary tests that avoid any flaky scenarios. If the overhead is lowered for managing these environments, they become very powerful tools for diagnosing major issues fast, which can be a great help to developers that want to get assurance about their code as soon as possible so that they are free to start working on their next ticket. Whether these environments are split by release, team, individual or feature can have different merits depending on what individuals want to know about the state of their code. For example, a team environment will quickly feed back to the team that they may carry the responsibility for a bug, which would allow them to get their heads together over it, while a feature environment would specifically state an issue with that feature and allow feature-based code fixes that could be shared across teams.
Conway's Law and artificial boundaries
Conway's Law tells us that any system produced in a company will reflect the quality of communication within that company. It is not hard to see that a breakdown in communications within a company can cause issues for any branching policy - the moment two teams have to merge their code together, they need to communicate with each other to ensure that no issue arises from the merge. While it is easy to notice the effects retrospectively, it is not so easy to avoid them while working on software.
Developers are used to creating artificial boundaries in the software they build. These range from access modifiers in classes and functions to code seperation into projects, solutions and folder structures. The main reason we create these boundaries is to try to help communication - if a class is Private, we know we shouldn't be trying to access it somewhere else and that we might be taking the wrong approach. If two domains in your code are split into seperate projects, you are are helping communicate the distinction between those domains to any other developers that may look at it.
When we arrive at a branching strategy, we should try to find the strategy that communicates the way we want to work, which may not be the way we are currently working. I cannot see any better way towards moving towards better communication than to run a project in a way that encourages everyone to fit into the communication model we idealise. I'm not entirely sure what this means in practice, but my gut feeling is that fewer dedicated branches can be useful if we want to develop trust between teams, while adding dedicated branches can be helpful for teams that already have a high level of trust and can release code fast, but are looking for a way to clarify what it is they are doing by applying labelled boundaries to their branched code.
published: Wed Mar 14 2018