Velocità e qualità del software. Tutta la verità sulle pull request, quando hanno senso e quando no

Recentemente ho pubblicato su LinkedIn i miei dubbi sull’efficacia delle pull request. Sorprendentemente, il mio semplice post ha dato il via a una serie di discussioni, raggiungendo oltre 350mila visualizzazioni. Ho sicuramente toccato un nervo scoperto

Ma cos’è una pull request? Essenzialmente, è una proposta per unire modifiche da un branch di codice a un altro. Le persone che lavorano al codebase esaminano e discutono questa proposta prima di integrarla nell’altro branch, solitamente quello principale. Questo processo permette ai collaboratori di valutare la qualità delle modifiche proposte e, in questo modo, mantenere la qualità dell’intero codebase. A prima vista, sembra tutto molto semplice. Le pull request hanno senso quando non si ha fiducia nelle modifiche proposte al codebase. Il caso più comune è nei progetti open-source, dove chiunque può suggerire miglioramenti: questo è il meccanismo alla base dell’open-source. I progetti open-source beneficiano della saggezza dei grandi numeri. Come uno degli autori del framework open-source Easy.ts, lo vedo in pratica ogni giorno.

TI PIACE QUESTO ARTICOLO?

Iscriviti alla nostra newsletter per essere sempre aggiornato.

Non sempre conosciamo personalmente chi propone le modifiche, quindi non possiamo sempre valutarne l’esperienza o le preferenze, che spesso sono una questione di gusto personale. Ed è qui che entrano in gioco le pull request, permettendo di discutere le decisioni di programmazione prima di unire il codice nei progetti. È un’ottima opportunità per condividere competenze e comprendere diversi approcci.

Fiducia come parola chiave

Quando non ci fidiamo delle modifiche proposte, le esaminiamo e discutiamo con i proponenti. In questo contesto, le pull request hanno senso. Ma facciamo un passo indietro, guardiamo ai progetti quotidiani e al codice scritto nelle organizzazioni e nei team. Prendiamo per esempio, il mio team a ibood.com: quindici persone con esperienza, background e conoscenze diverse. Alcuni hanno decenni di esperienza, altri due anni. Il nostro è un team relativamente piccolo. Per mantenere la qualità del nostro codice, applichiamo diverse tecniche semplici: in primo luogo, abbiamo standardizzato la nostra architettura software, e tutti ne comprendiamo livelli e pattern. Di conseguenza, possiamo aprire uno qualsiasi degli oltre 150 repository e capire cosa troviamo, anche se non l’abbiamo mai visto prima. In secondo luogo, lavoriamo spesso insieme, per esempio con il pair e mob programming, anche da remoto. Quindi, molte modifiche vengono create da più persone. In questo modo si riduce la necessità di verifiche aggiuntive.

Leggi anche:  SAS, la vera potenza dell’AI

Inoltre, teniamo sessioni settimanali di condivisione della conoscenza con il metodo lean coffee, in cui chiunque può discutere qualsiasi argomento, imparando rapidamente e direttamente; scriviamo unit test per tutto il nostro codice, spesso applicando il test-driven development; e infine le nostre pipeline CI/CD sono completamente automatizzate e gestiscono la compilazione, il linting, l’esecuzione dei test in varie fasi, l’analisi statica del codice e gli sviluppi anche in produzione. Le nostre pipeline includono numerosi punti di controllo per garantire la qualità. Di conseguenza, non usiamo pull request. Ogni membro del team carica direttamente le modifiche nel branch principale. Pratichiamo il trunk-based development, senza branch. Abbiamo creato un ambiente in cui la fiducia è fondamentale, indipendentemente dal livello di esperienza dell’individuo.

La legge della marmellata di lamponi

Le pull request sono utili in ambienti dove il livello di fiducia è basso. Questo è il caso dell’open source, dove sappiamo poco delle persone che propongono modifiche. Ma nel mio team attuale, e così come in molti altri con cui ho lavorato, la fiducia non rappresenta un problema. Tuttavia, in molte organizzazioni la fiducia è diventata un problema. Molti commenti al mio recente post lo dimostrano: «Non possiamo fidarci che i singoli sviluppatori carichino direttamente nel branch principale, soprattutto i junior. C’è troppo in gioco». La mancanza di fiducia spesso accompagna la crescita. Più persone lavorano sul codebase, più difficile è mantenere la qualità. Con la forte ambizione di far crescere i team rapidamente e la scarsità di buoni sviluppatori, le organizzazioni assumono persone meno esperte e, di conseguenza, faticano con la qualità. È la Legge della Raspberry Jam, la marmellata di lamponi, di Jerry Weinberg: più la spalmi, più diventa sottile. E così, le pull request vengono in soccorso.

Leggi anche:  Etica, privacy e organizzazione, le sfide dell’intelligenza artificiale

La tempestività

Tuttavia, usare le pull request e rivedere le modifiche ha un grave inconveniente. In questo caso, la parola chiave in è tempestività. La maggior parte delle organizzazioni che usa formalmente le pull request è grande o in crescita. I revisori sono spesso i più senior nel team di sviluppo e, quindi, i più occupati, anche perché devono esaminare tutte le pull request. Ma i revisori spesso diventano un collo di bottiglia, e così le revisioni spesso non avvengono immediatamente. Quando si fa una pull request, passa del tempo prima che un revisore la prenda in carico. A volte è una questione di ore, ma se i revisori sono in riunione, in ferie, oppure è iniziato il weekend e un loro figlio è ammalato, l’attesa si allunga. I ritardi hanno diverse conseguenze. Quando devono aspettare, gli sviluppatori si dedicano a un’altra funzione. Quando una revisione arriva giorni dopo con feedback che richiede interventi, lo sviluppatore deve tornare alla funzione precedente. Se gli sviluppatori hanno più pull request aperte (cosa non rara), sono costantemente costretti a rifocalizzarsi. Questo si chiama cambio di contesto ed è oneroso. Il multitasking è un mito.

Inoltre, gli sviluppatori vogliono evitare cicli di feedback eccessivamente lunghi. Quindi, evitano di proporre piccole modifiche accumulandole fino al completamento di tutta la funzione. Oppure, inviano le modifiche solo quando sono sicuri di aver inserito tutto quello che gli altri potrebbero volere e anche di più. E così si finisce per costruire troppo, facendo over-engineering. Ma più si aspetta, più grande diventa la modifica. Più grande è la modifica, più difficile sarà riportarla nel branch principale, poiché nel frattempo altri avranno apportato cambiamenti. Nonostante le buone intenzioni, le pull request aumentano continuamente i ritardi in queste situazioni.

Perdere l’autobus

Qual è quindi la soluzione ideale? La fiducia è un problema più limitato in organizzazioni e team piccoli. Qualcuno ha risposto al mio post dicendo che lavora con trenta team sulla propria app mobile e la rilascia ogni due settimane, spiegando di essere orientati verso le pull request e di revisionare ogni modifica, con una strategia improntata alla prudenza. In ibood.com, carichiamo subito ogni modifica nella nostra piattaforma e-commerce in produzione. Sì, con numerosi controlli e test nelle nostre pipeline, ma comunque subito. Per noi, fare un errore in produzione non è la fine del mondo. Come dice Jason Gorman – “perdere l’autobus non è un grosso problema se sai che ne arriverà un altro tra cinque minuti”. Alla fine, si tratta di questo: quanto è grave perdere l’autobus? Le grandi organizzazioni, spesso con team remoti, richiedono maggiore fiducia. Più diventano prudenti, più utilizzano pull request e revisioni. Al contrario, quando i team sono piccoli e coesi, molte tecniche aiutano a costruire fiducia e velocità. Pair programming, mob programming, test-driven development e pipeline di delivery completamente automatizzate aiutano a evitare lunghe attese e il context-switching. In ibood.com, il prossimo autobus passa in cinque minuti. E da voi?

Leggi anche:  Breve storia dell’ingegneria dei dati. Linguaggi di programmazione e terreni minati

Sander Hoogendoorn

Consulente indipendente, artigiano del software, architetto, programmatore, coach, speaker, formatore e scrittore. La sua carriera è un percorso ricco di esperienze che lo hanno visto confrontarsi con le pratiche più avanzate dell’ingegneria del software. Ha una profonda conoscenza di Agile, Scrum, Kanban, Continuous Delivery, Agile Requirements, Design Patterns, Domain Driven Design, UML, Software Architecture e Microservices, e una vera passione per la scrittura di codice che rispecchia i più alti standard di qualità e design. Autore di bestseller come “This is Agile” e “Pragmatic Modeling with UML”, ha condiviso la sua esperienza, aiutando professionisti e aziende a crescere e a innovare. Attualmente, sta lavorando al suo prossimo libro sul nuovo Agile.

Sander Hoogendoorn presenterà per Technology Transfer il seminario “Progettare, sviluppare e implementare una Microservices Architecture” che si terrà online live streaming il 16 dicembre 2024.