2012-02-14 13 views
19

Devo confessare che sono nuovo nel mondo dei maven dopo anni passati a vivere nel mondo delle mostruose costruzioni chimeriche debuild/form/makefile. Non ho ancora la stessa sensazione che aiuta lo sviluppatore esperto a scegliere le giuste decisioni, e sembra che ci siano molti modi diversi in Maven.Il modo più semplice di implementare in produzione con build

Quindi, ho un semplice progetto contenente web-app. Voglio fondamentalmente seguente:

  • distribuire allo sviluppo Tomcat (sto usando Tomcat: deploy), poi non fare nulla.
  • distribuire alla produzione Tomcat, ma prima della distribuzione aggiorna git repo, aggiunge commit con tag e aggiorna la versione di build.

per distinguere tra lo sviluppo e la produzione ho creato i profili, dev e prod. Il profilo dev è attivato per impostazione predefinita. Quando voglio distribuire qualcosa in produzione, digito semplicemente mvn -P prod tomcat:deploy

Ho letto sul plugin di rilascio, oltre che sul plugin di buildnumber. Ma non sono sicuro che sto andando nel modo giusto.

Quindi, la domanda è: qual è il modo più succinto, autonomo e "mavenish" per risolvere il compito che sto chiedendo.

risposta

21

Shabunk, come ho commentato, Maven ti guida sul modo migliore per fare quello che vuoi, ereditando da anni di esperienza di sviluppo.

Spiegherei cosa farei (e ciò che io stesso realmente) fare.

Quindi stai diritto di utilizzare Maven rilascio Plugin, oltre a un altro (per esempio carico) si sta cercando di fare due differenti cose:

  • Identificazione di una versione unica, il che significa codificarla, e l'aggiornamento pom per una nuova versione
  • Distribuire la vostra applicazione (non importa quale environnement è)

Maven Release Plugin

Si consideri che il proprio processo è forse più leggero di quello che altri team di sviluppo sono abituati. Intendo dire che ci sono più passaggi tra la verifica delle unità e l'implementazione della produzione in team più grandi (Q & A, accettazione degli utenti, campagne di non regressione). Sembra che tu abbia creato un collegamento che collega tag e distribuzione di produzione. Se si desidera distribuire la propria webapp su diversi ambienti (integrazione, user acceptannce, performance, preprod e così via) è necessario identificare la propria versione e dover essere in grado di ricostruirla (sicuramente e "ripetibile").

Che cosa è inteso per maven-release-plugin. Ti aiuta a verificare che il tuo codice sorgente sia pulito (tutti i file sotto controllo sorgente, senza modifiche), può compilare e passare tutte le fasi di test. Quindi, si occupa della versione pom e del tagging e termina memorizzandolo per un uso futuro nel tuo repository aziendale Maven.

Sono disponibili numerose configurazioni da configurare (ditributionManagement, SCM, configurazione di rilascio del plug-in maven).Ma una volta che è a posto, rilasciando stare versione in una semplice riga di comando:

mvn release:prepare release:perform 

Se volete qualche esempio, posso darvi qualche.

<scm> 
    <!-- Base URL repository --> 
    <url>scm:svn:http://svn.myorg.corp/svn/repository/</url> 
    <!-- Developper URL (from trunk or branche) --> 
     <developerConnection>scm:svn:http://svn.myorg.corp/svn/repository/trunk/project1</developerConnection> 
    <connection>scm:svn:http://svn.myorg.corp/svn/repository/trunk/project1</connection> 


</scm> 
<build> 
    <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-scm-plugin</artifactId> 
       <version>1.6</version> 
       <configuration> 
      <username>${from.settings.xml.user}</username> 
      <password>${from.settings.xml.password}</password> 
       </configuration> 
    </plugin> 

    <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-release-plugin</artifactId> 
       <version>2.2.2</version> 
       <configuration> 
       <tagBase>http://svn.myorg.corp/svn/repository/tags/</tagBase> 
      <scmCommentPrefix>[DEV#SCM]</scmCommentPrefix> 
     </configuration> 
    </plugin> 
</plugins> 
    [...] 
</build> 
<distributionManagement> 
    <repository> 
     <id>enterprise_repo</id> 
     <name>Enteprise Repository on Artifactory - Stable versions</name>  <url>http://repo.corp:8080/artifactory/prj-xxx-releases</url> 
    </repository> 
    <snapshotRepository> 
     <id>enterprise_repo</id> 
     <name>Enteprise Repository on Artifactory - DEV versions</name> 
     <url>http://repo.corp:8080/artifactory/prj-xxx-snapshots</url> 
    </snapshotRepository> 
    <site> 
     <id>corporate_site</id> 
     <name>Corporate public site</name> 
     <!-- must add wagon plugin that support this protocol --> 
     <url>ftp://...</url> 

    </site> 
</distributionManagement> 

deployement

Ancora una volta, è possibile avere più Environnements su cui si desidera testare la vostra applicazione contro. Ci sono molti plugin che ti permettono di inviare e distribuire la tua guerra: il generale carico-plugin, o più specifici plugin per tomcat, glassfish-plugin, ... I plugin ti danno l'abilità di fare ciò che vuoi. Quindi, la configurazione può essere eseguita in molti modi.

Full Maven way: Il modo completamente integrato con Maven è utilizzare Profile e forse Filters. I profili consentono di descrivere le proprietà e il comportamento, come sembri sapere. I filtri sono tipi di .properties che raggruppano una serie di variabili che verranno utilizzate per sostituire i modelli nel file di configurazione xml in war (ad esempio, la connessione db). Non è quello che uso perché lo trovo meno flessibile di esternalizzare i file. Ma non importa

Maven con il suo ecosistema: Il modo che preferisco è quello di costruire le mie applicazioni con Maven e Jenkins (o un oggetto continuo di integrazione). Questo è il motivo per cui sono d'accordo con Aaron quando dice che dovevi limitare i tuoi strumenti. Usando Jenkins, eseguo ogni ora/giorno la mia applicazione contro Test unitari, generaz. Q & A rapporti, documentazione, ... Ho una versione di rilascio che mi aiuta a produrre tutto ciò che voglio consegnarlo (al mio team di test o al mio cliente) e fornisco alcune informazioni ai miei lavori per distribuirli in diversi ambienti (utilizzando i profili maven o la configurazione integrata di jenkins).

Funziona davvero bene per me, e sono abbastanza sicuro che questo sia il modo giusto di fare.

[EDIT]


Deployment

Ancora una volta, la distribuzione significa diverse fasi del ciclo di vita.

locale/Dev environnement

avrei mai utilizzare Tomcat: distribuire fino ad ora, ma solo perché preferisco utilizzare molo come web container luce (e ben integrato con Maven). Ma sono abbastanza sicuro che ogni kinf di configurazione si adatta alle tue esigenze qui.

Continuous Integration Environnement In un environnement integrazione continua, di solito copiare la guerra direttamente con Jenkins (esportazione * .war sulla macchina desiderata). Il mio modo di fare dipende da molti fattori:

  • se CI morbida è sullo stesso (fisico | virtuale) del server che il vostro application server (Tomcat, JBoss, Weblogic, Glassfish, ...uno o più lontano => il tempo di copia supererà il tempo di aggiornamento del server e produrrà un dispiegamento non sicuro (archivi generalmente danneggiati)
  • se il server supporta il ricaricamento a caldo (guerra esplosa in web-app per Tomcat) o almeno è a conoscenza del file system modifiche (full guerra in/deploy per JBoss)
  • se è necessario interrompere il server prima, ...

la maggior parte del tempo, si tratta di una semplice copia. Se non riesco, uso alcuni plugin Maven integrati (come jahia: plug-in di distribuzione per il famoso CMS: www.jahia.com), o solo un plugin cargo: http://cargo.codehaus.org/Maven2+plugin. Non ho alcun esempio, ma è davvero facile trovarne su internet perché questa configurazione è spesso raccomandata.

Q & A/Accettazione/Produzione environnement

Per questo tipo di Environnements, che spesso (per quanto io ho visto nel mio lavoro) si occupa di Service Level Agreement, noi (I o gruppo admin) ha scritto alcuni script specifici. Sono sicuro che rimarrai deluso, ma come ho detto, non mi affido a Maven per tutto, e per il dispiegamento in particolare. IMHO, questo è un limite di questo strumento. Si può forse fare affidamento sul plugin cargo o su quelli specifici, ma rilasciando una versione o costruendone uno non corrisponde (in sequenza temporale) con il deploy effettivo. Ancor di più, non ho trovato nessun plugin che mi consenta di implementare facilmente su più istanze ... e vale anche la pena di dover arrestare le istanze in un ordine specifico (le esigenze dello SLA). Detto questo, non ho menzionato le proprietà esterne, o gli script SQL, o qualsiasi altra cosa. Sono ulteriori motivi per fare affidamento su uno strumento dedicato.

Quindi, in genere, abbiamo scritto i nostri script ant/sell. Se qualcun altro ha soluzioni migliori, ovviamente sono interrazzato!

Spero di essere stato abbastanza chiaro.

Saluti.

1

La soluzione Mavenized non consiste nell'utilizzare Maven quando si ha un'eccezione al caso comune. Maven è tutto su casi comuni. Le eccezioni sono gestite altrove, il che significa che il POM (dovrebbe) non contenere mai sorprese.

Poiché è necessario un processo di distribuzione personalizzato, scrivere uno script di shell o un Ant build.xml che esegue i passaggi necessari e utilizza Maven nel processo per eseguire la distribuzione.

In questo modo, ogni strumento fa ciò che può fare meglio.

[EDIT] Nota per tutti i downvoters là fuori: a meno che tu non abbia una discussione, il tuo voto negativo non significa nulla. Maven è uno strumento. Come tutti gli strumenti, ha dei limiti. La filosofia di base di Maven è di evitare le eccezioni. Ant è tutto su casi angolari, Maven riguarda il flusso principale. Dalla "What is Maven?" pagina:

  • Rendere il processo di compilazione facile
  • Fornire un uniforme sistema di accumulo

(corsivo mio) Quindi sì, ci sono cose per le quali Maven non è la soluzione migliore per. Se la procedura di rilascio standard funziona, utilizzare release plugin.

Ma quando non lo fa, cerca altrove invece di innamorarsi della trappola mentale "everything looks like a nail".

Una delle principali fasi di sviluppo personale è comprendere i propri limiti e i limiti degli strumenti con cui si lavora. Quando uno strumento non è adatto per un lavoro, prova uno strumento diverso invece di cercare di deformare la realtà. La tua vita sarà più felice.

+0

In che modo un profilo supporta l'etichettatura in un repository git e l'incremento della versione di build? Maven è uno strumento come un martello: non è adatto per ogni compito. –

+0

Ti stai sbagliando con le tue premesse di base. –

+0

Sono totalmente d'accordo con te Aaron. Maven è uno degli strumenti migliori che conosco per guidare il ciclo di vita dello sviluppo sulle migliori pratiche. Se non riesci a usarlo, è probabilmente perché non sei sulla strada giusta (per quanto riguarda le migliori pratiche). Quindi devi delegare a un altro strumento, generalmente Ant, Jenkis o qualcos'altro. È difficile, spesso impossibile sul progetto precedente, ma rappresenta il modo giusto per farlo ... +1! –

4

La domanda originale chiedeva "la migliore pratica" per eseguire gli schieramenti di produzione con Maven. Mi aspettavo di ottenere più di una "buona pratica" e ho offerto la grazia di vedere diverse soluzioni e di imparare da loro. Non mi interessa se sono soluzioni puramente meccaniche o se utilizzano strumenti diversi.

Parallelamente a questa discussione ho fatto anche delle ricerche e vorrei postare qui i diversi approcci che sto vedendo. Ho provato 1) e 3), sono puri esperti e indipendentemente da ciò che sta dicendo Aaron, stanno anche lavorando.

Nel mio progetto corrente ho un ambiente di sviluppo, un ambiente di test, un ambiente di staging e un ambiente di produzione. Dal mio maven pom mi piacerebbe lavorare con l'ambiente di sviluppo e distribuirmi solo all'ambiente di test. Vedo i seguenti approcci con Maven pom:

  1. profili con proprietà filtranti
    Quando si lavora con questo approccio il risultato finale (il file di guerra) deve essere ricostruita per ambienti diversi. Questo mi ha costretto ad offrire la taglia perché non mi piaceva.
  2. profili con Maven WAR overlays o assembly plugin
    Questo ha anche generato diversi artefatti per diverse piattaforme. Ma invece di ricostruire il file war, verrà spacchettato/rattoppato/reimballato (per l'overlay di guerra) o compilato e caricato con impostazioni diverse (plug-in di assembly). Non mi è piaciuta neanche questa soluzione.
  3. Un plug-in di distribuzione (ad esempio Cargo plugin) senza profili
    Specificare la build completa con l'installazione e includere anche il plugin cargo che esegue una distribuzione remota ma non lo connette a nessuna fase. Quindi lavoro sempre con l'ambiente di sviluppo ma quando richiama esplicitamente il plugin cargo distribuisce la guerra dal repository a un contenitore (l'ambiente di test). Posso persino usare i profili per distinguere tra diversi contenitori solo per lo spiegamento tramite cargo.

In tutte le soluzioni sto usando test di integrazione (plugin surefire), plug-in di versione e plug-in di rilascio per la creazione della guerra. Per l'implementazione sto adottando l'approccio numero 3 seguendo gli argomenti da https://stackoverflow.com/a/1151870/734687 (un post che esprime molto bene ciò che preferisco anch'io).

Poiché l'applicazione deve funzionare invariata in tutto l'ambiente, è necessario distinguere le diverse impostazioni in fase di esecuzione e ciò può essere molto complicato. Il nostro team operativo desidera avere impostazioni per applicazione esterne al contenitore, quindi supporto un ambiente var che mi indirizza alla directory corretta ma è facoltativo. Se non è impostato nulla, utilizzo le impostazioni di sviluppo all'interno della guerra. Vedere un campione sorgente qui:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="ignoreResourceNotFound" value="true"/> 
    <property name="locations"> 
     <list> 
      <value>classpath:META-INF/spring/*.properties</value> 
      <value>file:///${picservice.configdir:-}/*.properties</value> 
     </list> 
    </property> 
</bean> 

Le proprietà del META-INF/primavera dir vengono caricati sempre. Aggiungendo inoltre le proprietà del file system che possono sovrascrivere le proprietà sopra. Se non viene trovata alcuna proprietà, ciò non innescherà l'esecuzione perché ho impostato ignoreResourceNotFound. Se la proprietà picservice.configdir è impostata, mi indirizza a una directory, se non di quanto ho fornito un valore predefinito con :. Il - dice che voglio avere nessun valore che è la directory corrente.

Per la registrazione ho una soluzione simile.Si possono trovare articoli molto interessanti sulle proprietà di file di movimentazione con la Primavera in seguenti link:

ho trovato una presentazione interessante di questo argomento, vedere Automated Deployment with Maven and friends.

+0

-1 Come si aggiorna il repository git utilizzando un profilo? In che modo un profilo incrementa un numero di build? Come fai tutte queste cose quando i plugin standard di Maven non funzionano come fai tu? –

+0

1) La tua risposta non mostra ancora come questo può essere fatto con Maven. Ho gli stessi problemi con la mia build e i plugin standard non fanno quello che mi serve. 2) Uso Maven per tutte le mie build. È il mio strumento standard. Ho scritto plugin per questo e patch di plugin esistenti. E soprattutto, so quali sono i limiti. –

+0

Ottima idea la tua taglia! –

2

aggiorna git repo, aggiunge il commit con tag e aggiorna la versione di build.

-

Ho letto di plug-release, così come su Plugin BuildNumber. Ma non sono sicuro che sto andando nel modo giusto.

Sì, utilizzare il plugin di rilascio è il metodo consigliato. Puoi usare il plugin buildnumber se vuoi il numero buildnumber in qualche documento, ad es. CHANGES.txt

0

forse Phing la sua un altro strumento per risolvere il problema, la sua semplice, e la u può rendere i processi personalizzati

Phing website

+2

la domanda riguardava Java e non PHP – Denees

2

Penso che il modo più semplice per realizzare quello che hai specificato (se ho capito bene) è configurare Maven Release Plugin come segue:

<!-- path: project/build/pluginManagement/plugins --> 
<plugin> 
    <artifactId>maven-release-plugin</artifactId> 
    <configuration> 
    <releaseProfiles>prod</releaseProfiles> 
    <goals>tomcat:deploy</goals> 
    </configuration> 
</plugin> 

per le distribuzioni dev procedere come si sta facendo: mvn tomcat:deploy -P dev (se dev è attiva per default rimuovere ilArgomento).

Rilasciando procedere in due fasi come Maven Release Plugin aspetta:

mvn release:prepare 

Questo obiettivo aumenterà la versione e tag come si desidera (and more). Si noti che è inoltre necessario specificare cosa SCM Maven dovrebbe usare configurando questo tag nel POM:

<!-- path: project --> 
<scm> 
    <connection>scm:git:ssh://yourrepo.url</connection> 
</scm> 

SCM plugin supporta un wide variety of SCM managers and protocols (si potrebbe essere interessati a git:http o git:https).

E poi

mvn release:perform 

Questa utilizzerà il profilo prod e semplicemente eseguire l'obiettivo tomcat:deploy, esattamente ciò che si è configurato.

Spero che questo sia ciò di cui avevi bisogno. Saluti.

Problemi correlati