Branching interrompe l'integrazione continua?

16

Penso che questo articolo, Un riuscito modello di Branca di Git , sia molto conosciuto tra utenti DVCS esperti.

Uso principalmente hg , ma direi che questa discussione va bene per qualsiasi DVCS.

Il nostro attuale flusso di lavoro è che ogni sviluppatore clona il repository principale. Scriviamo codice sul nostro repository locale, eseguiamo test e, se tutto va bene, spingo al master.

Quindi vogliamo configurare server CI come Jenkins e migliorare il nostro flusso di lavoro con il futuro sistema di provisioning (chef, fantoccio, ansible, ecc.)

Parte reale

Bene, il modello qui sopra funziona bene ma i rami possono rompere l'IC. Il ramo della funzione dovrebbe sincronizzarsi con l'origine (secondo l'articolo, sarebbe development branch) per rendere CI e fondersi liscio, giusto?

Dire che Alice e Bob stanno lavorando su due funzioni. Ma Alice è fatta il giorno dopo. La funzione di Bob dura una settimana. Quando Bob ha finito, le sue modifiche sono obsolete (forse Alice ha refactorato / rinominato alcune classi).

Una soluzione è ogni mattina che gli sviluppatori devono tirare master/origin per verificare se ci sono cambiamenti. Se Alice si impegna, Bob deve tirare e unirsi nel suo spazio di lavoro in modo che il suo ramo di funzionalità sia aggiornato.

  1. È un buon modo?
  2. Questi branch dovrebbero esistere nel master repo (non il clone locale?) Significato: ogni sviluppatore ha il privilegio di commit sul master repo su GitHub / Bitbucket in modo che possano creare un nuovo ramo? O questo è fatto localmente?
  3. Infine, il modello presentato dall'articolo dovrebbe interrompere l'IC se i rami non sono sincronizzati con origin/master . Dal momento che vogliamo fare build notturni, gli sviluppatori dovrebbero estrarli e unirli prima che lascino il lavoro, e anche l'IC venga eseguito su ciascun ramo di funzione?
posta CppLearner 07.01.2013 - 07:53
fonte

3 risposte

11

Prima di tutto, l'uso di feature branch (per isolare il lavoro svolto su una funzione) e CI (per trovare i problemi di integrazione non appena vengono commessi) sono leggermente in disaccordo.

A mio parere, l'esecuzione di elementi di configurazione su feature è una perdita di tempo. Poiché i rami delle funzionalità vanno e vengono frequentemente, gli strumenti CI dovrebbero essere riconfigurati più e più volte. E quello per un ramo che molto probabilmente riceve solo gli aggiornamenti da una o due fonti che coordinano i loro check-in per evitare i problemi che un sistema CI deve rilevare.
Pertanto, non è necessario avere i branch delle funzionalità sul server del repository principale.

Come per le domande 1 e 3: è responsabilità dello sviluppatore assicurarsi che la build sul ramo di sviluppo principale non si interrompa quando si uniscono il loro ramo di funzione in esso. Come fanno questo è il loro problema, ma due possibili modi sono:

  • Estrai regolarmente le modifiche apportate al ramo di sviluppo principale nel ramo delle funzioni (ad esempio ogni giorno)
  • Una volta terminata la funzione, unisci il ramo di sviluppo principale al ramo della funzione e premi il risultato della fusione sul ramo di sviluppo principale.

In entrambi i casi, gli evidenti problemi di integrazione (ad esempio classi / file rinominati) vengono trovati e risolti per primi sul ramo di funzionalità. È probabile che i problemi più sottili vengano rilevati solo quando viene eseguita la compilazione notturna e dovrebbero essere risolti lì e poi.

    
risposta data 07.01.2013 - 11:20
fonte
5

In risposta a 1)

Qualsiasi modo funziona è un buon modo. Tuttavia : l'intera premessa dell'integrazione continua consiste nell'integrare continuamente . L'idea è di catturare i bug di integrazione non solo il prima possibile, ma all'interno del ciclo di feedback di sviluppo - cioè, mentre tutti i dettagli per il codice in prova sono nella memoria a breve termine dello sviluppatore che apporta le modifiche. Ciò significa che, in normali circostanze quotidiane, il lavoro deve essere integrato tra i rami di funzionalità su ogni commit, forse una volta ogni 15 minuti o giù di lì. Per ribadire: lo scopo principale dell'integrazione continua è di esporre i bug di integrazione, mentre tutti i dettagli sono nella memoria a breve termine degli sviluppatori che apportano le modifiche.

2)

Per lo più, le ramificazioni vengono create in Mercurial mediante la clonazione dei repository, quindi non è necessario assegnare a ogni sviluppatore i privilegi di commit per il repository master. Probabilmente, tuttavia, si vuole dare agli sviluppatori la possibilità di creare repository clonati sul server di integrazione continua, poiché non è sempre possibile eseguire test localmente. (Una volta avevo un sistema CI in cui i test di unità impiegavano 8 ore per funzionare su un cluster di 128 core). Inutile dire che gli sviluppatori non lo facevano, non potevano eseguire test localmente.

3)

Se hai le risorse computazionali per questo, sì, gli sviluppatori dovrebbero essere sempre aggiornati con la linea principale di sviluppo in ogni momento, in particolare prima di lasciare il lavoro, e dovresti eseguire test notturni su tutte le linee di sviluppo (sebbene la maggior parte dei sistemi CI non lo rende facile).

    
risposta data 07.01.2013 - 10:19
fonte
1

Ecco come puoi farlo: feature branching.

  1. Per qualsiasi nuova attività (bugfix, funzionalità, ecc.) avvia un nuovo ramo (ad esempio bugfix-ticket123-the_thingie_breaks)
  2. Mentre lavori, aggiorna e unisci continuamente default (o master in git) nel tuo ramo delle funzioni . Questo ti aiuta ad avere il tuo ramo aggiornato senza dover lavorare nel ramo predefinito
  3. Quando la tua funzione è pronta e i tuoi test di unità passano , quindi tira e unisci di default nel tuo ramo ancora una volta, chiudi il tuo ramo e spingilo senza unire , il tuo integratore noterà il nuovo capo e che è un ramo chiuso, quindi si prenderà cura di integrarlo. Se non hai un integratore, passa a quello predefinito e unisci il ramo della funzione in default .

La cosa importante qui è che avrai 0 conflitti nel ramo predefinito quando unisci il tuo ramo di funzione al suo interno e tutti i tuoi test passano .

Con questo semplice flusso di lavoro avrai sempre un ramo predefinito incontaminato e stabile, ora fa lo stesso per i rami di rilascio, ma l'integrazione è predefinita . Se devi integrare gli hotfix direttamente nei rami di rilascio, puoi farlo saltando il ramo predefinito, ma di nuovo, selezionando solo i rami appena aggiornati dal ramo di destinazione e senza conflitti e passando i test delle unità.

    
risposta data 07.01.2013 - 12:25
fonte

Leggi altre domande sui tag