Come possiamo tenere traccia della versione del nostro codice in ogni ambiente?

14

Il mio team utilizza attualmente un processo di distribuzione / distribuzione abbastanza semplice simile a questo:

                ┌────────┐ ┌────┐ ┌──────┐
 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 utilizza quel ramo. Quando vogliamo promuovere da un ambiente a un altro, ad esempio da DEV a QA, uniamo il ramo master a qa e avvia una nuova build QA (che viene quindi distribuita automaticamente nell'ambiente QA).

Stiamo valutando la possibilità di passare a un nuovo processo che eliminerebbe il possesso di una filiale dedicata e la creazione di ogni ambiente. Invece, una singola versione di rilascio 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 ad un altro non verrebbe più gestita nel controllo del codice sorgente; piuttosto, dovremmo semplicemente prendere i binari già costruiti (il "pacchetto di distribuzione") e rilasciarlo nel nuovo ambiente.

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

Il più grande svantaggio di questo nuovo sistema è che non abbiamo più un modo automatico per tenere traccia del codice in quale ambiente. Se abbiamo bisogno di fare una correzione in PROD, non abbiamo più una diramazione dedicata in sincronia con la base di codice di produzione corrente. Lo stesso vale per il QA: se vogliamo apportare una rapida modifica al QA senza dragare il lavoro in corso da master , non abbiamo più un ramo che rifletta lo stato corrente dell'ambiente QA.

Come possiamo tenere traccia del codice presente in ogni ambiente?

Alcune opzioni che stiamo considerando:

  • utilizzando tag git per tenere traccia di quale commit è in quale ambiente
  • incorporare il commit git utilizzato dalla build in ogni pacchetto di distribuzione
posta Nathan Friend 06.11.2015 - 22:58
fonte

3 risposte

14

I tag Git sono ciò che vuoi 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 build server può avere (come il numero di build).

Mentre quella è la risposta che stai cercando, risolve solo metà del problema. L'altro è "hey, ecco il% co_de distribuito sul server, da quale build proviene?" Sappiamo che non avrai mai versioni diverse dell'applicazione distribuite su dev e qa o prod. Giusto?

La soluzione a quella parte della domanda è che il server di build inserisca le informazioni nel manifest. Provenendo da un esempio di maven e svn che ho di fronte 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>

Questo è nella configurazione dell'archivio plugin maven-war. Ma lo puoi trovare anche in altri plugin. Quindi, in Hudson, parte dell'invocazione di generazione di maven è:

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

che imposta quelli definisce che quindi Maven preleva. E quindi è solo questione di cercare nel file MANIFEST.MF che è stato distribuito sul server per vedere quale versione è.

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

  • .[wje]ar - SHA dell'attuale
  • GIT_COMMIT - Nome del repository remoto (predefinito per origine), seguito dal nome del ramo attualmente in uso, ad es. "origine / master" o "origine / pippo"

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

    
risposta data 06.11.2015 - 23:24
fonte
3

Un approccio completamente diverso sarebbe quello di eliminare completamente l'idea di versions . Hai solo "una versione" che ha un comportamento configurabile diverso. L'unica differenza sarebbe che hai una base di codice comune - anche nella produzione dovresti implementare work in progress : ma non attivato.

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

L'attivazione / disattivazione viene eseguita tramite attiva / disattiva .

Upside: l'intero processo di rilascio è semplificato: stai sempre fornendo una versione integrata del tuo software. Ogni funzione è sempre disponibile in master . Non sono necessari ulteriori rami.

Non ci sono problemi con l'unione di feature, perché: nessuna succursale non ha bisogno di unire. Non vi è alcuna confusione su quale caratteristica è su quale diramazione e forse dipende o si scontra con le caratteristiche di altri rami. Ogni parte potrebbe essere attivata a piacimento. Anche un rollback non è più necessario: è solo un capovolgimento di un interruttore .

Non lo so, se questo funziona per il tuo codebase: i prerequisiti in termini di qualità del codice e disciplina dello sviluppatore sono piuttosto alti - devi occuparti di "cleanup" dopo che una funzione diventa < em> funzionalità di base e devi gestire un gruppo di toggles che impediscono un pasticcio più grande

Forse funziona per te.

    
risposta data 07.11.2015 - 12:44
fonte
-1

Usiamo Maven per inserire la versione nel file manifest. Quindi fare in modo che l'applicazione visualizzi la versione se è un'app Web o dispone di un endpoint / versione per i servizi Web.

    
risposta data 11.11.2015 - 01:35
fonte