La stabilizzazione è il processo mettere una ramo di release in uno stato in cui si può rilasciare; cioè il processo di decidere quali cambiamenti ci saranno nelle release, quali no, e dar forma al contenuto del ramo di conseguenza.
Ci sono un sacco di di potenziali pene in quella parola, “decidere”. La corsa alla funzionalità dell'ultimo minuto è un fenomeno familiare nei progetti di software in collaborazione: appena gli sviluppatori vedono che la release sta per avvenire, si agitano a finire il loro correnti cambiamenti, per non perdere il battello. Questo, certamente, è l'esatto opposto di ciò che volete al momento del rilascio. Sarebbe molto meglio per la gente lavorare alle funzionalità in una confortevole ritmo, e non preoccuparsi e non preoccuparsi tanto se i loro cambiamenti riusciranno a farcela per questa release o per la prossima. Più uno cerca di imbottire i cambiamenti nella release all'ultimo minuto, più il codice è destabilizzato, e (usualmente) più bugs si creano.
La maggior parte degli ingegneri di software convengono in teoria su abbozzi di criteri circa quali cambiamenti debbano essere consentiti in una linea di rilascio durante il suo periodo di stabilizzazione. Ovviamente correzioni per importanti bugs dovrebbero entrarci, specialmente per bugs senza correzioni che non risolvono il problema. Gli aggiornamenti della documentazione vanno bene, così come le correzioni ai messaggi di errore (eccetto quando sono considerati parte dell'interfaccia e devono rimanere stabili). Molti progetti anche consentono certi cambiamenti non rischiosi e non di base di entrare durante la stabilizzazione, e si possono avere formali linee guida per la misurazione del rischio. Ma nessun ammontare di formalizzazione può ovviare al bisogno del giudizio umano. Ci saranno casi in cui il progetto deve semplicemente prendere una decisione se un dato cambiamento deve entrare in una release. Il pericolo è che siccome ognuno vuol vedere il suo cambiamento preferito ammesso nella release, ci sarà una gran quantità di gente motivata a consentire cambiamenti, e gente non abbastanza motivata a impedirli.
Così, il processo di stabilizzazione di una release consiste per lo più nel creare un meccanismo per dire “no”. Il trucco per un progetto open source, in particolare, è venir fuori con modi di dire “no” che non abbiano molto come risultato dare la sensazione di una ferita o creare il disappunto degli sviluppatori, e che anche non impediscano che cambiamenti validi entrino nella release. Ci sono molti modi per fare ciò. E' piuttosto facile inventare sistemi che soddisfino questi criteri, una volta che il team si è focalizzato su di essi come criteri importanti. Qui descriverò due dei più popolari sistemi, agli estremi dello spettro, ma non permetto che questo scoraggi il vostro progetto dall'essere creativo. Una abbondanza di altri espedienti è possibile; questi sono giusto due che ho visto funzionare in pratica.
Il gruppo conviene di permettere a una persona di essere proprietario della release. Questo proprietario ha la parola finale sui cambiamenti che devono entrare nella release. Certo, ci si aspetterebbe ed è normale che ci siano discussioni e argomentazioni, ma alla fine il gruppo deve assegnare al proprietario la sufficiente autorità per prendere le decisioni finali. Affinché questo sistema funzioni, è necessario scegliere una persona con la competenza tecnica per comprendere tutti i cambiamenti e la posizione sociale e le capacità di navigare fra le discussioni puntando alla release senza causare tanti sensi di risentimento.
Un comportamento comune del proprietario è dire “non penso che ci sia qualcosa di sbagliato in questo cambiamento, ma non abbiamo avuto abbastanza tempo per provarlo, per cui non deve entrare nelle release”. Ciò aiuta molto se il proprietario della release ha larghe conoscenze tecniche del progetto, e ha la capacità di rendere conto del perché il cambiamento potrebbe esser potenzialmente destabilizzante (per esempio la sua interazione con altre parti del software, o questioni di portabilità). La gente potrà a volte chiedere che tali decisioni siano giustificate o sostenere che il cambiamento non è un rischio come sembra. Queste conversazioni non devono essere provocatorie, nella misura in cui il proprietario della release è capace di prendere in considerazione tutte le argomentazioni obbiettivamente e non come un colpo alle sue gambe
Notate che non è necessario che il proprietario della release sia la stessa persona del leader del progetto (nei casi in cui c'è un leader del progetto; vedere sezione chiamata «I Dittatori Benevoli» in Capitolo 4, L'Infrastruttura Sociale e Politica). Infatti a volte è bene assicurarsi che non siano la stessa persona. Le capacità che fanno un buon leader di sviluppo non sono necessariamente le stesse che fanno un buon proprietario di release. In una cosa così importante come il processo di release, può essere saggio avere qualcuno che controbilanci il giudizio del leader di progetto.
Contrastate il ruolo del proprietario di release con un un ruolo meno dittatoriale descritto in sezione chiamata «Il manager di release» più avanti in questo capitolo.
All'estremo opposto della dittatura da parte del proprietario di release, gli sviluppatori possono semplicemente votare su quali cambiamenti includere nella release. Comunque, poichè la funzione più importante per la stabilizzazione delle release è escludere cambiamenti, è importante creare un sistema di voto in modo tale che fare cambiamenti alla release comporti una azione positiva da parte di più di uno sviluppatore. Per inserire un cambiamento ci dovrebbe essere bisogno più di una semplice maggioranza (vedere sezione chiamata «Chi Vota?» in Capitolo 4, L'Infrastruttura Sociale e Politica). Diversamente un voto a favore e uno contro un dato cambiamento sarebbe sufficiente per inserirlo nella release e si creerebbe una sciagurata dinamica per cui ciascuno sviluppatore voterebbe per i propri cambiamenti, mentre sarebbe riluttante a votare contro i cambiamenti degli altri, per paura di possibili ritorsioni. Per evitare ciò, il sistema dovrebbe essere congegnato in modo che sottogruppi di sviluppatori debbano agire in cooperazione per inserire cambiamenti nella release. Ciò significa non solo che più persone revisionano ogni cambiamento, ma rende uno sviluppatore individuale meno indeciso nel votare contro un cambiamento, perché egli sa che nessuno in particolare fra quelli che votarono per esso può prendere il suo voto contro come un affronto personale. Più grande è il numero di persone coinvolte, più numerose diventano le discussioni sui cambiamenti e meno numerose quelle sugli individui.
Il sistema che noi usiamo nel progetto Subversion sembra aver centrato un buon bilanciamento, per cui io lo raccomando qui. Affinché un cambiamento sia apportato a un ramo di release, almeno tre sviluppatori devono votare a favore di esso, e nessuno contro. Un singolo voto “no” è sufficiente a impedire che il cambiamento sia incluso; cioè un voto “no” in un contesto di release è equivalente a un veto (vedere sezione chiamata «I Veti»). Naturalmente ogni voto di questo tipo deve essere accompagnato da una giustificazione, e in teoria si potrebbe non tener conto del veto, se abbastanza gente ritenesse che esso è non ragionevole e obbliga a un voto speciale su di esso. In pratica, ciò non è mai successo, e prevedo che non succederà mai. Le persone sono conservatrici nei confronti delle release in ogni modo, e quando qualcuno si sente abbastanza fortemente a favore del veto nei confronti dell'inclusione di una cambiamento, c'è usualmente una buona ragione per ciò.
Poiché la procedura di rilascio è deliberatamente orientata verso il conservatorismo, le giustificazioni portate per il veto sono talvolta procedurali piuttosto che tecniche. Per esempio, una persona può ritenere che un cambiamento sia ben scritto e che sia improbabile che causi nuovi bugs, ma vota contro la sua inclusione nella micro release semplicemente perché è troppo grossa magari apporta nuove funzionalità, o in qualche modo sottile non riesce a seguire completamente le linee guida di compatibilità. Io occasionalmente ho visto anche sviluppatori porre il veto a qualcosa semplicemente perché avevano una sensazione viscerale che il cambiamento avesse bisogno di ulteriori prove, anche se essi non potevano individuare bugs in esse con un esame interno. Le persone si lagnavano un poco, ma il veto resisteva e il cambiamento non veniva incluso nella release (non ricordo se qualche bug veniva trovato o no in una ulteriore prova, comunque).
Se il vostro progetto opta per un sistema di voto per il cambiamento, è imperativo che i meccanismi di organizzazione delle schede di voto e di votare sia il più adatto possibile. Anche se c'è una pletora di software open source disponibile, in pratica la cosa più facile da fare è giusto preparare nel ramo di release un file di testo, chiamato STATO
or VOTI
o qualcosa di simile. Questo file elenca ogni cambiamento proposto per l'inclusione insieme a tutti i voti a favore e contro, più eventuali note o commenti (Proporre un cambiamento non significa necessariamente votarlo, strada facendo, sebbene le due cose vadano insieme). Una voce in un tale file appare così:
* r2401 (issue #49) Prevent client/server handshake from happening twice. Justification: Avoids extra network turnaround; small change and easy to review. Note: Ciò fu discusso in http://.../mailing-lists/message-7777.html e altrimessaggi in quel thread. Voti: +1: jsmith, kimf -1: tmartin (breaks compatibility with some pre-1.0 servers; admittedly, those servers are buggy, but why be incompatible if we don't have to?)
In questo caso il cambiamento ottenne due voti a favore, ma ad esso fu messo il veto da tmartin, che diede ragione del veto in una nota scritta fra parentesi. Non ha importanza l'esatto formato della annotazione; qualunque cosa il vostro progetto corregga è ben fatto forse la spiegazione di tmartin per il veto dovrebbe andare in “Note”: la sezione o magari la descrizione del cambiamento dovrebbe comprendere una intestazione “Descrizione:” per adattarsi alle altre sezioni. La cosa importante è che tutte le altre informazioni necessarie per valutare il cambiamento devono essere raggiungibili, e che il meccanismo per dare il voto siano quanto più leggero possibile. Il cambiamento proposto è individuato dal suo numero di revisione nel deposito (in questo caso una singola revisione, la r2401, sebbene un cambiamento proposto potrebbe appunto facilmente consistere in revisioni multiple). Si conviene che la revisione si riferisca a un cambiamento fatto sul tronco; se il cambiamento fosse già nel ramo di release, non ci sarebbe bisogno di votare su di esso. Se il vostro sistema di controllo della versione non ha una chiara sintassi per far riferimento a un singolo cambiamento, allora il progetto dovrebbe crearne una. Affinché il votare sia pratico, ciascun cambiamento in considerazione dovrebbe essere identificato senza ambiguità.
Queste proposte o voti per un cambiamento sono affidabili per essere sicuri che si applichino in modo pulito al ramo di release, cioè, si applichino senza conflitti (vedere conflitto). Se ci sono conflitti, allora la nuova voce dovrebbe puntare o a una patch apposita che si applica in modo pulito, o a un ramo temporaneo che sostiene una apposita versione del cambiamento, per esempio:
* r13222, r13223, r13232 Riscrive libsvn_fs_fs's auto-merge algorithm Giustificazione: unacceptable performance (>50 minutes for a small commit) in a repository with 300,000 revisions Ramo: 1.1.x-r13222@13517 Voti: +1: epg, ghudson
Questo esempio è preso dalla vita reale; esso proviene dal file
STATO
per il processo di rilascio Subversion 1.1.4. Notare che esso usa le revisioni originali come gradi del cambiamento, anche se c'è un ramo con una versione del cambiamento con un conflitto superato (il ramo combina anche tre revisioni di tronco in una, la r13517, per rendere più facile l'unione dei cambiamenti nella release, dovrebbe essere approvato). Sono fornite la revisioni originali, perché esse sono le entità più facili da revisionare, perché hanno i messaggi di log originali. Il ramo temporaneo non dovrebbe avere questi messaggi di log; per evitare duplicazione di informazioni (vedere
sezione chiamata «Singolarità dell'informazione» in
Capitolo 3, L'Infrastruttura Tecnica
), l messaggio di log del ramo per la r13517 dovrebbe dire semplicemente “Adatta la r13222, r13223, e 13232 per il backport al ramo 1.1.x”. Tutte le altre informazioni sui cambiamenti possono essere inviate alle loro revisioni originali.
Il processo reale di unire (vedere Unire(merge)) cambiamenti approvati nel ramo di release può essere effettuato da un qualunque sviluppatore. Non c'è bisogno che sia una persona il cui compito sia quello di unire i cambiamenti; se c'è una gran quantità di cambiamenti, la cosa migliore può essere quella di suddividere il carico.
Comunque, sebbene l'unione dei cambiamenti e il voto avvengono in un modo di fare decentrato, nella pratica c'è una o due persone che guidano il processo di release. Il ruolo è benedetto talvolta come manager di release, ma è completamente differente da un proprietario di release (vedere sezione chiamata «Dittatura Da Parte del Proprietario Della Release» precedentemente in questo capitolo) che ha la parola finale sui cambiamenti. I managers di release tengono traccia di quanti cambiamenti sono al momento sotto considerazione, quanti sono stati approvati, quanti sembrano da approvarsi, ecc... Se essi hanno l'impressione che cambiamenti importanti non stanno avendo sufficiente attenzione, e potrebbero essere lasciati fuori per una manciata di voti, essi potrebbero brontolare con gli altri sviluppatori per ottenere una revisione o un voto. Quando un gruppo di cambiamenti viene approvato, queste persone possono prendersi il compito di unirle al ramo di release; è cosa buona se gli altri lasciano questo compito a loro, fintanto che ognuno ritiene che essi non sono obbligati a fare tutto il lavoro a meno che non siano esplicitamente incaricati di farlo. Quando viene il tempo di far uscire la release (vedere sezione chiamata «Prove e Rilascio» più avanti in questo capitolo), i managers di release si prendono anche la cura della logistica della creazione dei pacchetti della release finale, raccogliendo le firme digitali, uploadando i pacchetti, e facendo gli annunci pubblici.