Come possiamo includere solo funzioni pronte per il rilascio nelle nostre versioni di produzione ogni due settimane?


12

Sono uno sviluppatore software di un team agile abbastanza grande (abbiamo otto sviluppatori che stanno attivamente apportando modifiche a un singolo repository di codice). Ogni due settimane, portiamo in produzione una nuova versione del nostro software. Ecco il nostro flusso di lavoro attuale:

  • Quando si avvia una nuova attività, gli sviluppatori creano un "ramo di funzionalità" al di fuori del ramo di sviluppo principale (usiamo git ) e lavorano a partire da questo nuovo ramo
  • Una volta che uno sviluppatore ha terminato di lavorare sulla propria attività, unisce nuovamente il proprio ramo di funzionalità al ramo di sviluppo
  • Lo sviluppatore unisce il ramo di sviluppo nel ramo QA.
  • Una build viene attivata al di fuori del ramo QA. L'output di questa build viene distribuito nel nostro ambiente QA per consentire ai tester di iniziare i test.

È abbastanza comune per i nostri tester trovare problemi con queste nuove funzionalità che sono state unite nel ramo QA. Ciò significa che in qualsiasi momento, l'ambiente QA probabilmente contiene diverse nuove funzionalità: alcune testate e prive di bug e altre non funzionanti. Questo rende difficile il rilascio perché è raro che la build QA sia pronta per la produzione.

Per mitigare questo, abbiamo cercato di avviare un "blocco del QA", il che significa che gli sviluppatori non uniscono il nostro ramo di sviluppo nel ramo del QA un paio di giorni prima del rilascio. Le correzioni di bug nell'ambiente QA vengono eseguite direttamente sul ramo QA e unite al ramo di sviluppo. Teoricamente, questo mantiene le nuove funzionalità non funzionanti fuori dal QA, consentendoci comunque di risolvere problemi già presenti nel QA.

Sebbene questo concetto di "blocco del QA" abbia avuto in parte successo, è difficile coordinarlo e le persone sono spesso confuse sul fatto che possano unirsi al QA. È stato anche difficile fissare una scadenza per il "blocco del QA": a tutti piace l'idea di un po 'di respiro tra il congelamento e il rilascio, ma in pratica, preferirebbero avere la loro caratteristica nella prossima versione piuttosto che rispettare la scadenza.

Esiste un modo migliore per garantire una build pulita per le nostre versioni ogni due settimane?


3
Sono i bug che provengono da problemi di regressione (in cui il test di regressione sarebbe utile), casi d'uso mancati (nella nuova funzionalità manca un caso speciale che necessita di modifiche) o collisioni con altre funzionalità che vengono costruite contemporaneamente (quindi la seconda funzione che viene unita causa problemi che sorgono)? Mi chiedevo se la radice potesse essere ristretta un po 'qui.
JB King,

1
Abbiamo avuto questo esatto problema. La risposta è QA creare il proprio ramo. Non congelano quello principale. Quando si verifica il rilascio, il ramo viene nuovamente unito, etichettato ed eliminato . Anche la sala di respirazione è QA può consentire alle cose di fondersi in questo ramo caso per caso. Ma il lavoro normale continua normalmente
Richard Tingle il

2
Uscire dall'argomento "bisettimanale" è considerato un termine pericoloso . Alcune persone pensano che significhi due volte a settimana, altre ogni 2 settimane
Richard Tingle il


@JBKing Praticamente tutto quanto sopra. Direi che il più comune è che il tester trova un bug nella nuova funzionalità o che la nuova funzionalità provoca un bug di regressione non correlato alla nuova funzionalità.
Nathan Friend,

Risposte:


9

Ci sono alcuni problemi che fluttuano in questo che causano problemi che si verificano.

Il primo è il ramo QA di lunga durata. Avere un ramo di lunga data che è parallelo alla linea principale di sviluppo può essere fonte di confusione perché ci sono diversi sforzi che devono essere replicati sia nel ramo QA che nella linea principale. Ciò significa che o stai controllando le correzioni nel ramo QA che devono essere unite alla linea principale (non è una cosa negativa) o stai controllando la linea principale che viene unita nel ramo QA (una fonte di possibili bug) .

L'altro problema con il ramo parallelo a esecuzione prolungata è che è possibile che i file diventino perpetuamente fuori sincrono. Una correzione di codice che non viene mai unita o una configurazione necessaria per build di produzione che non viene mai testata e che fa parte della linea di sviluppo principale.

Successivamente, hai ruoli che vengono influenzati. Ciò significa che il ruolo dell'imballaggio (ne parleremo più avanti) non viene sufficientemente isolato.

Nel modello git-flow , il ramo di rilascio viene ramificato dallo sviluppo ( non lo sviluppo unito al QA) e tutte le correzioni vengono controllate nel ramo di rilascio e quindi riunite al ramo di sviluppo.

Parte della filosofia della ramificazione si trova nelle Strategie di ramificazione avanzate di SCM (ritengo sia una lettura eccellente). Questo si concentra sui ruoli che ogni ramo può assumere. Il ramo di rilascio assume il ruolo di impacchettamento.

Il ruolo di packaging è spesso confuso con l'accumulo o, più comunemente, i ruoli principali. Una volta che lo sviluppo e la manutenzione previsti sono stati eseguiti e sono stati effettuati eventuali accumuli, è tempo di preparare il codice per il rilascio. Un tale sforzo potrebbe non essere banale, richiedendo un team di ingegneri del rilascio e correzioni aggiuntive oltre a quelle già eseguite. La politica relativa a una filiale di imballaggio è significativamente diversa da quella di una filiale di manutenzione, come suggerisce il ruolo dell'imballaggio, dovrebbero essere affrontate solo le modifiche necessarie per rendere il prodotto rilasciabile.

  • Diramazione dal punto di sviluppo al ramo di rilascio. Il ramo di rilascio che crea il QA ottiene un ramo e non si fonde dallo sviluppo.
    • Se si desidera percorrere quella strada, con nomi e hook coerenti, è possibile impedire che un'unione venga eseguita in un ramo di rilascio.
  • Risolvi tutto ciò che deve essere risolto nel ramo di rilascio e unisci quelle modifiche alla linea principale.
  • Al termine dello sforzo di rilascio, unire il ramo di rilascio nel ramo "Rilasci vai qui" e contrassegnarlo come tale.
    • Alcuni siti non hanno un ramo "Rilasci vai qui" e lasciano semplicemente la fine del ramo di rilascio penzolante con un tag.

Si dovrebbe prendere seriamente in considerazione l'applicazione dell'intero flusso git in atto. Questo non è troppo lontano da ciò che viene fatto attualmente e mette un po 'di disciplina e coerenza sul significato di ogni ramo e su come ogni ramo interagisce con gli altri.


"I rilasci vanno qui" è stato conosciuto per essere chiamato "funzionante".
RandomUs1r

10

Il problema mi sembra che tu abbia un singolo ramo QA.

Per ogni versione, creare un ramo QA separato dal trunk / master di sviluppo primario. Quindi unisci solo le correzioni dei bug per le funzionalità di quel ramo - mai nuove funzionalità. Fai testare la qualità in quel ramo.

In questo modo, il "congelamento" è abbastanza evidente - è nel nome del ramo. Potresti usare qualcosa del tipo, non lo so release/26/10/2015. Quindi è ovvio che nessuno dovrebbe fondersi con nuove funzionalità dopo questo.

È particolarmente utile se non attraversi nemmeno il ramo fino al congelamento. Le persone possono unirsi al master in qualsiasi momento, semplicemente non farà parte di questa versione se non viene eseguita in tempo per essere testata.

Non hai un singolo ramo QA di lunga durata, che sta solo chiedendo problemi. Fork dal ramo di sviluppo principale per ogni versione e QA quel ramo.


1
Avere una filiale il cui nome ricorda la scadenza del congelamento mi sembra un'ottima idea (+1) purché gli sviluppatori non continuino a lavorare su funzionalità non finite e chiamino questo "bug fixing".
Giorgio,

4

Sei in qualche modo mappato al modello di ramificazione Sviluppo-MAIN-Produzione visto di seguito. L'area sopra MAIN si dice che sia l'area di sviluppo. L'area sotto PRINCIPALE è l'area di produzione.

Modello di ramificazione Sviluppo-PRINCIPALE-Produzione

Punti salienti di questo modello che ritengo rilevanti per te:

  • I tuoi sviluppatori hanno bisogno di Forward Integrate (FI) (FI = unisci lontano da MAIN) frequentemente (2-3 volte a settimana) nei loro rami DEV per garantire che le loro ultime modifiche prendano sempre in considerazione gli ultimi sviluppi generali.
  • I tuoi sviluppatori devono Reverse Integrate (RI) (RI = fusione verso MAIN) nel ramo TEST solo quando hanno raggiunto un traguardo di completamento delle funzionalità che vogliono esporre al QA e per i quali sono pronti a fornire soluzioni rapide in risposta al feedback QA. Le correzioni verranno eseguite sul ramo TEST e immediatamente FI nel ramo DEV.
  • Mai RI da qualsiasi ramo DEV in MAIN
  • Sempre RI dalla filiale TEST a MAIN, esclusivamente quando il QA ritiene che la qualità di TEST sia OK. Mantenere una soglia di alta qualità per la fusione in MAIN. Per lo meno, il tuo Product Manager deve essere in grado di dimostrare sempre una versione funzionante del tuo prodotto dall'ultimo commit in MAIN.
  • Creare filiali nell'area di produzione solo se necessario. Il tuo server di compilazione dovrebbe sempre etichettare tutti i rami, compresi quelli dell'area di sviluppo, e la fonte di qualsiasi build / release dovrebbe essere identificabile in ogni momento, indipendentemente dal ramo da cui proviene.
  • Prendi le pubblicazioni per la produzione solo da MAIN o dall'area di produzione. Se in seguito è necessario fornire una correzione per una versione rilasciata esatta (ovvero non è possibile fornire l'ultima versione da MAIN), creare un ramo nell'area di produzione dal tag MAIN della versione difettosa, quando è necessaria la correzione. Risolvi sempre il problema sul ramo HotFix e quindi immediatamente RI in MAIN e FI in TEST.

Sospetto che tu abbia problemi perché:

  • I tuoi sviluppatori trasformano il codice TEST in codice non completo
  • I tuoi sviluppatori sviluppano il RI in TEST senza ottenere il via libera dal QA (ovvero il QA non ha il controllo di ciò che viene iniettato nel TEST)
  • Quando il QA segnala un bug su TEST, i tuoi sviluppatori lo risolvono sul loro ramo DEV e poi RI in TEST. Questa è una cattiva pratica importante perché l'unione porterà sempre in altra merda di sviluppo incompleta. Dovrebbero sempre ripararlo su TEST e poi FI nel loro ramo DEV. Se non è riparabile su TEST, in primo luogo hanno fornito una schifezza totale e hai problemi più grandi.
  • I tuoi sviluppatori non effettuano FI abbastanza spesso da TEST e quindi destabilizzano TEST ogni volta che li consegnano. È una buona arte bilanciare la frequenza con cui FI in DEV. Rimandalo troppo e sarà estremamente costoso e rischioso prima della consegna, cosa che non vorrai mai. Fallo troppo spesso e non realizzi alcun vero lavoro di sviluppo se ti sovrapponi troppo con il lavoro svolto da altre persone in TEST nel frattempo.

2

Come capisco la domanda hai due problemi. (a) le funzionalità non funzionanti vengono unite alle funzioni valide che si desidera rilasciare; (b) vuoi essere in grado di rilasciare le buone funzionalità mentre trattieni quelle rotte. Come vincolo alle possibili soluzioni, suppongo che desideri che i tuoi test QA finali / ufficiali vengano eseguiti su un ramo integrato che contenga tutte le funzionalità previste per la prossima versione.

Indipendentemente dal modello di diramazione SCM, ti suggerisco di provare una o entrambe le seguenti:

  1. Assegna una risorsa QA a ciascun team di funzioni. Invitali a fare alcuni test delle funzionalità su build dal ramo delle funzionalità e a dare loro l'autorità di decidere quando una funzionalità è abbastanza buona da unire. Idealmente, falli lavorare in collaborazione con (il resto del) team delle funzioni, quindi le cose vengono testate poco dopo essere state scritte. (Nota che questo non significa che devono fare tutti i test da soli.)
  2. Utilizzare gli interruttori funzione, anziché i rami funzione o in aggiunta a loro. Fatto a destra, gli interruttori funzione ti consentono di disattivare una funzionalità interrotta senza provare a separarla dal codice, in modo da poter testare e rilasciare le altre funzionalità. Il tipo di interruttore di cui sto parlando non è accessibile ai clienti; non vuoi testare un numero esponenzialmente crescente di combinazioni. Impostate gli interruttori sul ramo QA in modo che corrispondano alle funzioni che state pianificando di rilasciare e se il piano cambia perché una funzione non è pronta, cambiate quell'interruttore.

1

Una soluzione molto semplice che ho visto lavorare in una squadra un po 'più grande della tua è far lavorare e distribuire tutti da un singolo ramo.

Dici che il team è agile ma non è chiaro se stai lavorando in sprint (ad esempio Scrum) o in un approccio a flusso più continuo (ad esempio Kanban). Supponendo che tu stia facendo degli sprint, lo scopo del team è quello di avere il codice rilasciabile alla fine di ogni sprint, per il tuo rilascio quindicinale. Non c'è confusione sul fatto che una funzionalità ne interromperà un'altra poiché sono state tutte sviluppate insieme. I tester possono essere in grado di accedere alle funzionalità in blocchi più piccoli poiché il sovraccarico per gli sviluppatori di fornire loro è inferiore. E non hai davvero bisogno di un QA-Freeze, invece tutti sanno quando è la fine dello sprint e non dovrebbero intraprendere un lavoro che non possono finire o lasciare in uno stato distribuibile (cioè disabilitato).

Ovviamente ci sono pro e contro in ogni approccio, lo presento come un'opzione non necessariamente il "modo migliore".


Controllare tutto nella linea principale è un approccio, sebbene un rischio elevato o cambiamenti più significativi possano causare qualche disturbo. Inoltre, una determinata versione si riferisce spesso a un set specifico di funzionalità. L'aggiunta di più funzionalità che il marketing non ha promesso può portare a problemi. Separare lo sforzo di rilascio dallo sforzo di sviluppo è spesso una cosa necessaria. Il QA tende a infastidire quando stavano testando l'interfaccia utente per la prossima versione e improvvisamente tutto cambia e devono ripetere il test.

In effetti, è necessario un migliore coordinamento tra ciò che va nello sviluppo e ciò che il marketing desidera. Probabilmente finisci con l'uso dei flag delle funzionalità nel codice per abilitare / disabilitare alcune funzionalità, che è un modello abbastanza comune. Direi che se i test fossero sorpresi da un cambiamento che gli sviluppatori hanno apportato, probabilmente potresti beneficiare di un più stretto allineamento tra tester e sviluppatori. Vale a dire lavorando su team interfunzionali, quindi nulla viene cambiato senza la conoscenza dei tester, o loro dicono così. Ovviamente ciò non è sempre possibile e devi modificare i tuoi processi in base al principio.
Robin,

1

Il motivo per cui stai riscontrando questi problemi è perché il tuo codice rilasciato al QA non è abbastanza buono (ed è qualcuno ?!), quindi devi iniziare a ottenere un rilascio migliore al QA in modo che non debbano ricevere correzioni così spesso. il modo più semplice per farlo è introdurre un ramo intermedio a cui si rilascia (chiamiamolo test). Questo è ancora di competenza dello sviluppo, ma consente agli sviluppatori di spingerlo per continuare a lavorare, pur avendo un ramo integrato che dovrebbe essere di qualità sufficiente per essere inviato al QA.

Il test di integrazione può essere eseguito su questo ramo al fine di trovare i bug che il QA sta attualmente rilevando, i bug possono essere corretti sul ramo originale e quindi uniti di nuovo, e di nuovo fino a quando non è possibile correggere direttamente i bug su questo ramo (consiglio ex). Una volta superato un sacco di test di base, può quindi essere inviato al QA per "le dita appiccicose dell'utente e il loro-cosa-cosa?" test.

Quindi questo approccio è progettato per proteggere il ramo QA da funzionalità di sviluppo non funzionanti, sia che ciò sia dovuto al fatto che la funzione non è stata codificata abbastanza bene sia che non ci siano problemi di integrazione imprevisti. Solo i rami di sviluppo che superano i test di integrazione possono essere promossi al QA.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.