Tuesday, May 08, 2018

More Thoughts on Feature Branching vs Trunk Based Development

Recent posts by Dave Farley and Jim Kinsey, and the release of the Accelerate book by Forsgren et al appear to be bringing dysfunctional development practices firmly into the spotlight once again, most specifically the practice of combining feature branching and automated builds, while calling it “continuous integration". I have already written my own opinion piece on the practice. In summary, I hate it - in a modern, collocated team it is wasteful, suppresses fast feedback, and completely undermines the advantages of powerful teamwork enabled by continuous integration. It harks back to a software dark age that I honestly thought our industry had finally left behind. It really is Continuing Isolation.

But perhaps the most damning piece of research about Feature Branching that has come out in recent years is best summarised by Dave Farley:
If you are not merging your changes to Trunk at least daily, [the research] predicts that your outcomes are more closely aligned with “Lower Performing Teams”.
So that’s it. Some limited edge cases aside, if you are not continually integrating to a common trunk at least daily, you are choosing to be a low performer. It is now a conscious choice based on hard data. Who actually wants to be a low performer?

Well, it would appear a significant number of companies and teams do. From my experience, heavyweight feature branching practices are rife, even when totally inappropriate.

Which, for me, raises the much deeper question. Why would otherwise perfectly sane, competent, conscientious people deliberately choose to be "lower performing”? And perhaps more telling, why would they choose to be lower performing and passionately defend the practices shown to be causing it? I believe Jez Humble (co-author of ‘Accelerate’) hits the nail squarely on the head here:

(The whole Twitter thread is worth a read, with some interesting insights)

In short (and kind of inevitably, in my not very humble opinion), it’s culture. That amorphous, difficult to define, "emergent property of interactions over time” (thanks due to Dave Snowden for the definition). So basically your team/company/personal decisions have been shaped by valuing certain narratives and interactions over others - perceived convention, fitting in & peer pressure, pressure from performance reviews, painful failures, habit, and so on. I cannot emphasise enough that culture is THE most pervasive, entrenched barrier to team improvement. Hence the apparent conflict between a declared wish to improve, yet defending dysfunctional practices. Yet it is also the most difficult to change precisely because it is emergent, and because going against local cultural norms is damned scary.

Jez correctly points out a key difference between feature branch development, and trunk based development. Feature branch based flows are optimised for individual developers. They can shut themselves away, with minimal collaboration, and eventually, magically conjure something at the end that may or may not work. It actively encourages solo, "hero programmer" behaviours and hence culture. Adding automated integration patterns to this (note, this is categorically not "continuous integration") will not help performance much because of the integrate-late, test-late nature of the flow.

"Trunk Based Development", with an entire team working on a single branch, encourages an entirely different kind of approach and behaviour; it is about team collaboration and communication. It has to - without these skills, quite simply, it will not work. Period. It requires a team. A real, functioning team, and not just a group of individuals.

As such, feature branching tends to be symptomatic of a company culture of broken teamwork, and as a result, low performance.

So, given the difficulty in changing an embedded culture, and how scary this kind of change is, how can a team move from feature branching approaches like GitFlow, and successfully change to Trunk Based Development and continuous integration? Well, the good news is you have already taken an enormous step forward by recognising a need to change. Unsurprisingly, the next step is to carry out a health-check on the team.

How do you recognise a healthy team? A useful starting point for assessing team health is the excellent Lencioni’s 5 Dysfunctions of a Team, which suggests that a healthy, functioning team has these traits. Each relies on the previous.
  • Trust. A willingness to be vulnerable within the team.
  • Constructive conflict. It’s OK to disagree and discuss. It is OK to have “constructive, passionate debate”.
  • Commitment. All team members buy-in to joint decisions.
  • Accountability. Team members call others out on counterproductive behaviour.
  • Attention to results. Team success first, over and above personal success and ego.
Having successfully installed Trunk Based Development and Continuous Integration practices into many teams (and with my fair share of failures over the years as well!), I can safely say that these provide a good guideline for success. At very least TBD/CI development needs teams aspiring to this baseline, with a little help from an experienced agile technical coach.

That’s it for now. In the second instalment, I will go through some of the practices and tricks that make TBD/CI work for a team, and link them back to how the 5 Dysfunctions undermine the chances of success.

Friday, February 09, 2018

How not to be an Igor

I recently wrote a somewhat tongue in cheek piece with a serious message. For agile - well, actually, any software development project - to succeed, business needs to be fully and intelligently engaged. Iterative delivery processes appear particularly sensitive to this (arguably, they just show it up sooner, but that’s another discussion).

So, how do you make sure that your software team(s) successfully deliver what’s needed? A very good question - and one with no definitive answer. But here are a few hints that should give you a better than average chance of success.

Firstly, and perhaps most importantly, is to recognise that “The Business” generally does not really understand the engineering discipine of software development. They might have an appreciation of it (at least, I hope they do!), but they don’t have skin in that particular game. They don’t cut code daily, so they don’t experience the trials and tribulations of producing the end product. So they don’t generally care about how many tests you have, or that you are using the latest whizzy ReacgularEmberAshSproutCabbageCarrotCore framework, nor do they care whether you are using continuous integration, containers, microservices or Tupperware. The business is usually only interested in one thing - the end game. Working, reliable software in front of the customer. And if they cannot see that, then they will be tempted to fall back on illusion of progress antipatterns as a proxy measure of progress, performance and value. For example, Number of Stories Delivered, Velocity Points Delivered, Accuracy of Estimates measures and so on (Hint: This is a Bad Thing(tm). None of these are productive. Quite the opposite, they are illusory).

Equally, “The Dev Team" don’t always understand the business. Since software development is a skilled, complex, creative endeavour, their focus needs to be on programming tools, techniques, patterns and paradigms. As a result, in the same way as business is disconnected from development pressures, they can miss important factors unrelated to their immediate engineering discipline. For example, time-to-market pressures, customer needs, visibility of real progress and so on.

I believe this situation is fine and good. It is rare to find teams that are so cross-skilled that developers and business representatives are interchangeable. Both disciplines require significant specialist personal investment of time and energy. But as a result, neither side can exist in isolation. Neither side is better than the other. Effective product delivery is a joint responsiblity. It has to be a symbiotic collaboration of the two sides, which requires communication and mutual respect. Frequent, effective, two-way, respectful communication. If this breaks down, then trust is lost, the illusory control mechanisms begin to appear, and both sides start an unproductive game of "blame whack-a-mole”. Business demands a meaningless progress metric, eg velocity points delivered. Dev team get metaphorically beaten up for “not delivering enough points”. Dev team learns how to game the metric to avoid pain. Software still doesn’t get delivered. Business demands another meaningless progress metric, which gets gamed…. and so the proverbial blame-moles get whacked.

So the first, most important rule of “Not being an Igor” is for Business and Development to communicate with each other openly, honestly, and with respect for each others’ needs and skillset. The rest follows on from here.

Once there is a meaningful, respectful dialogue between Business and Development, then both can openly and honestly discuss, challenge and align goals. For example, if the Business genuinely needs something working in time for, say, a key conference, then the thorny subject of how it can be delivered can be discussed. The Development team knows their subject, so they are the best people to ask. Equally if there is budgetary consideration, then perhaps Business are the best people to ask. Both sides have valuable input. However, both sides need to be alert for imagined terms. The needs of both side can be challenged (respectfully!) and discussed to see if they are real or based on flawed information or opinion. Eg. "What happens if we miss that date? Does the company go bankrupt?”, “Do we want this product so badly that budget isn’t really an issue? When does cost become a real issue?”.

There are facilitation techniques that can be used to ensure these discussions are effective and productive rather than damaging. This is a rich seam of material for other articles at some indeterminate time in the future - do get in touch if you need help with this.

Now the goals are aligned, actual development of software to satisfy them can start. More importantly, an ongoing, meaningful discussion of progress can begin. To be meaningful, progress needs to be directly measurable, and not abstract (story point burn is definitely out). The only measure is demonstrably working software. That is, software that you can give to the business and say “This is what it does now, compared to what it did last time”. No smoke, no mirrors, no voodoo SQL statements showing magic has happened. Plain old warts’n'all User Experience.
From visible progress, more meaningful discussion can take place. Does the software work? Does it look like we can deliver within budget/time? What are the unforeseen (unforeseeable!) problems stopping us? Are we likely to succeed? Is it worth continuing for another week/fortnight/month? The odds are, by making small, mutually agreed corrections early and frequently during delivery, the product becomes much more likely to succeed, and if not, significant budget, effort and stress saved by recognising this early.

Following these simple pieces of advice do not guarantee success. The supermarkets are sold out of silver bullets, and the world supply of magic project beans has had an unfortunate run-in with some weed killer. However, I do guarantee that by simply appreciating the skills others bring to the project, and having honest, sensible discussions with each other, you will be less Igor-like, and your project will stand a far better chance of succeeding.