È buona prassi memorizzare i numeri di versione del software in VCS?


22

Una versione del prodotto, ad esempio v1.0.0.100, rappresenta non solo una versione di produzione unica del software, ma aiuta a identificare i set di funzionalità e le fasi di aggiornamento rapido per tale prodotto. In questo momento vedo due modi per mantenere il pacchetto finale / build / versione binaria di un prodotto:

  1. Controllo versione. Un file da qualche parte memorizza il numero di versione. Il server di compilazione a integrazione continua (CI) avrà uno script per compilare il software che utilizza questo numero di versione del check-in per applicarlo a tutte le aree del software necessario (file binari, pacchetti di installazione, pagine della guida, documentazione, ecc.).

  2. Ambiente e / o parametri di costruzione. Questi sono mantenuti al di fuori del controllo della versione (cioè non sono legati allo snapshot / tag / branch). Gli script di build distribuiscono e usano il numero allo stesso modo, comunque ottenere il valore in modo diverso (è fornito allo script di build, invece di avere il know script in cui per farlo relativamente alla struttura di origine).

Il problema con il primo approccio è che può complicare le fusioni tra i rami principali. Se si mantengono ancora 2 versioni parallele dello stesso software, si risolveranno i conflitti quando si uniscono tra le due linee principali se la versione è cambiata su entrambe dall'ultima unione.

Il problema con il secondo approccio è la riconciliazione. Quando torni a una versione 1 anno fa, ti affidi esclusivamente alle informazioni sui tag per identificarne il numero.

In entrambi i casi, potrebbero esserci alcuni aspetti del numero di versione che non sono noti prima della build CI. Ad esempio, una build CI può inserire programmaticamente un quarto componente che è in realtà il numero di build automatizzato (ad es. 140a build sul ramo). Potrebbe anche essere un numero di revisione in VCS.

Qual è il modo migliore per tenere il passo con il numero di versione di un software? Le parti "note" devono sempre essere mantenute in VCS? E se è così, i conflitti tra i rami principali sono un problema?

Al momento manteniamo il nostro numero di versione tramite parametri specificati e mantenuti nel piano di costruzione CI (Atlassian Bamboo). Dobbiamo stare attenti prima di unirci alla nostra masterfiliale che i numeri di versione siano impostati correttamente prima dell'inizio della build CI . Per quanto riguarda il flusso di lavoro di Gitflow, ritengo che se il numero di versione fosse tracciato nel controllo del codice sorgente, potremmo garantire che sia configurato correttamente quando creiamo il nostro releaseramo in preparazione del rilascio. Il QA eseguirà i test finali di integrazione / fumo / regressione su questo ramo e al momento della firma, si verifica una fusione masterche segnala l'impegno a rilasciare.


3
Un conflitto di unione tra due versioni di un file in version.txtcui una versione contiene la riga singola 1.0.7e l'altra è 1.2.0davvero così difficile da risolvere? Se questo è l'unico conflitto nella fusione di due rami che si sono separati, mi ritengo molto fortunato. Quanto spesso si verifica? Se si verifica, non è una buona cosa che sei costretto a pensare a quale numero di versione dovrebbe avere la versione unita? (Ci scusiamo per l'uso ambiguo della parola "versione".)
5gon12eder

1
@ 5gon12eder Le difficoltà o i sentimenti sulla fusione stessa sono irrilevanti. È solo un aspetto negativo della soluzione globale.
void.pointer

Risposte:


28

Personalmente, scelgo l'opzione 3: mantenere le informazioni sulla versione nei metadati VCS , in particolare i tag.

Git lo rende molto semplice, poiché esiste un comando git describeche può descrivere in modo univoco un commit basato su un tag. Ecco come funziona:

  • Se il commit corrente è taggato, genera il nome del tag.
  • In caso contrario, a piedi, i ritroso la storia fino a trovare un tag e poi uscita una descrizione nel seguente formato: <tag>-<number of commits since the tag>-g<abbreviated commit hash>.
  • Se ci sono cambiamenti non impegnati nella workingtree, aggiungi -dirty.

Quindi, se stai eseguendo una build di rilascio e hai il tag taggato 1.2.3, verrà generato 1.2.3. Se stai attualmente lavorando su 1.2.4 e hai eseguito 4 commit da 1.2.3 e hai modifiche non confermate nella struttura, verrà generato 1.2.3-4-gdeadbee-dirty.

Questo è garantito per essere unico e monotonico, oltre che leggibile dall'uomo, e quindi può essere usato direttamente come stringa di versione. L'unica cosa che devi garantire è una convenzione di denominazione adeguata per i tag.


Adoro questa idea, ma sembra difficile da gestire con JIRA + Bamboo. Bamboo funziona solo sui rami, non sui tag, quindi dovresti assicurarti che venga premuto un tag prima che venga generata una build. Questo è soggetto a errori.
void.pointer

1
git describefunziona anche con i rami: " --all - Invece di usare solo i tag annotati, usa qualsiasi ref trovato nello refs/spazio dei nomi. Questa opzione consente di abbinare qualsiasi ramo noto, ramo di tracciamento remoto o tag leggero". Non sono sicuro di come funzioni con Bamboo, però. (Ciò richiederà ovviamente un'attenta denominazione dei rami, proprio come fa la modalità normale con i tag.)
Jörg W Mittag

1
Conosco alcune persone che fanno uscite completamente automatiche da Git. La stringa di versione è costruita da git describe, il ChangeLog è generato da git shortlog(beh, in realtà da uno script che analizza l'output di git log --pretty=tformat:<some custom format string>) e le note di rilascio sono generate dalla descrizione del tag e git notesassociate a importanti commit milestone.
Jörg W Mittag,

Il mio punto è che il tag dovrebbe essere creato prima del rilascio in modo che i commit dopo che siano stati correttamente sottoposti a versione con un numero di base. Ciò è contrario al principio di etichettatura durante o al momento del rilascio. Bamboo raccoglie le build automaticamente in base agli commit a master(da develop, ricorda che sto usando gitflow). Cosa succede se qualcuno inserisce un'unione mastersenza un tag? Non utilizzerà la versione corretta (in effetti userebbe la versione dell'ultima versione)
void.pointer

Se usi uno schema come questo, il tagging è in fase di rilascio. Ah, vedo a cosa stai arrivando, penso. Quindi, attualmente, il tuo server CI è il driver di rilascio e, con questa modifica, SCM è il driver di rilascio, ma vorresti che rimanesse così?
Jörg W Mittag,

8

Sì. È buona norma conservare la maggior parte del numero di versione in vcs. Se consideriamo la versione semantica semver.org dove abbiamo major.minor.patch.build i primi tre devono vivere in vcs. L'ultimo può essere un numero crescente dal server di build utilizzato per eseguire il backtracking del commit specifico da cui è stato creato un binario.

Per facilitare ciò in .NET, abbiamo creato un exe cmd line che si impegna a git. Con un evento pre-build, raccoglie il numero di build che teamcity ha taggato durante la build. Questo strumento di linea cmd genera automaticamente una classe con una costante contenente il numero di build. Il resto del numero di versione: major.minor.patch è solo una costante normale in un altro file. Questi due file condivisi sono inclusi in ogni assieme in una soluzione come collegamento (alt + Maiusc + trascinamento).

Questo approccio è abbastanza potente da consentire a teamcity di creare e testare il nostro codice. Spingi verso l'azzurro e chiedi a kudu di costruirlo di nuovo, ma con il numero di build di teamcity come versione delle DLL.

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.