Evita che i rami si accumulino


19

Stiamo iniziando a riscontrare un problema man mano che diventiamo più grandi, in cui le funzionalità arrivano alla messa in scena per i test, ma quando tutto viene testato e le nuove funzionalità approvate sono in fase di messa in scena per i test.

Questo sta creando un ambiente in cui non possiamo quasi mai spingere alla produzione perché abbiamo una combinazione di funzionalità testate e non testate. Sono sicuro che questo è un problema comune, ma non ho ancora trovato buone risorse per noi.

Alcune specifiche:

  • GIT su BitBucket
  • Jenkins per la distribuzione tramite script in Azure

Quello che spero è un modo per isolare le funzionalità mentre si spostano attraverso gli ambienti e spingono solo ciò che è pronto a stimolare.


1
Stai effettuando la diramazione per ogni funzione o stai spingendo le modifiche alla funzione direttamente nel ramo del server di prova?
Robert Harvey,

1
Senza informazioni su come gestisci funzionalità e filiali non possiamo fornire una risposta specifica ai tuoi problemi.
Michael Durrant,

2
Lavori in qualche modo con le iterazioni (es. Sprint di due settimane o versioni)?
RemcoGerlich,

@RobertHarvey: stiamo ramificando per ogni funzione, ma abbiamo un ramo Dev, Stage e Prod in cui ci uniamo che costruisce e distribuisce automaticamente quel ramo in unione.
Wesley,

@RemcoGerlich: Al momento lavoriamo in sprint di tre settimane, ma con otto sviluppatori non vi è alcuna garanzia che i progressi che facciamo ogni ciclo siano perfetti su tutta la linea.
Wesley,

Risposte:


22

Sembra che tu abbia alcuni problemi qui:

1. Identificazione delle funzionalità per una versione specifica

Questo è un problema di gestione del progetto e un problema di coordinamento. Sarà questa caratteristica essere rilasciato prima, allo stesso tempo, come, o dopo questo altro caratteristica? Se le versioni vogliono accadere una funzionalità alla volta, identificala. Se le funzionalità verranno raggruppate in rilasci, quindi capire quali sono i raggruppamenti e applicarli agli sviluppatori e ai decisori. Utilizzare il sistema di tracciamento o emissione dei problemi per contrassegnare le versioni. Metti in chiaro che se una caratteristica di una versione specifica è un no-go, allora tutte lo sono.

2. Strategie di ramificazione

Git-flow è la risposta semplice a problemi come questi, e spesso le persone usano una variante di git-flow anche se non sanno di cosa si tratta. Non ho intenzione di dire che è un problema per tutti i problemi, ma aiuta molto.

Sembra che tu stia riscontrando un problema con le strategie di rilascio non deterministiche, in cui le funzionalità sono approvate scattershot e qualcosa che ha iniziato lo sviluppo molto tempo fa potrebbe essere rilasciato dopo qualcosa che è iniziato più di recente: le funzionalità di salto con la rana.

I rami di lunga durata o quelli a rilascio simultaneo sono probabilmente la risposta migliore per questo tipo di problemi. Unisci (o rebase, se ti senti a tuo agio con esso) le ultime novità dal master nei tuoi rami di vecchia data. Fai attenzione a unire solo le funzionalità che sono già attive, altrimenti ti imbatterai nei problemi che hai riscontrato ora (troppe funzioni confuse su un ramo).

I rami "Hotfix" o "bugfix" sono una parte essenziale di questo processo; usali per piccole correzioni singole che hanno un breve ciclo di QA.

Dalla tua descrizione, potrebbe anche essere meglio non mantenere un ramo di "sviluppo" ufficiale. Piuttosto, diramare tutte le funzionalità dal master e creare rami di rilascio uniti una volta identificato un rilascio.

3. Ambienti

Non abbinare i rami git ai tuoi ambienti, ad eccezione di production == master. Il ramo "sviluppo" dovrebbe essere considerato spezzato. Le filiali di rilascio vengono inviate agli ambienti di test, che si tratti di un ambiente di controllo qualità o di un ambiente di gestione temporanea. Se necessario, spingere un ramo di funzionalità specifico in un ambiente.

Se hai più di un ramo delle funzioni che devono essere rilasciati separatamente ma sono in fase di test allo stesso tempo ..... ¯ \ _ (ツ) _ / ¯ .... far girare un altro server? Magari uniscili in un ramo da buttare via ... commetti correzioni / modifiche ai rami originali e ricollegali nel ramo da buttare via; fare l'approvazione finale e UAT sui singoli rami di rilascio.

4. Rimozione di funzioni non approvate da una filiale

Questo è ciò che i pensieri di cui sopra stanno cercando di evitare, perché questa è senza dubbio la cosa più dolorosa da provare. Se sei fortunato, le funzionalità sono state unite nel tuo sviluppo o testano i rami atomicamente usando i commit di unione. Se sei sfortunato, gli sviluppatori si sono impegnati direttamente nel ramo sviluppo / test.

In entrambi i casi, se ti stai preparando per una versione e hai modifiche non approvate, dovrai utilizzare Git per eseguire il backout di quelle commit non approvate dal ramo di rilascio; l'idea migliore è farlo prima di testare il rilascio.

Buona fortuna.


NB: con un "ciclo di QA breve" per le filiali di hotfix, sto parlando di qualcosa che verrà portato alla produzione nel corso della giornata, praticamente. Emergenze. Alcune persone non li usano in questo modo, ma è quello che facciamo io e il mio team e sembra funzionare bene per noi.
Jen,

annuncio 1: la domanda ha un tag "integrazione continouus", quindi penso che l'OP voglia rilasciare immediatamente le funzionalità alla produzione una volta che sono state testate (abbastanza). Quindi l'esito del test potrebbe controllare l'ordine di rilascio alla produzione, il che è leggermente contrario alla tua raccomandazione.
Doc Brown,

... nondimeno penso che questa sia un'ottima risposta.
Doc Brown,

Concordato: ho rimosso il bit "ordine" dalla prima sezione. Penso che "ordinare" sia meno importante dell'identificazione delle versioni. Se l'obiettivo è CI, mantenere le funzionalità distinte per i test e le versioni è sicuramente più importante che mantenere un programma.
Jen,

Di solito non lo consiglierei nemmeno a me - ma la domanda si è posta specificamente sul tentativo di gestire il codice in cui alcune funzionalità non erano state testate e non approvate. Raramente lavoro su progetti che hanno tanta incertezza su quali funzionalità verranno rilasciate quando - di solito il programma di rilascio è piuttosto pianificato e un ritardo in una versione spingerebbe indietro anche al successivo. Cosa faresti invece?
Jen,

4

Ecco un'idea, Smetti di usare i rami di rilascio. Invece, inizia a creare gli interruttori funzione e gestiscili tramite la configurazione. In questo modo, si uniscono sempre i rami delle funzionalità in master e non dovrebbe mai esserci una domanda su quale versione sia in test o prod. Se hai una domanda su quali funzionalità / implementazioni sono attive in un ambiente, controlla il file di configurazione.


3

Questa dovrebbe essere una semplice questione di coordinamento tra test e produzione. Se stai usando i rami delle funzionalità in Git, smetti semplicemente di inviare i rami delle funzioni completati a Test durante un ciclo di test e riprendi quando il test è completo.

Se hai bisogno di un controllo migliore di questo, separa Test in un server di sviluppo e un server Test di collaudo e coordina i rami che verranno inviati al server Test di collaudo con il team di test. Qualcuno può quindi essere responsabile per dare il via alla distribuzione finale dal Test di accettazione alla produzione.


2

Il lavoro si accumula

Questo è un problema universale nella mia esperienza. Lo indirizzo con:

  • Gestione efficace delle versioni delle funzionalità da parte del proprietario del prodotto
  • Assicurarsi che i rami vengano eliminati quando vengono uniti
  • Limitare i lavori in corso (con limiti di colonna in Jira)
  • Revisione trimestrale di vecchi biglietti che languiscono, sia bug che funzionalità
  • Retrospettive per discutere i componenti del problema
  • Incoraggiamento costante per le revisioni del codice da parte di tutti
  • Associare opportunità per affrontare biglietti e problemi di vecchia data
  • Riunioni trimestrali per rivedere e ripulire i vecchi biglietti
  • Approccio di gruppo per far lavorare strettamente sviluppo, prodotto e QA / QE
  • Buoni rapporti e strumenti per rendere evidenti le nuove funzionalità del prodotto e l'arretrato
  • Rivedi le sessioni per passare attraverso i vecchi rami ed eliminarli

2

filiali

Hai bisogno di alcuni rami per controllare quel processo:

  • caratteristica : questi rami sono nati dal maestro. Utilizzare alcune applicazioni di gestione dei progetti per identificare ogni ramo di funzionalità con alcune attività. Per esempio, se si utilizza TRAC, si finirà se rami come: 1234-user-crud, 1235-bug-delete-catalog, ecc Identificare i vostri commit con il numero compito troppo, questo vi aiuterà molto quando si hanno problemi di unioni (si vuole).
  • test : tutti i rami funzione che vengono eseguiti verranno uniti al ramo test. Non unire mai il ramo di prova in un ramo di funzionalità , perché non si desidera il codice da un'altra funzionalità che non si trova nella produzione (master). Lo stesso vale per il releaseramo.
  • rilascio : quando decidi quali funzionalità testate possono essere nella produzione, unisci questi rami (di nuovo ...) in questo ramo. È necessario testare nuovamente tutte le funzionalità, perché questa unione può portare nuovi problemi. Quando la versione viene testata ed eseguita, si unisce questo ramo al master e si crea un tag sul master per la versione.
  • master : contiene solo il codice di produzione.

Vedi il flusso git:

                              |FEAT_2|
                                  |
                             .---C06<-------.---------.
                            /                \         \
                           /   |FEAT_1|        \         \
                          /       |            \         \
                         /    .--C07<--.--------\---------\---------.
                        /    /          \        \  |TEST| \         \
                       /    /            \        \    |    \         \
                      /    /        .-----`--C09<--`--C10    \         \ |RELEASE|
                     /    /        /                          \         \    |
    <v4.6.0>        /    /        /                       .----`--C11<---`--C12<--.
       |           /    /        /                       /                         \
C01<--C02<--C04<--´----´--------´-----------------------´---------------------------`--C13
 |           |                                                                          |
<v4.5.0>  <v4.6.1>                                                                   |MASTER|
                                                                                        |
                                                                                     <v4.7.0>

ambienti

Molto semplice:

  • test : questo ambiente utilizza il ramo di test.
  • release : questo ambiente utilizza il ramo di release effettivo.

Gli sviluppatori lavorano nella sua macchina, ognuno usando il proprio database. Se non è possibile ogni sviluppatore ha un singolo database (a causa di licenze, dimensioni del database, ecc.), Si avranno molti problemi nel condividere un database tra gli sviluppatori: quando qualcuno elimina una colonna o una tabella nel suo ramo, gli altri rami conta ancora con questa colonna / tabella nel database.

I problemi

Il problema più grande in questo processo sono le fusioni.

Devi rifare le stesse fusioni in teste release. Questo sarà doloroso se nel codice vengono creati alcuni buoni refactor, come eliminare una classe, spostare / rinominare metodi, ecc. Poiché non è possibile ottenere il codice dal ramo test(o release) nel ramo della funzione, i commit di unione possono essere risolti solo in il test(o release). Quindi, finisci per risolvere gli stessi conflitti in due rami diversi, probabilmente producendo codice diverso in ogni unione e, in futuro, scoprirai che il team di test dovrà testare le funzionalità due volte: nei rami teste release, perché ogni unione può provocare diversi bug.

Un altro problema è il testramo. Dovrai "riciclare" questo ramo (eliminalo e creane uno nuovo masterdi volta in volta), perché alcuni vecchi rami (o vecchie fusioni, rami uniti che sono stati eliminati) possono portare molti problemi per il nuovo codice, divergendo molto da ciò che è dentro master. In questo momento, hai bisogno del controllo di quali rami vorresti unire di nuovo in test.

La soluzione davvero migliore è che il team aziendale sappia cosa deve essere consegnato nella prossima versione e tutti lavorano in un ramo unico (sviluppo ramo). È positivo per loro la possibilità di scegliere quale funzionalità "fatta" vorrebbero essere nella prossima versione ogni volta che lo desiderano (penso che questo sia il tuo scenario), ma questo è un incubo per gli sviluppatori e (credo) per il team di test.


@DownVoter, perché?
Dherik,

0

Sembra che tu stia unendo le modifiche dal tuo ramo di integrazione al tuo ramo di produzione, che IMHO non è una buona pratica, esattamente per i motivi che menzioni. Non appena un ramo di produzione per una determinata versione viene estratto dal ramo di integrazione principale, il ramo di integrazione può, in qualsiasi momento, divergere (dopo tutto dovrebbe evolversi nella versione successiva). L'unione dal ramo di integrazione al ramo di rilascio corrente può comportare modifiche incompatibili con tale rilascio.

IMHO un processo adeguato sarebbe:

  • estrarre un ramo di produzione dal ramo di integrazione solo quando si ritiene che sia abbastanza vicino al livello di qualità desiderato, in modo che solo una manciata di modifiche dovrebbe ulteriormente completare il rilascio. In altre parole, il completamento delle funzionalità deve essere valutato (continuamente) sul ramo di integrazione, prima di estrarre il ramo di produzione.
  • dopo l'estrazione del ramo di produzione vengono apportate solo le modifiche selezionate, trattate come modifiche standalone / fisse - cioè verificate che funzionino effettivamente come previsto (solo perché una modifica funziona in un ramo non significa necessariamente che funzioni anche in un altro ramo).

0

Personalmente, sembra che potrebbe essere un problema di processo più che un problema di utensili. Alcune cose che suggerirei qui:

  • Non sono sicuro se hai gruppi Dev e QA separati. In tal caso, assicurati che Dev e QA partecipino alle riunioni di pianificazione e stima dello sprint. In una delle mie precedenti società, ci siamo assicurati che il numero di punti della storia che avevamo assegnato a una storia rappresentasse sia lo sviluppo che i test. (Potresti anche teoricamente avere due stime separate per lo sviluppo e lo sforzo di controllo qualità, ma in entrambi i casi è necessario che la stima includa entrambi; il tempo necessario per una storia è il tempo necessario per realizzarlo effettivamente). Anche se non hai un gruppo di QA separato, assicurati comunque di includere lo sforzo di test nelle tue stime.
  • Lungo una vena simile a quella sopra, concorda in anticipo su quante storie includerai in uno sprint particolare. Il numero di punti storia che accetti si basa sulla quantità che gli sviluppatori possono completare nel loro sprint e sul numero di elementi che il QA può testare nel loro sprint. (Presumo, ovviamente, che gli sprint di QA siano alla base degli sprint di Dev, ma puoi adattare questo al tuo processo). Se i tuoi sviluppatori possono finire 200 punti trama ma il tuo QA può finire solo 150 punti trama, ovviamente puoi fare solo 150 punti trama prima che il lavoro inizi ad "accumularsi" e finisci con un caso come quello che descrivi. (In un caso come questo, potresti voler indagare sulla causa del blocco stradale per tentare di mitigarlo).
  • Nessuno spinge nulla al QA fino a quando tutto ciò che è attualmente in QA non viene testato e consegnato .
  • Una funzionalità completa è quella che è stata testata e fornita. Se non viene consegnato, non viene eseguito.
  • Ovviamente, vuoi provare a farlo su una sorta di programma fisso. Una delle idee alla base di Integrazione continua e Agile è l'iterazione. Per definizione, l'iterazione comporta consegne frequenti. Integrazioni e consegne frequenti riducono al minimo il rischio di ciascuno.

Onestamente, penso che la cosa più importante sarà la disciplina su quando stai consegnando e su quante attività puoi effettivamente completare completamente in un determinato periodo di tempo.

Riassumendo: consegna al QA solo quando hai finito di testare e fornire le vecchie funzionalità.


-2

Quando "tutto viene testato e approvato", distribuire ciò che è stato testato e approvato per la produzione. Potrebbe essere un impegno particolare o potrebbe essere un particolare artefatto di generazione generato da Jenkins.

Non dovrebbe importare che i commit successivi nello stesso ramo non siano ancora stati testati.


1
È certamente importante che i commit successivi nello stesso ramo non siano stati testati e approvati: distribuire il codice alla produzione che non è stato testato è un modo sicuro per ottenere un client arrabbiato.
Jen,

Non sto suggerendo che gli commit successivi dovrebbero essere distribuiti. Sto dicendo di lasciare da soli quei successivi commit, distribuire quello che è stato testato.
bdsl,

In altre parole, ignora i rami, prendi la decisione di schieramento rispetto ai singoli commit o ai singoli build.
bdsl,
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.