Esecuzione del branching strategico
Pubblicato: aprile 2016
Il codice sorgente è una risorsa importante nel lavoro di sviluppo. Una gestione e un'elaborazione efficaci dei file di origine, tuttavia, possono rappresentare una sfida impegnativa quando più sviluppatori si occupano simultaneamente degli aggiornamenti dei file. È possibile usare un sistema di controllo della versione per archiviare il codice sorgente in repository condivisi, isolare attività di sviluppo parallele, integrare modifiche al codice e recuperare versioni precedenti dei file. Un elemento chiave nel controllo della versione è la creazione di rami che consente attività di sviluppo simultanee. La creazione di rami eseguita in modo strategico consente di mantenere l'ordine e la coerenza di più versioni del software.
Team Foundation fornisce un sistema di controllo della versione affidabile e flessibile. È possibile usare Controllo della versione di Team Foundation per gestire più revisioni durante lo sviluppo di codice sorgente, documenti, elementi di lavoro e altre informazioni critiche usate dal team. Per altre informazioni sul controllo della versione in Visual Studio Team Foundation Server, vedere Utilizzare il controllo della versione.
In che modo il team gestisce il codice quando si introducono simultaneamente più modifiche in diversi rilasci del progetto?
Quando si usa un sistema di controllo della versione, è necessario valutare come configurare una struttura di rami. È possibile creare un ramo eseguendo il mirroring del file del codice sorgente. È quindi possibile modificare il ramo senza influire sull'origine. Come illustrato dalla struttura di rami nella figura seguente, ad esempio, il ramo MAIN contiene una funzionalità completata che ha superato i test di integrazione, mentre il ramo DEVELOPMENT contiene il codice in fase di creazione. Quando una nuova funzionalità inclusa nel ramo DEVELOPMENT viene completata e supera i test di integrazione, è possibile alzare di livello il codice dal ramo DEVELOPMENT al ramo MAIN. Questo processo è denominato integrazione all'indietro. Al contrario, il processo di unione del codice dal ramo MAIN al ramo DEVELOPMENT è denominato integrazione in avanti.
Per altre informazioni su come creare e unire rami del codice, vedere la pagina relativa alla creazione di rami in Team Foundation Server del sito Web CodePlex.
Le operazioni di creazione rami e unione comportano i principi seguenti:
Per ogni ramo devono essere definiti i criteri su come integrare il codice nel ramo. Nella struttura di rami della figura precedente, ad esempio, è possibile assegnare un membro del team come proprietario e responsabile della gestione del ramo MAIN. Questo membro è responsabile dell'esecuzione dell'operazione iniziale di creazione rami, dell'integrazione all'indietro delle modifiche dal ramo DEVELOPMENT al ramo MAIN e dell'integrazione in avanti delle modifiche dal ramo MAIN al ramo DEVELOPMENT. L'integrazione in avanti è importante quando il ramo MAIN integra anche modifiche da altri rami.
Il ramo MAIN deve contenere codice che abbia superato i test di integrazione, in modo che sia sempre pronto per il rilascio di una versione.
Il ramo DEVELOPMENT (o di lavoro) evolve continuamente, in quanto i membri del team archiviano periodicamente le modifiche.
Le etichette sono snapshot dei file presenti in un ramo in un momento specifico.
Per altre informazioni, vedere Utilizzare le etichette per eseguire uno snapshot dei file.
Team Foundation Build consente di scegliere tra diversi tipi di compilazione per i rami: manuale, continua, gestita, in sequenza e pianificata. È consigliabile che il ramo MAIN abbia un tipo di compilazione con archiviazione gestita. Ciò significa che il ramo DEVELOPMENT deve soddisfare tutti i requisiti per il ramo MAIN prima di poter eseguire un'integrazione all'indietro. Il ramo DEVELOPMENT deve eseguire un tipo di compilazione continua, in quanto il team deve essere informato il prima possibile se una nuova archiviazione influisce sul ramo DEVELOPMENT.
Con quale frequenza il team deve eseguire le integrazioni all'indietro e in avanti?
Come illustrato nella figura seguente, l'integrazione all'indietro e l'integrazione in avanti devono essere eseguite almeno quando si completa una storia utente. Benché ogni team possa definire in modo diverso la completezza, il completamento di una storia utente indica in genere che sono stati completati sia la funzionalità che gli unit test corrispondenti. È possibile eseguire l'integrazione all'indietro nel ramo MAIN solo dopo che gli unit test hanno verificato la stabilità del ramo DEVELOPMENT.
Se sono presenti più rami di lavoro (DEVELOPMENT), l'integrazione in avanti in tutti i rami di lavoro deve essere eseguita non appena un ramo viene integrato nel ramo MAIN. Poiché il ramo MAIN viene mantenuto stabile, l'integrazione in avanti è un'operazione sicura. Possono verificarsi conflitti o errori nei rami di lavoro perché non è possibile garantire la stabilità dei rami di lavoro.
È importante risolvere tutti i conflitti il prima possibile. L'uso di un'archiviazione gestita per il ramo MAIN consente di semplificare significativamente l'integrazione all'indietro, in quanto i controlli di qualità consentono di evitare conflitti o errori nel ramo MAIN. Per altre informazioni, vedere Archiviare in una cartella controllata da un processo di compilazione di archiviazione gestita.
In che modo il team gestisce le origini che implementano storie utente diverse?
Come illustrato nella figura seguente, è possibile archiviare periodicamente le modifiche in un ramo di lavoro per completare una storia utente. È possibile implementare contemporaneamente più storie utente nello stesso ramo. È tuttavia possibile eseguire l'integrazione all'indietro nel ramo MAIN solo dopo aver completato tutto il lavoro in corso. È consigliabile raggruppare le storie utente per dimensioni simili, in quanto è necessario evitare che una storia utente di grandi dimensioni blocchi l'integrazione di molte storie utente più piccole. È possibile suddividere i due set di storie utente in due rami.
Quando il team deve aggiungere un ramo?
È necessario creare i rami nelle situazioni seguenti:
Quando è necessario rilasciare il codice in un diverso ciclo o una diversa pianificazione rispetto ai rami esistenti.
Quando il codice richiede criteri diversi per i rami. Se si crea un nuovo ramo con nuovi criteri, è possibile aggiungere valore strategico al progetto.
Quando la funzionalità viene rilasciata a un cliente e il team prevede di apportare modifiche che non influiranno sul ciclo di rilascio pianificato.
Non è consigliabile creare un ramo per ogni storia utente, perché ciò comporta costi di integrazione elevati. Benché Team Foundation Server semplifichi la creazione di rami, il sovraccarico di gestione dei rami può diventare significativo in presenza di molti rami.
In che modo il team gestisce i rilasci dal punto di vista del controllo della versione?
Il team deve essere in grado di rilasciare il codice alla fine di qualsiasi sprint. Con Team Foundation Server è possibile applicare un'etichetta a un ramo per creare uno snapshot del codice in un momento specifico. Come illustrato nella figura seguente, è possibile applicare un'etichetta al ramo MAIN per un rilascio. Ciò consente di tornare allo stato del ramo di quel momento specifico.
Poiché può essere necessario implementare aggiornamenti per i rilasci, la creazione di un ramo per un rilascio consentirà al team di continuare a lavorare in modo indipendente sullo sprint successivo senza creare conflitti con i rilasci futuri. La figura seguente illustra un ramo contenente il codice per un aggiornamento e su cui viene eseguita un'integrazione all'indietro nel ramo MAIN dopo un rilascio alla fine del secondo sprint.
Quando si crea un ramo per una rilascio, è consigliabile crearlo dal ramo MAIN, che è più stabile. La creazione di un ramo per un rilascio da un ramo di lavoro può provocare difficoltà di integrazione, in quanto la stabilità dei rami di lavoro non è garantita.