Come possiamo tenere traccia di quale versione del nostro codice è presente in ogni ambiente?


14

Il mio team attualmente utilizza un processo di diramazione / distribuzione abbastanza semplice simile al seguente:

                ┌────────┐ ┌────┐ ┌──────┐
 Environments:  │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Builds:        │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Branches:      │ master │ │ qa │ │ prod │
                └────────┘ └────┘ └──────┘

Ogni ambiente ha il suo ramo (usiamo git ) e la sua build che usa quel ramo. Quando vogliamo promuovere da un ambiente all'altro, ad esempio, da DEV a QA, uniamo il masterramo qae iniziamo un nuovo build di QA (che viene quindi automaticamente distribuito nell'ambiente di QA).

Stiamo considerando di passare a un nuovo processo che eliminerebbe la presenza di un ramo dedicato e la creazione per ogni ambiente. Invece, una versione a rilascio singolo creerebbe un "pacchetto di distribuzione" che potrebbe quindi essere distribuito in qualsiasi ambiente. Immaginiamo che un tipico flusso di lavoro sia simile a questo:

                ┌────────┐     ┌────┐     ┌──────┐
 Environments:  │  DEV   │ ──► │ QA │ ──► │ PROD │
                └────────┘     └────┘     └──────┘

                      ▲ 
                       \ 

                        ┌───────────────┐
 Builds:                │ release build │
                        └───────────────┘

                                ▲
                                │

                ┌────────┐ ┌─────────┐
 Branches:      │ master │ │ release │
                └────────┘ └─────────┘

La promozione da un ambiente all'altro non sarebbe più gestita nel controllo del codice sorgente; piuttosto, prenderemmo i binari già creati (il "pacchetto di distribuzione") e li rilasciammo sul nuovo ambiente.

Questo nuovo sistema ci consentirebbe di distribuire qualsiasi build in qualsiasi ambiente, con diversi vantaggi. Ad esempio, è banale testare le correzioni di bug PROD in DEV e QA. Il nostro sistema attuale non fornisce un modo semplice per farlo senza il rollback di un ramo, che ovviamente vorremmo evitare.

Il più grande svantaggio di questo nuovo sistema è che non abbiamo più un modo automatico di tracciare il codice in quale ambiente. Se dobbiamo apportare una correzione in PROD, non abbiamo più un ramo dedicato sincronizzato con l'attuale base di codice di produzione. Lo stesso vale per il QA: se vogliamo spingere una rapida modifica al QA senza trascinare il lavoro in corso master, non abbiamo più un ramo che rifletta lo stato attuale dell'ambiente QA.

Come possiamo tenere traccia di quale codice è presente in ciascun ambiente?

Alcune opzioni che stiamo considerando:

  • utilizzando i tag git per tenere traccia di quale commit è in quale ambiente
  • incorporare il commit git utilizzato dalla build in ciascun pacchetto di distribuzione

Hai un sistema di CI come Hudson o Jenkins? È in grado di inviare tag a ciò che ha costruito su Git? (So ​​che ci sono plugin per Hudson e Jenkins che possono ... - non sono così sicuri degli altri).

@MichaelT Utilizziamo MSBuild per le nostre build e Octopus Deploy per le nostre implementazioni. Sono abbastanza fiducioso che potremmo far manipolare Octopus al nostro repository git con uno script di distribuzione Powershell personalizzato.
Nathan Friend,

Risposte:


14

I tag Git sono ciò che si desidera veramente utilizzare per designare le versioni. Il motivo è che hanno un significato per te e possono essere utilizzati per riconoscere rapidamente il collegamento tra il codice distribuito dallo stato e qualsiasi informazione che il server di compilazione potrebbe avere (come il numero di build).

Mentre questa è la risposta che stai cercando, risolve solo metà del problema. L'altro è "ehi, ecco il distribuito .[wje]arsul server, da quale build è venuto?" Sappiamo che non avrai mai diverse versioni dell'applicazione distribuite su dev e qa o prod. Giusto?

La soluzione a quella parte della domanda è che il server di compilazione metta le informazioni nel manifest. Provenendo da un esempio di maven e svn che ho davanti a me:

<manifestEntries>
    <Specification-Title>${project.name}</Specification-Title>
    <Specification-Version>${project.version}</Specification-Version>
    <Build-Number>${build.number}</Build-Number>
    <Build-Id>${build.id}</Build-Id>
    <Svn-Revison>${svn.revision}</Svn-Revison>
</manifestEntries>

È nella configurazione dell'archivio di maven-war-plugin. Ma puoi trovarlo anche in altri plugin. Quindi in Hudson, parte dell'invocazione di build maven è:

-Dbuild.number=${BUILD_NUMBER}
-Dsvn.revision=${SVN_REVISION}
-Dbuild.id=${BUILD_ID}

che imposta quelli definiti che poi la ripresa prende. E poi è solo una questione di cercare nel file MANIFEST.MF che è stato distribuito sul server per vedere di che versione si tratta.

C'è un plugin git , che offre un insieme simile di variabili d'ambiente tra cui:

  • GIT_COMMIT - SHA della corrente
  • GIT_BRANCH - Nome del repository remoto (predefinito su origin), seguito dal nome del ramo attualmente in uso, ad es. "Origin / master" o "origin / foo"

La combinazione di queste due pratiche consente di identificare facilmente la build (perché i numeri di build vanno avanti e hanno un significato, a differenza dei checksum sha) e il commit git specifico da cui è stata costruita.


3

Un approccio completamente diverso sarebbe di respingere versionscompletamente l'idea . Hai solo "una versione" che ha un comportamento configurabile diverso. L'unica differenza sarebbe che hai una base di codice comune - anche in produzione distribuiresti lavori in corso : ma non attivati.

La differenza si riduce solo a diversi set di funzionalità abilitate nel prodotto.

La disattivazione / attivazione viene eseguita tramite gli interruttori funzione .

Upside: l'intero processo di rilascio è semplificato: fornisci sempre una versione integrata del tuo software. Ogni funzione è sempre disponibile in master. Non sono necessarie filiali aggiuntive.

Non c'è alcun problema con l'unione delle funzioni insieme, perché: nessun ramo non è necessario unire. Non c'è confusione su quale caratteristica sia presente su quale ramo e forse dipende o si scontra con le caratteristiche di altri rami. Ogni parte può essere attivata a piacimento. Anche un rollback non è più necessario: è solo una rotazione di un interruttore .

Non lo so, se funziona per la tua base di codice: i prerequisiti in termini di qualità del codice e disciplina degli sviluppatori sono piuttosto elevati - devi affrontare la "pulizia" dopo che una funzione diventa una funzionalità di base e devi gestire un gruppo di opzioni prevenire un pasticcio più grande .

Forse funziona per te.


Ma che dire di avere diversi stati di repository distribuiti su server diversi? Il codice in esecuzione nella casella QA è uguale a quello in esecuzione per poter riprodurre un bug? Il codice che gli sviluppatori hanno inserito nella loro casella di sviluppo è uguale al codice su cui è in esecuzione il QA?

1
La domanda deve essere posta in modo diverso: è il bug con una configurazione speciale riproducibile "ora" se sì, puoi risolverlo. Se no, il bug è importante? Spingi sempre al lavoro (e al codice integrato).
Thomas Junk,

-1

Usiamo maven per inserire la versione nel file manifest. Quindi fare in modo che l'applicazione visualizzi la versione se si tratta di un'app Web o avere un endpoint / version per i servizi Web.

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.