Come utilizzare Git Flow con più progetti dipendenti

7

Stiamo provando a lavorare su una strategia di ramificazione efficace per la nostra organizzazione, in modo che rilasci, versioning e simili vengano gestiti in modo coerente.

Abbiamo molte soluzioni basate su C #, ognuna con un numero qualsiasi di 2-60 progetti. Ogni soluzione si riferisce a un particolare prodotto per il quale pubblichiamo aggiornamenti su base regolare. Questi prodotti hanno una certa interdipendenza, ma non molto. Quando attraversano, per tradizione abbiamo creato un progetto di tipo proxy che fornisce la logica per accedere alla risorsa ai progetti dipendenti.

Ad esempio, abbiamo un sito Web API Web che ha un progetto proxy per astrarre gli endpoint (creare un Web Client, autenticare e effettuare la chiamata all'URL), quindi gli altri progetti devono semplicemente chiamare quel proxy. Questi progetti proxy condividono un numero di versione con il progetto a cui si riferiscono e vengono rilasciati / consumati tramite un feed NuGet interno. Generalmente seguiamo SemVer per aiutare a gestire eventuali modifiche di rottura, con il controllo della versione appropriata sul progetto proxy (ad esempio l'API Web) per garantire che il comportamento funzioni come previsto.

Questa strategia ha funzionato bene per noi, ma sembra che ci sia una caduta che non possiamo superare: il ciclo di rilascio.

In base a Git Flow, abbiamo tagliato% ramo% di% del nostro ramo release primario per ogni soluzione (rilasciamo contemporaneamente tutti i nostri prodotti contemporaneamente). All'interno di questo ramo, incrementiamo il numero di versione (maggiore / minore in base al tipo di modifiche) e aggiorniamo i pacchetti NuGet interni alla versione più recente. Queste filiali di rilascio si collegano al nostro ambiente QA finale, che è il luogo in cui tutti i prodotti vengono testati insieme per i bachi emergenti e si verifica una segnalazione finale.

Tecnicamente, dovremmo essere in grado di finalizzare tutti i rami di rilascio e distribuire il codice risultante da ciascun ramo principale. Tuttavia, si verificherebbe una mancata corrispondenza della versione tra gli assembly distribuiti e quelli consumati.

Un esempio di chiarezza:

Abbiamo il progetto A, che include un Proxy Project A e non ha dipendenze, e Project B, che consuma il Proxy Project A.

Suppongo che ogni commit, indipendentemente dal ramo, sia costruito con un numero di versione univoco per progetto, e distribuiamo gli assembly creati dal ramo develop .

  1. Abbiamo tagliato i nostri due rami master : release (che produce A 1.0.0.001 e A 1.0.0.001 ) e A Proxy 1.0.0.001 (che produce B 1.0.0.001 ).
  2. Entrambi i progetti ottengono il numero di versione avanzato di un numero di versione secondario: B 1.0.0.001 e A 1.1.0.002
  3. Aggiorniamo i pacchetti NuGet per il Progetto B: B 1.1.0.002 , che ora consuma B 1.1.0.003
  4. Il test è completato, non sono stati trovati errori, è stata approvata la firma finale. Entrambi i progetti sono uniti a A 1.1.0.002 : master e A 1.1.0.003 (consumo B 1.1.0.004 )

Tuttavia, ora c'è una discrepanza nei numeri di versione - abbiamo distribuito A 1.1.0.002 , ma stiamo consumando A 1.1.0.003 . In questo caso, potremmo essere in grado di assumere che questi contengano lo stesso codice esatto e che la differenza nei numeri di versione sia dovuta a un'unione di diramazione, che è vera qui, ma potrebbe non essere sempre.

In passato, il modo in cui abbiamo lavorato attorno a questo era di unire sequenzialmente i rami di rilascio in ordine della catena di dipendenze e aggiornare i progetti dipendenti, ma se un bug viene trovato a monte nel ciclo di rilascio, non abbiamo modo di applicare patch fuori da un ramo A 1.1.0.002 (che non sembra avere senso perché il codice non è tecnicamente ancora implementato - è ancora in fase di test a causa dei prodotti dipendenti, e non è ancora stato completamente disconnesso).

Come possiamo risolvere questo paradosso? Dobbiamo mantenere sincronizzati tutti i cicli di rilascio del prodotto a causa della relazione dipendente tra di loro, ma vogliamo anche garantire che per ogni prodotto e dipendenza siano state rilasciate le versioni che sono state testate e firmate.

    
posta kingofzeal 31.03.2017 - 14:57
fonte

3 risposte

2

Non capisco come sia arrivato all'improvviso alla versione B 1.1.0.003, tuttavia non posso fare a meno di pensare che lo stai rendendo molto più complicato di quanto dovrebbe essere. Hai detto a te stesso che tutti i tuoi progetti verranno rilasciati contemporaneamente, e questo è probabilmente dovuto alla ragnatela di dipendenze che i progetti sembrano avere l'uno con l'altro. Un singolo cambiamento per un hotfix nel Progetto A sembra che possa avere un effetto downstream in cui Project B probabilmente deve aggiornare la sua dipendenza dalla versione del Progetto A alla nuova versione di aggiornamento rapido, facendo in modo che Project B abbia una nuova versione di aggiornamento rapido ed ecc. .

Sviluppo ramo

Il modo di pensare al ramo di sviluppo di qualsiasi progetto è per lo sviluppo continuo verso la prossima versione maggiore o minore di quel componente software. Solo dopo che questo è stato accuratamente testato e pronto per il test del QA finale, dovrai mai impegnarti in un nuovo numero di versione.

Rilascia ramo

Quando ti sei impegnato con un nuovo numero di versione e tutto è a posto, aumenti i numeri di versione maggiore o minore e aggiorna le dipendenze. È finalmente ufficiale, questi componenti stanno entrando in produzione. Puoi sempre rebase il tuo ramo dev in un secondo momento e ora il tuo ramo dev ha il numero di versione più recente in produzione e le ultime correzioni di bug che sono state risolte nel ramo Release.

Ramo di aggiornamento rapido

Fondamentalmente uguale alla versione, tranne che per modificare l'aggiornamento o il numero di patch nelle versioni del componente software.

Numeri di build di Nuget per il salvataggio

I numeri di versione ufficiali dovrebbero essere incrementati o modificati SOLO per codice "completo" stabile. Tutti gli altri codici sono considerati in fase di sviluppo, pertanto, quando si gestiscono le modifiche delle dipendenze attualmente in fase di sviluppo, è necessario utilizzare gli strumenti in Nuget per fare riferimento alle dipendenze su versioni + numeri di build. I numeri di build sono intrinsecamente temporanei e possono essere rimossi prima di unire nuovamente il Release in Master. Capisco che ci sono altri strumenti che lo fanno ancora meglio come Paket.

    
risposta data 05.04.2017 - 14:24
fonte
1

Non so come esattamente crei i numeri di versione. Viene creato un nuovo numero anche quando un'unione potrebbe essere una unione rapida in avanti ? In caso contrario, vedo la possibilità di risolvere il problema effettuando l'unione nel passaggio 4. un'unione che potrebbe essere un'unione avanti veloce. In realtà questa unione non è mai un'unione avanti veloce perché Git Flow utilizza

git merge --no-ff release   

durante l'unione nel ramo principale.

Penso che il punto principale sia se c'è qualcosa nel ramo principale che può causare l'unione nel passaggio 4. non potrebbe essere veloce. Se questa fusione non può essere un'unione avanti veloce, terminerai con qualcosa di diverso nel master rispetto a quello testato nel ramo di rilascio. Se segui correttamente il flusso Git, la differenza è solo nell'ordine delle modifiche applicate. (Nel tempo del primo aggiornamento rapido è possibile avere già diversi commit nello sviluppo del ramo.)

È possibile unire il master nel ramo di rilascio una volta creato e dopo ogni aggiornamento rapido inviato al master. Ciò assicurerà l'unione nel passaggio 4, potrebbe essere un'unione avanti veloce.

L'ultima cosa da sistemare è quella di regolare il controllo delle versioni in modo tale da non produrre nuovi numeri di versione per le unioni che potrebbero essere veloci. Non ho esperienza con questo. Sto solo pensando al tuo problema. Potrebbe essermi perso qualcosa di importante.

    
risposta data 05.04.2017 - 13:35
fonte
1

Abbiamo utilizzato cambiamento atomico flusso sincronizzato su più repository con esito positivo su una situazione simile in passato.

L'idea di base è che tu mantenga i cambiamenti atomici nel loro ramo il più a lungo possibile. Per alleviare la complessità della sincronizzazione e unire l'inferno utilizzando i rami di "rilascio assembly" intermedi, lo sviluppo (o rami sussidiari simili) può essere interrotto in qualsiasi momento, e ti unisci al master solo quando distribuito in prod.

    
risposta data 05.04.2017 - 20:19
fonte

Leggi altre domande sui tag