Mais uma discussão sobre trunk-based vs branch-based development
Da série "Polêmicas Ágeis"
English version here.
De tempos em tempos essa discussão aparece, e é difícil deixar os viéses de lado para tomar uma decisão. Geralmente, as pessoas desenvolvedoras têm uma opinião formada previamente e, por isso, não importa o contexto, elas irão defender um determinado caminho.
Mas como não existe bala de prata, eu vou dar a minha opinião sobre quando devemos utilizar uma ou outra abordagem.

Antes disso, vamos às definições:
Trunk-based development é a prática de fazer commits sempre na master, não utilizar branches para manter o desenvolvimento parcial. Cada commit é uma integração com o código final.
Branch-based development tem duas sub-categorias:
Short-lived branch é a prática de criar branches com funcionalidades parciais, agregando um ou mais commits. Essa prática é utilizada para se aproveitar dos benefícios do pull request com code review, ao mesmo tempo que gozamos dos benefícios do trunk-based development. Uma short-lived branch não deveria durar mais que um dia na média.
Feature branch é a prática de criar um branch para cada feature. O código só é mergeado na master quando a feature está completa, eliminando a possibilidade de código não usado/não terminado ser mergeado com a master. A definição de feature depende do time, mas geralmente se refere a uma User Story. Rebases constantes com a master são importantes.
Dica importante: não caia na armadilha de comparar e ter que escolher entre trunk-based development e code reviews. As short-lived branches estão aí para possibilitar que os dois conceitos sejam complementares.
1. Um time pequeno (5–8 devs) que trabalha no mesmo local físico desenvolvendo em um codebase greenfield.
Este é o cenário perfeito. Trabalhamos em um time ágil, temos autonomia do nosso codebase, conhecemos e estamos próximos de todas as pessoas que tocam esse código. Geralmente as práticas e cerimônias em times nessa configuração estão sob responsabilidade do time. Porém ainda há a necessidade de garantir qualidade, de igualar o conhecimento técnico, ou de definir padrões para o novo código que está sendo criado.
Neste caso, eu optaria por trunk-based development com pair programming numa parte considerável do tempo, e tentaria me aproveitar ao máximo de tech huddles, que são mini reuniões de 15 minutos no máximo, criadas sob demanda para discutir uma abordagem técnica para determinado problema.
Como o ambiente é muito controlado, se utilizamos branches e pull-requests que requerem aprovação para ser mergeados, estamos adicionando um passo no processo que pode diminuir a efetividade do time. Processos extras são inimigos do Lean Software Development.
2. Um time pequeno (5–8 devs) que trabalha distribuidamente desenvolvendo em um codebase greenfield.
Quando o trabalho é distribuído, é necessário um pouco mais de preparação para todas as etapas da entrega de software e para a fase de desenvolvimento não seria diferente. É mais fácil chamar a pessoa ao lado e pedir um desenho no quadro branco antes do desenvolvimento do que fazer uma call e, pela minha experiência, isso guia as pessoas desenvolvedoras para silos de estilo de código e formação de opinião. Quando temos um time dividido em dois ou mais lugares diferentes, é muito comum entender melhor as decisões que as pessoas ao nosso redor estão tomando. E porque estamos distantes, é comum cair no erro de não conversar com quem não concordamos, já que não temos intimidade ou o fuso horário é diferente; se forem pessoas de países diferentes então, até os aspectos culturais impactam nesse processo.
Minha primeira abordagem seria manter o time unido. A prática de pair programming também funciona para pessoas remotas. Não caia na tentação de parear somente com quem está no mesmo local físico do que você, isso só aumenta o silo. Tenha boas práticas de comunicação. Se o time é distribuído, mesmo comunicações com pessoas próximas devem ser feitos no canal do time, assim todas as pessoas têm acesso à mesma informação. Se possível ($), se encontre pessoalmente com as pessoas que estão em outro escritório. Se mesmo assim sentir que há problemas em alinhar padrões de código e nível técnico entre as pessoas, pense em maneiras alternativas de fazer revisão de código, por exemplo, abram pull requests somente quando precisarem de feedback no código, não limitem a uma quantidade mínima de approvals no pull-request, deixem a cargo das pessoas que abriram o PR optarem ou não por não executar determinada mudança baseada num comentário.
As pessoas tendem a gostar muito dessa abordagem. Dá segurança para quem está desenvolvendo, sem tirar sua autonomia. Também gera um sentimento de que a construção é feita em conjunto.
3. Um time grande, ou um codebase compartilhado entre vários times (15–20 devs), com um codebase mais evoluído — já que geralmente os times não começam grande (crescem após um tempo considerável de desenvolvimento).
Esse é o cenário que não gostaríamos de ver, mas todo mundo com alguns anos de experiência já passou por alguma situação dessas. Acontece mesmo! E vai continuar acontecendo, quer a gente ache que é um anti-padrão ou não.
Algumas situações que eu já vi levar a esse cenário:
1. Entrega desandou, algum gerente pediu pra colocar mais gente para desenvolver. Leva um tempo até as pessoas perceberem o gasto.
2. Código legado monolito que precisa ser mantido pelo time que está desenvolvendo o produto novo.
3. Código legado usando a técnica de estrangulação para desenvolver o novo sistema.
Entre outros.
O fato é, esse cenário deveria ser temporário, mas enquanto é a nossa realidade, precisamos encontrar uma maneira eficiente de lidar com o problema.
Principalmente se esse código não está sendo substituído por outro, mas não exclusivamente, precisamos nos atentar à qualidade do código. Não é fácil chegar a consensos com 20 pessoas, e provavelemente não iremos chegar. Mas existem maneiras efetivas de discordar.
Geralmente nesses cenários a pior maneira de discordar é não ter contexto da tomada de decisão. Se alguma pessoa toma a abordagem de desenvolver da maneira A, e outra pessoa acha que deveria ser feito da maneira B, mas ela só descobre isso daqui a 3 semanas quando ela for tocar aquele trecho de código, ela vai sentir que a pessoa fez errado por falta de conhecimento, e a discussão sobre se essa é a abordagem mais correta já vai ser em vão. Isso nos leva a ter múltiplos padrões no código para problemas similares, pessoas desconfortáveis em discordar dentro do time, entre outros conflitos. E esses pequenos conflitos são mais custosos que os code-reviews.
Nesse caso eu optaria por ter code-reviews, com short-lived branches.
São muitas pessoas, logo, são muitas decisões. Code-reviews ajudam a comunicar decisões entre as 20 pessoas, definir padrões de forma mais colaborativa.
São muitas pessoas, logo, a rotatividade é alta. Code-reviews ajudam a garantir que estamos alinhados tecnicamente, mesmo com alguém que acaba de entrar.
São muitas pessoas, logo, a possibilidade de erros é maior. Antes de mergear na master podemos garantir que os testes da branch passam e não bloqueamos outras pessoas por conta de um build vermelho.
E eu não acho que o pair programming aqui é descartável. Podemos nos sentir mais confortáveis em parear menos, já que temos outra forma de garantir qualidade, e isso pode até ser um benefício, mas principalmente se temos múltiplos times trabalhando no mesmo codebase, o pareamento dentro dos times ainda é muito valioso, mas não temos a possibilidade de executar essa prática inter times, o que faz até que as duas práticas se complementem.
Eu passei por 3 cenários, o primeiro é o ideal, é o que todos os times deveriam mirar como objetivo. O terceiro é geralmente uma consequência das tomadas de decisão do produto. Cada um deles tem suas particularidades e requer formas personalizadas de abordagem. Eu já trabalhei nos três formatos e isso foi o que funcionou para o meu time.
Apesar de eu não ter escolhido feature branch para nenhum dos três cenários, eu gostaria de ressaltar que eu também já trabalhei nesse formato, por uma necessidade de negócio, e não por ser uma técnica eficiente.
Se quiser ler sobre outras polêmicas ágeis, tem também o
User Stories — Atinja o próximo nível de maturidade e o Precisamos de inception?