Librerie comuni nella catena di build

2

Come molte (la maggior parte?) persone, abbiamo più librerie "comuni" che gestiscono varie cose (oggetti di business, utilità, librerie esterne ...) per più progetti (servizio web, sito di amministratori / utenti, app desktop ... ).

Come è stato impostato oggi, ogni progetto copia i suoi file binari in una cartella "assiemi" di un livello superiore al progetto, e fanno tutti riferimento ai binari in questa cartella, piuttosto che al progetto stesso.
Anche le cartelle SVN sono un disastro, con librerie comuni in soluzioni di progetti specifici e servizi a volte raggruppati, a volte all'interno della propria cartella.

Oggi esiste un insieme incredibilmente complicato di lavori Jenkins che copiano e utilizzano vari output di progetti ovunque, con dipendenze molto difficili da tracciare e spesso infranti: ad esempio, quando eseguo il commit con l'interfaccia utente di amministrazione, si costruisce rapidamente, ma fallisce perché il servizio web non ha terminato la costruzione.

Vedo molti problemi con questa organizzazione; tra gli altri:

  • Devo rispettare un albero di cartelle specifico per poter costruire un progetto, non posso solo controllare un singolo progetto e lavorarci sopra.
  • Per costruire il progetto A, devo costruire il progetto B, e prima del progetto C, e così via e così via. Posso spendere un sacco di tempo per scoprire quale progetto mi manca per costruire il primo.
  • La configurazione intera build è memorizzato in Jenkins, e gli sviluppatori non hanno un accesso diretto ad esso. Quindi non posso semplicemente controllare un progetto che non ho mai toccato prima e costruire l'intero albero delle dipendenze eseguendo uno script

Sono abituato a scrivere script di grandi dimensioni che fanno tutto, quindi mi sta facendo impazzire, ma altri sviluppatori ci sono abituati e si limitano a scrollare le spalle.

In che modo tu puoi configurare il tuo sistema di generazione per gestire le tue librerie comuni ed esterne?

( Aggiornamento : stiamo usando .Net, perché a quanto pare ci sono diverse soluzioni per lingue diverse)

Informazioni sui gestori delle dipendenze: nuget, npm, ecc.

Abbiamo pensato di utilizzare un server Nuget interno per archiviare DLL con versioni e usarlo per fare riferimento ad altri progetti.
Il problema con questo approccio è l'impatto sul flusso di lavoro giornaliero.

Diciamo che immagazzino i miei binari in un repository nuget. E per creare una nuova funzione, devo modificare i progetti A, B e C. Il mio flusso di lavoro diventa molto attesa:

  • Modifico e impegno il progetto A.
  • Aspetto che la compilazione A termini e che il feed nuget aggiorni
  • Aggiorna il mio pacchetto nuget su B, modifica, commit.
  • Aspetto che finisca la compilazione di B e che il feed di nuget aggiorni
  • Aggiorna il mio pacchetto nuget su C, modifica, commit.
  • Per la mia prossima funzione, devo tornare al passaggio 1.
  • Oppure codifico più funzioni contemporaneamente e non è molto agile (e molto rischioso).

Questa organizzazione interrompe completamente il flusso di codice e, in quanto tale, è inaccettabile.

Forse non sto pensando all'organizzazione corretta che utilizza un manager delle dipendenze? Forse c'è un modo migliore?

    
posta thomasb 08.08.2017 - 16:03
fonte

3 risposte

1

Di solito, l'API dei pacchetti di nuget non dovrebbe cambiare così spesso. Per esempio. se l'API del pacchetto A non è stata modificata, non è necessario ricreare il pacchetto B e C perché può essere utilizzato con la nuova versione del pacchetto A.

Tuttavia, se l'API di un pacchetto è ancora in fase di sviluppo, un'alternativa è includere il codice sorgente del progetto come progetto esterno (esteri per i sottomoduli SVN o per GIT) direttamente in più progetti. Questa soluzione ha anche qualche svantaggio (ad es. Potresti rompere accidentalmente altri progetti cambiando i progetti esterni) ma semplifica in modo definitivo il processo di compilazione;).

    
risposta data 09.08.2017 - 11:31
fonte
1

Sono in un negozio .NET che ha tonnellate di librerie di classi che ci piace riutilizzare in più progetti ed ecco come lo facciamo.

  • I progetti non vivono sotto Soluzioni nella struttura delle cartelle di il nostro controllo del codice sorgente (TFS). Abbiamo una cartella "Sln" per le soluzioni, a Cartella 'Lib' per le librerie di classi, 'Web' per le applicazioni web, ecc.

  • Se una soluzione in cui mi trovo deve usare una classe lib esistente, tiro giù quella libreria dal sorgente quindi usa il "Aggiungi progetto esistente" sul mio soluzione per selezionare la libreria.

  • Utilizziamo TFS per le build.

  • Ogni volta che cambio un metodo in una libreria condivisa, è mio responsabilità di cercare attraverso il nostro codebase per cercare altre app che usano quella libreria e tutti i metodi che sto cambiando e a coordinare con gli altri membri del team se queste altre app devono essere ritestato / distribuito. (Fortunatamente non super comune)

Questo flusso ci consente di riutilizzare le librerie di classi, con le librerie completamente rimovibili durante l'esecuzione di un'app in Visual Studio, e questo processo ha sostituito un processo più vecchio in cui abbiamo compilato le DLL comuni in una posizione comune e mirato alla nostra abitudine Proj's per afferrarli da lì. Il problema con questo approccio era che era molto difficile dire quale versione di una DLL era stata rilasciata nella posizione condivisa, ed erano una sorta di scatole cieche di funzionalità. Penso che abbia anche creato un caso in cui anche le versioni DLL di Test-vs-Prod potrebbero essere confuse.

Il modo in cui lavoriamo ora non è sempre l'ideale (far soffrire Nuget), ma personalmente preferisco semplicemente prendere le DLL da un'unità condivisa.

    
risposta data 09.08.2017 - 14:41
fonte
0

Il codice esterno utilizzato per creare l'applicazione viene aggiunto utilizzando un manager delle dipendenze. Maven per Java, Composer per PHP e node / npm per JavaScript. Lo stesso meccanismo è usato per il codice che abbiamo scritto internamente e il codice da repository esterni. Per il nostro codice utilizziamo un repository interno che può essere semplice come un insieme di cartelle su un server centrale.

Se la compilazione include più di solo il recupero del codice esterno, viene aggiunto uno script di compilazione. La maggior parte delle volte questi script possono essere configurati nello strumento di compilazione (Maven, Composer, node) o almeno richiamati da essi.

I nomi di questi script sono gli stessi per tutti i progetti, chiamati build o test per eseguire i test. Usando lo stesso nome è più facile iniziare con un progetto su cui non hai mai lavorato prima.

    
risposta data 08.08.2017 - 21:18
fonte

Leggi altre domande sui tag