
Qualche mese fa ho cominciato a lavorare su un progetto completamente nuovo e con il team abbiamo deciso di inserire qualche tecnologia innovativa e provare un altro modello di branching chiamato Trunk Based Development (TBD).
Solitamente abbiamo un backlog di “Story” su cui lavorare. Il lavoro è diviso in “Sprint” di due settimane e, con un meeting all’inizio di ogni sprint, decidiamo su quali storie lavorare. A quel punto, gli sviluppatori sono liberi di dedicarsi a qualsiasi storia nello stato “To Do”, sempre con un occhio alle priorità decise durante lo sprint meeting.
Il modello di branching che utilizziamo abitualmente è una variante del tipico “GitHub Flow”:
- Quando si comincia lo sviluppo su una determinata storia, viene creata una branch a partire da master.
- Si lavora su quella branch, senza pensare a nient’altro. Lo sviluppo può durare ore, giorni, settimane. Quando il lavoro è terminato, il codice viene pushato verso il server e il build tool (Jenkins) prova a creare una build e far girare i test.
- Se tutto va a buon fine, viene aperta una Pull Request (PR) verso la branch master, su cui tutti i membri del team possono fare review. Chi vuole può fare delle osservazioni inserendo un commento sulla PR e, se lo si ritiene necessario, vengono fatte delle modifiche che saranno poi pushate, attendendo di nuovo le approvazioni da parte del team.
- Una volta che la PR è stata approvata, viene fatta la merge sulla branch master e il processo di Continuous Integration (CI) fa partire una build con la quale viene poi creato il “pacchetto” per il deploy sui vari ambienti applicativi.
Il problema con questo workflow è la parte di code review sulle PR che vengono aperte. Il meccanismo con cui viene fatta la review del codice (composta da commenti, risposte, implementazioni e altri commenti) a volte può durare settimane, visto che le persone che fanno code review sono comunque occupate in altre attività, in quanto non abbiamo nel team persone dedicate esclusivamente alle review. Questo rallenta significativamente il ciclo di sviluppo.
Per superare questo problema, abbiamo deciso di utilizzare il TBD, che consiste nel pushare il codice direttamente sulla branch master, senza creare altre branch. So che può suonare strano, ma continuate a leggere.

Come facciamo TBD?
Ovviamente non si tratta solo di pushare su master: per poter avere un vantaggio reale da questo modello bisogna darsi alcune regole.
Commit robusti
Ogni commit deve lasciare l’applicativo in uno stato “funzionante”, nessun test deve fallire, quindi bisogna organizzare lo sviluppo della propria feature, soprattutto se è corposa, per ottenere questo risultato.
Pair Programming
Almeno 2 coppie di occhi su ogni riga di codice: in questo modo il codice viene sottoposto al controllo di più persone.
Feature Flags
Può capitare durante lo sviluppo che il branch master contenga delle feature non ancora testate e che ancora non vogliamo portare all’attenzione del business. Possiamo disabilitarle utilizzando la tecnica dei feature flags (vi consiglio questo interessante articolo di Martin Fowler: Feature Toggles (aka Feature Flags) (martinfowler.com).
Design Review
Non avendo più il meccanismo delle Pull Request, la code review viene rimandata a un meeting settimanale in cui discutere delle varie implementazioni fatte. In questo meeting, un relatore espone quanto sviluppato e gli altri partecipanti fanno eventuali osservazioni. Può capitare di fare delle modifiche direttamente durante il meeting.
Come è migliorato il nostro sviluppo
Partire con questo approccio è stato tutto in salita. Il problema principale da affrontare è quello di trovare la giusta dimensione dei commit da pushare. Inizialmente alcuni membri del team non erano confidenti nell’effettuare il push di piccoli commit robusti, ma piuttosto preferivano un push unico al completamento della feature, causando diverse problematiche nel merge del codice.
Nonostante questo, dopo una prima fase di assestamento, il team ha riscontrato molti benefici da questo modello, e di seguito provo ad elencarne alcuni.
Il codice appartiene al team
Quando il codice di una feature viene scritto da una sola persona, che ne segue l’intero ciclo fino al merge su master, c’è la tendenza a ritenere quel codice di “proprietà” di quell’unico sviluppatore. Usando il TBD il codice appartiene al team, perché ad ogni commit vedi il tuo applicativo crescere, magari facendo refactoring su una parte di codice pushata precedentemente da un tuo collega, rendendo lo sviluppo più dinamico e di squadra.
Feedback veloci
Con il meccanismo delle PR i feedback arrivano solo a lavoro concluso. La fase di code review è sempre ardua da organizzare: nel nostro team non ci sono figure dedicate a quello, e quindi ci tocca trovare del tempo libero per farla. Una volta fatta, se troviamo qualcosa che non convince, lasciamo un commento, quindi l’altro membro (che nel frattempo ha cominciato un’altra attività) dovrà trovare il momento giusto per guardare il commento e magari rispondere, richiedendo così una forte interazione tra le parti che spesso può essere stimolante, ma altre volte si basa su una mera approvazione. Quando invece è presente un flusso di commit continuo, le code review sono sempre in corso, quindi scegliere una strada diversa rispetto a quella pensata può risultare più facile da implementare.
Feedback di migliore qualità
Con le PR, i commenti arrivano sotto forma di annotazioni in una casella di testo, con tutte le difficoltà del caso. Il commentatore potrebbe non riuscire ad esprimere correttamente il suo punto di vista, oppure lo sviluppatore potrebbe non cogliere l’esatto motivo del commento, considerandolo quasi un attacco personale.
Avere possibilità di confrontarsi sul codice in tempo reale, magari già mentre si fa Pair Programming, evita sicuramente incomprensioni e rende più fluido lo sviluppo.
Metodologia di sviluppo del team
Pair programming e TBD portano il team a creare una metodologia di sviluppo condivisa da tutti, rendendo le successive code review semplici e veloci.
Propensione al refactoring
Quando una PR ottiene le approvazioni necessarie e viene portata sul branch master, si tende a ritenerla conclusa, anche se il codice pushato avrebbe bisogno di un po’ di refactoring, che si cerca di evitare principalmente per non incappare poi in problemi di merge, che potrebbero essere necessari. Quando lo sviluppo è continuo, il refactoring di piccoli pezzi di codice diventa più semplice e non c’è bisogno di avventurarsi nel risolvere conflitti di merge complessi.
Visibilità sul lavoro di tutti
Quando gli sviluppi avvengono in una branch separata sono invisibili finché la branch non viene pushata. Se invece tutti pushano sulla branch master c’è la possibilità, in tempo reale, di vedere su quali feature il team lavora in quel momento.
TBD si adatta a tutti i team?
Vorrei chiarire un punto: lo sviluppo TBD di per sé non offre alcun vantaggio oggettivo e se ci pensate non è poi niente di speciale. Quello che invece dà dei vantaggi oggettivi sono le pratiche che è necessario mettere in atto per essere in grado di eseguire lo sviluppo basato su trunk.
Affinché un team sia in grado di lavorare direttamente su master è necessario che tutti siano in grado di lavorare senza rompere il codice, che tutti sappiano come scrivere dei test robusti e che tutti sappiano come lavorare insieme in modo efficace.
Come cominciare?
Se al momento stai sviluppando in feature branch e vuoi cominciare ad usare TBD, mi sento di consigliarti due cose:
- Fortifica il tuo modo di scrivere test. Cerca di lavorare per arrivare ad una build che secondo te non ha problemi, anche se non si può mai esserne certi. Prova a utilizzare la tecnica TDD (Test Driven Development), ti renderai così conto di inserire una quantità di test che riesce quasi a coprire tutto quello che la tua applicazione è in grado di fare.
- Fai Pair Programming. Eliminando il processo di Pull Request e quello di Code Review è fondamentale che il codice sia sviluppato sotto il controllo di almeno due persone.
- Analisi del codice: È possibile integrare all’interno della propria CI dei meccanismi di analisi statica del codice (noi utilizziamo SonarQube). In questo modo, viene fatto l’enforcing delle regole di stile semplificando ancora di più parte del processo di review.
Spero di aver alimentato la vostra curiosità su un nuovo modo di sviluppare.
Alla prossima.