16

Abbiamo un prodotto che comprende molti progetti Maven che dipendono l'uno dall'altro. Tutti questi progetti Maven si fondono in un unico progetto che consegna il prodotto finale.Jenkins crea un prodotto composto da molti progetti Maven? (con il plug-in Jenkins Pipeline?)

I progetti Maven condividono lo stesso ciclo di vita. In altre parole, non sono gestiti da team separati di persone con esplicite modifiche <dependency> per raccogliere versioni più recenti di altri progetti. Piuttosto, quando qualcuno cambia qualcosa in uno dei progetti, il risultato dovrebbe andare direttamente nel prodotto finale senza ulteriori modifiche.

Utilizziamo Jenkins come strumento di integrazione continua.

Le principali richieste che abbiamo sono i seguenti:

  • Non c'è bisogno di copiare tutte le dipendenze inter-progetto alla configurazione Jenkins: questi dovrebbero essere in un unico luogo, idealmente i file pom.xml.
  • Evita build non necessari: in una modifica SCM, crea solo i progetti potenzialmente interessati.
  • In caso di dipendenze diamante (C dipende sia da B1 che da B2, che dipendono entrambi da A), se viene modificato il valore più basso (A), il prodotto finale (C) deve sempre utilizzare la versione di A è stato anche usato per costruire/testare B1 e B2.

Domanda: Qual è l'approccio migliore per fare questo con Jenkins?

Attualmente stiamo pensando di utilizzare un singolo lavoro utilizzando il plug-in Pipeline di Jenkins, che analizza le dipendenze Maven e le modifiche SCM, decide che cosa deve essere costruito e in quale ordine e quindi effettivamente costruisce i progetti.

+0

Ho appena trovato http://stackoverflow.com/q/33753857/223837 ('Jenkins flusso di lavoro “costruire ogni volta una dipendenza ISTANTANEA è costruito ""), che è almeno relativo. –

+0

Il plug-in Multijob non risolverà lo scopo? – Gandhi

risposta

18

Al fine di soddisfare le vostre esigenze, potete contare su molte delle funzionalità predefinite di una build multi-modulo Maven e una configurazione aggiuntiva spiegata di seguito.

Da tua domanda:

Non c'è bisogno di copiare tutte le dipendenze inter-progetto alla configurazione Jenkins: questi dovrebbero essere in un unico posto, idealmente i file pom.xml.

Utilizzando un aggregator/multi-module pom è possibile avere un unico punto di accesso (un file pom.xml) per una build di Maven che avrebbe poi costruire tutti i moduli definiti:

Un progetto con moduli è noto come un progetto multimodulo o aggregatore. I moduli sono progetti che questo elenco di POM elenca e vengono eseguiti come gruppo. Un progetto pacchettizzato può aggregare la creazione di un insieme di progetti elencandoli come moduli, che sono directory relative a quei progetti.

Cioè, un file pom.xml come la seguente:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.sample</groupId> 
    <artifactId>project</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>pom</packaging> 

    <modules> 
     <module>module-1</module> 
     <module>module-2</module> 
     <module>module-n</module> 
    </modules> 
</project> 

un breve esempio: definire un elenco di moduli (altri progetti Maven) che sarà costruito a partire da questo progetto Maven (a vuoto progetto che ha solo lo scopo di costruire altri progetti di maven).Si noti che il pom packaging richiesto per avere moduli, sta dicendo a Maven che questo progetto fornisce solo un pom (senza ulteriori artefatti).

Si potrebbe quindi avere un progetto di aggregatore Maven radice che definisca gli altri progetti di maven come i suoi moduli e che abbia un singolo lavoro Jenkins che costruisce questo punto di ingresso.


Inoltre, dalla tua domanda:

evitare inutili costruisce: su un cambiamento SCM, costruire solo i progetti che sono potenzialmente interessati.

per soddisfare questo requisito, è possibile utilizzare il incremental-build-plugin:

Perché sembra per la modifica dei moduli di un progetto unico nel suo genere, l'incrementale plugin Maven prende sens solo su multi-progetti moduli. Se viene rilevata una modifica su un modulo, la directory di output viene rimossa.

Questo plugin verificherà se qualcuno dei file pom, le risorse, le fonti, le fonti di prova, le risorse di prova cambierebbe in un modulo e se il caso rimuovere la sua directory di output. Come tale, risparmiando tempo di costruzione per un modulo interessato e in catena per l'intero progetto multi-modulo (la nostra build, in questo caso).

Per abilitare questo meccanismo, è possibile configurare nel pom aggregatore sopra, il seguente:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.sample</groupId> 
    <artifactId>project</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>pom</packaging> 
    <modules> 
     <module>module-1</module> 
     <module>module-2</module> 
     <module>module-n</module> 
    </modules> 

    <properties> 
     <skip.incremental>true</skip.incremental> 
    </properties> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>net.java.maven-incremental-build</groupId> 
       <artifactId>incremental-build-plugin</artifactId> 
       <version>1.6</version> 
       <executions> 
        <execution> 
         <goals> 
          <goal>incremental-build</goal> 
         </goals> 
         <configuration> 
          <noIncrementalBuild>${skip.incremental}</noIncrementalBuild> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

Sopra, abbiamo semplicemente aggiunto il incremental-build-plugin alla costruzione aggregatore e una proprietà, skip.incremental, che salterà la plug esecuzione per la prima compilazione, l'aggregatore vuoto uno, consentendo in moduli come segue:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <parent> 
     <groupId>com.sample</groupId> 
     <artifactId>project</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
    </parent> 
    <artifactId>simple-module</artifactId> 

    <properties> 
     <skip.incremental>false</skip.incremental> 
    </properties> 
</project> 

Nota: nel pom dall'alto di un modulo di esempio indichiamo al file di aggregazione pom pa come affitto, quindi utilizzando maven inheritance in combinazione con l'aggregazione (un utilizzo classico) e come tale con una build multi-modulo più una governance di build comune fornita dal genitore comune per tutti i moduli dichiarati (in questo caso, la governance di build comune fornisce l'ulteriore Configurazione incremental-build-plugin). Inoltre, ogni modulo riconfigura la proprietà skip.incremental per non saltare il plug-in sopramenzionato. Questo è un trucco: ora il plugin verrà eseguito solo in moduli, non nella sua radice (il che non avrebbe senso e in questo caso genererebbe un errore altrimenti).

Ovviamente, nel lavoro Jenkins legate, nel proprio Codice di gestione sezione sorgente non è necessario configurare un nuovo e fresco check-out come parte di ogni generazione, altrimenti nessun cambiamento sarebbe rilevabile (e ogni volta che sarebbe inizia da zero, che è una buona pratica per le build di rilascio in realtà).

Inoltre, il comando di Maven non dovrebbe richiamare il ciclo di vita clean, che rimuoverà anche il target ad ogni build e pertanto non rende rilevabile alcun cambiamento.


Inoltre, dalla tua domanda:

Nel caso di 'dipendenze Diamond' (C dipende sia B1 e B2, che entrambi dipendono A), se il più basso (A) viene modificata , quindi il prodotto finale (C) dovrebbe sempre utilizzare la versione di A utilizzata anche per creare/testare B1 e B2.

Maven avrà cura di questa esigenza nell'ambito di una costruzione multi-modulo e la sua reactor meccanismo:

Il meccanismo di Maven che gestisce progetti multi-modulo è indicato come il reattore. Questa parte del nucleo Maven fa il seguente:

  • raccoglie tutti i moduli disponibili per costruire
  • ordinamenti progetti in ordine di generazione corretto
  • Costruisce progetti selezionati in ordine

Per impostazione predefinita, il reattore creerà anche un ordine di build e creerà sempre un modulo prima del modulo relativo al modulo dipendente/consumatore. Ciò significa anche che l'ultimo modulo creato sarà effettivamente il modulo responsabile della creazione del manufatto finale, il prodotto consegnabile a seconda di parte o di tutti gli altri moduli (ad esempio, un modulo responsabile della consegna di un file war sarà probabilmente l'ultimo per costruire in un progetto webapp multi-modulo).


Ulteriore lettura correlata riguardante Maven e saltare azioni quando qualcosa è invariato:

  • Il maven-jar-plugin fornisce la forceCreation che di default è già abilitato

    Richiede il plugin vaso di costruire un nuovo JAR anche se nessuno dei contenuti sembra essere cambiato. Per impostazione predefinita, questo plugin cerca di vedere se il jar di output esiste e gli input non sono cambiati. Se queste condizioni sono vere, il plugin salta la creazione del jar.

  • Il maven-compiler-plugin fornisce la useIncrementalCompilation, anche se not properly working al momento.
  • Il maven-war-plugin offre la possibilità recompressZippedFiles che potrebbe anche essere utilizzato per accelerare costruisce ed evitare di ri-fare qualcosa (per passare a false in questo caso):

    Indica se archivi zip (jar, zip ecc) di essere aggiunto alla guerra dovrebbe essere nuovamente compresso. La compressione di nuovo può comportare dimensioni di archivio ridotte, ma offre tempi di esecuzione notevolmente più lunghi.
    predefinito: true


Aggiornamento progetti

The Maven condividono lo stesso ciclo di vita.

Questo requisito dovrebbe anche far rispettare l'uso di un progetto aggregatore/multi-modulo, tuttavia può anche applicarsi a diversi progetti collegati effettivamente attraverso le dipendenze.

non sono gestiti da gruppi separati di persone con modifiche esplicite per raccogliere le versioni più recenti di altri progetti.

Questo punto impone anche l'utilizzo di un progetto multi-modulo. In un progetto multi-modulo, potresti avere versioni diverse tra i moduli, tuttavia la pratica e le linee guida comuni sono di condividere la stessa versione, definita dal progetto principale (l'aggregatore) e in cascata tra i suoi moduli. In quanto tale, la sua centralizzazione e governance eviteranno disallineamenti ed errori.

quando qualcuno cambia qualcosa in uno dei progetti, quindi il risultato dovrebbe andare direttamente nel prodotto finale senza ulteriori modifiche.

Ancora, questo sarebbe gestito automaticamente da un progetto multi-modulo. Lo stesso potrebbe accadere con diversi progetti ciascuno utilizzando SNAPSHOT versions, quindi non è necessario modificare la versione delle dipendenze nel suo progetto consumer (quello responsabile della creazione del prodotto finale). Tuttavia, mentre le versioni di SNAPSHOT sono davvero utili (e raccomandate) durante lo sviluppo, non dovrebbero essere assolutamente utilizzate durante la consegna del prodotto finale in quanto la riproducibilità della build sarebbe in pericolo (ovvero, potresti non essere in grado di ricostruire la stessa versione in seguito in quanto si basava su versioni SNAPSHOT, quindi non versioni congelate). Quindi, SNAPSHOT non è una soluzione di proiettile d'argento e dovrebbe essere usato solo durante determinate fasi del SDLC del prodotto, non come soluzione finalizzata e congelata.


Update 2
Vale la pena di guardare anche al nuovo Maven Incremental Module Builder per Maven 3.3.1+ e Java .

Maggiori dettagli su:

Problemi correlati