Dopo aver infranto il nostro codice in bit riusabili, come testiamo e implementiamo?

9

Abbiamo iniziato con uno sviluppatore e un repository SVN contenente tutto il nostro codice:

^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1

(al momento questo è stato un grande miglioramento). Dopo aver avuto la possibilità di crescere per un po 'abbiamo iniziato ad avere problemi con le dipendenze circolari, i testuites lenti e le difficoltà generali nel riutilizzare il codice (poiché, ad esempio, il set di funzionalità di website1 si era insinuato in un modulo generico-a).

Volendo modulare la base di codice, e aspettandoci di passare a git a breve (e avendo letto da qualche parte che git non ama i mega-repos di svn), siamo passati a una struttura molto più granulare:

^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)

Questo era concettualmente fantastico. Codice più modulare, suite di test molto più veloci, più facile da documentare, ecc. Abbiamo aperto alcuni dei nostri componenti più generici e abbiamo reso installabili tutti i moduli pip (utilizzando pip install -e . per installarli in development virtualenv).

Abbiamo creato un repository ^/srv/trunk contenente la struttura delle cartelle dell'ambiente runtime, ad es. ^/srv/trunk/lib per i moduli, /srv/trunk/src per i resti di ^/foo/trunk , ^/srv/trunk/www per siti Web ecc.

E infine (prendendo spunto da Forza, che ho lavorato molto tempo fa [ link ) abbiamo creato un file di testo" vcs-fetch "che elenca tutti i repository rilevanti e dove devono essere estratti nell'ambiente dev e un comando corrispondente per farlo. Per esempio. una linea vcs-fetc:

svn srv/lib/module-a ^/module-a/trunk

causerebbe l'uno o l'altro (prima volta)

cd /srv/lib && svn co ^/module-a/trunk module-a

o (in seguito)

cd /srv/lib/module-a && svn up

e allo stesso modo per i repository di github (sia i pacchetti dei nostri fornitori sia quelli modificati / non modificati).

Abbiamo utilizzato lo stesso processo vcs-fetch per creare l'ambiente di produzione, ma stiamo rapidamente scoprendo che non abbiamo modo di sapere quale versione è stata utilizzata per produrre dopo aver fatto un vcs-fetch.

Con il mega-repo, potevamo semplicemente notare il numero di revisione prima di aggiornare il prodotto dal trunk, e tornare indietro era un semplice svn -r nnn up . di distanza. Con il codice in entrambi i repository svn e git (e un modulo in hg) - e ~ 120, non è ovvio come farlo ...

Ho letto link oggi, e il primo fattore è "One codebase", quindi mi sto anche chiedendo se sono fuori moda percorso qui?

Un'idea che ho avuto è stata quella di creare uno script di distribuzione che creerebbe "distribuzioni" di installazione di pip e le "impacchetta" insieme in un file requirements.txt . Una distribuzione implicherebbe quindi la creazione di una nuova virtualenv, la pip che installa il file requirements.txt che elenca le ruote di implementazione e che commuta la virtualenv attiva. Ritornare ai precedenti significherebbe solo riaccendere il virtualenv (ma a meno che non volessimo mantenere i virtualenvs per sempre non ci permetterebbe di tornare indietro in qualsiasi momento - nella mia esperienza che non è mai stato necessario comunque).

A questo punto mi chiedo se sto camminando nella direzione sbagliata, o se non ho camminato abbastanza lontano sulla retta via ...? (tutto ciò che sto leggendo continua a parlare di "la tua app", e non so come ciò si traduca nell'esecuzione di 14 siti web con lo stesso codice base ...)

    
posta thebjorn 13.04.2016 - 22:59
fonte

2 risposte

2

Sembra che manchi i rami (o piuttosto i rami "tag" o "rilascio").

Invece di usare il tuo SVN revnum come riferimento per determinare quale versione stai installando, dovresti creare un ramo in quella revisione rilasciata. Quindi si distribuisce il nome del ramo.

Rende più semplice la diramazione anche se non ci sono cambiamenti, quindi ogni modulo mantiene lo stesso numero di versione, tuttavia i pacchetti OSS potrebbero non piacere essere ramificati senza modifiche, quindi la cosa migliore da fare è mantenere uno script di dipendenze - quindi la versione 5 del tuo prodotto richiede il modulo OSS X v2 e così via.

Dovresti cambiare lo script per smettere di fare riferimento alle versioni e lavorare invece con i nomi dei rami (anche se possono essere qualsiasi cosa, è meglio decidere su una convenzione di denominazione fissa, ad esempio Release_1_2_3)

Un altro suggerimento è di mantenere un file con ogni modulo che descrive la versione corrente, è possibile generarli automaticamente se necessario, e magari includere anche un log delle modifiche completo, ma significa che chiunque può vedere quale versione viene distribuita semplicemente guardando.

    
risposta data 23.06.2016 - 11:57
fonte
1

Penso che tu abbia già molte buone idee, ho usato la maggior parte di esse in vari progetti nel corso degli anni, e la tua preoccupazione principale sembra essere l'incapacità di dire quale versione di tutti i moduli sia inclusa in un determinato pacchetto se li dividi.

Sono disposto a dividerli, con un certo livello di granularità, specialmente se hai più team e cicli di rilascio variabili, come cita @ Ext3h.

Dato che non sono sicuro di quanto siano isolati i tuoi moduli o di quanto dettagliato vuoi che sia la tua versione, ti suggerisco alcune opzioni.

Utilizza i sottomoduli git. Con i sottomoduli, è possibile memorizzare ciascun modulo in un repository git separato, simile alla configurazione di svn, e anche a ciò a cui stai pensando. Quindi colleghi questi moduli al progetto root che conterrà un riferimento al commit pertinente di ogni sottomodulo, per ciascuno dei suoi commit.

IMO questa è una configurazione teoricamente piacevole e ragionevolmente semplice. I principali svantaggi sono che il flusso di lavoro per i sottomoduli è un po 'imbarazzante, tuttavia sembra che tu abbia già risolto bene queste cose con gli script, quindi potrebbe non essere un problema reale.

L'altra avvertenza è che i riferimenti di commit del submodule saranno solo uno SHA1, non ci sono mai dettagli leggibili da umani su quale ramo sei, e potresti finire per dover controllare manualmente il ramo giusto quando vuoi lavorare direttamente in il sottomodulo.

Tuttavia, non ho usato questo modello estensivamente, quindi non so quanto potrebbe essere un problema per un progetto di grandi dimensioni come il tuo.

Un'altra alternativa è usare una sorta di gestore delle dipendenze. Ciò richiede che ogni modulo o gruppo di moduli possa essere versionato, impacchettato e pubblicato individualmente e che tu abbia un sistema in grado di riunire questi pacchetti nel modo desiderato quando lo desideri.

Stai già suggerendo pip, e quello che sembra mancare dal tuo suggerimento è archiviare i requisiti richiesti.txt insieme alla build, o nel repository del progetto root, in modo che tu possa ricreare il virtualenv più tardi piuttosto che dovendo salvarlo su disco.

Ci sono anche altri sistemi; Ho creato un progetto piuttosto ampio utilizzando una versione leggermente personalizzata di Apache Ivy come strumento per confezionare e pubblicare ogni modulo, oltre a riunirli per il progetto finale. Ivy memorizza anche un manifest elencando tutte le versioni di tutti i moduli a cui si fa riferimento, se è necessario ricreare la configurazione in un secondo momento.

    
risposta data 23.06.2016 - 11:42
fonte

Leggi altre domande sui tag