web-dev-qa-db-ger.com

Was ist der Maven-Weg für automatische Projektversionen bei kontinuierlicher Lieferung?

Ich habe eine Webanwendung, in der wir zur Produktionsbereitstellung bereitstellen, wann immer eine Funktion bereit ist. Manchmal kann dies ein paar Mal am Tag sein, manchmal kann es ein paar Wochen zwischen den Releases sein. 

Derzeit erhöhen wir unsere Versionsnummern für unser Projekt nicht, und seit über einem Jahr sitzt alles in der Version 0.0.1-SNAPSHOT .. Ich frage mich, wie Maven die kontinuierliche Bereitstellung von Web-Apps ermöglicht. Es scheint übertrieben zu sein, die Versionsnummer bei jedem Commit hochzuschrauben, und niemals die Versionsnummer zu erhöhen, wie wir es jetzt tun, scheint auch falsch zu sein.

Was ist die empfohlene Vorgehensweise für diese Art der Verwendung von Maven?

Das Problem ist eigentlich ein zweifaches:

  • Versionsnummer des Projekts in der individuellen pom.xml-Datei vorrücken (und es kann viele geben).
  • Aktualisieren der Versionsnummer in allen abhängigen Komponenten, um die neuesten voneinander zu verwenden.
44
ams

Ich empfehle die folgende Präsentation, die die praktischen Realitäten einer kontinuierlichen Zustellung mit Maven beschreibt:

Der Schlüssel zum Mitnehmen ist, dass jeder Build eine potenzielle Version ist. Verwenden Sie daher keine Snapshots.

38
Mark O'Connor

Dies ist meine Zusammenfassung basierend auf dem Video, das von Mark O'Connors Antwort verlinkt wurde.

  • Die Lösung erfordert ein DVCS wie Git und einen CI-Server wie Jenkins. 
  • Verwenden Sie keine Snapshot-Builds in der Continuous Delivery-Pipeline und nicht das Maven-Release-Plugin.
  • Snapshot-Versionen wie 1.0-SNAPSHOT werden in echte Versionen umgewandelt, wie 1.0.buildNumber, wobei buildNumber die Jenkins-Auftragsnummer ist. 

Algorithmusschritte:

  1. Jenkins klont das Git-Repo mit dem Quellcode, und der Quellcode hat die Version 1.0-SNAPSHOT.
  2. Jenkins erstellt einen Git-Zweig mit dem Namen 1.0.JENKINS-JOB-NUMBER, sodass aus der Snapshot-Version eine echte Version wird. 1.0.124
  3. Jenkins ruft das Plug-In für Maven-Versionen auf, um die Versionsnummer in den Dateien pom.xml von 1.0-SNAPSHOT in 1.0.JENKINS-JOB-NUMBER zu ändern. 
  4. Jenkins ruft mvn install auf
  5. Wenn mvn install ein Erfolg ist, legt Jenkins den Zweig 1.0.JENKINS-JOB-NUMBER fest, und eine echte Nicht-Momentaufnahme-Version wird mit einem richtigen Tag in git erstellt, um später reproduziert zu werden. Wenn mvn install fehlschlägt, löscht Jenkins einfach den neu erstellten Zweig und schlägt den Build fehl.

Ich kann das Video, das von Marks Antwort verlinkt wird, wärmstens empfehlen.

34
ams

Ab Maven 3.2.1 werden fortlaufende, benutzerfreundliche Versionen standardmäßig unterstützt: https://issues.Apache.org/jira/browse/MNG-5576 .__ Sie können 3 vordefinierte Variablen in Version verwenden:

${changelist}
${revision}
${sha1}

Was Sie im Grunde tun, ist: 

  1. Stellen Sie Ihre Version auf z. 1.0.0-${revision}. (Sie können mvn versions:set verwenden, um dies in einem Projekt mit mehreren Modulen schnell und korrekt durchzuführen.)
  2. Setzen Sie eine Eigenschaft <revision>SNAPSHOT</revision> für die lokale Entwicklung.
  3. Führen Sie in Ihrer CI-Umgebung mvn clean install -Drevision=${BUILD_NUMBER} oder so etwas oder sogar mvn clean verify -Drevision=${BUILD_NUMBER} aus.

Sie können beispielsweise https://wiki.jenkins-ci.org/display/JENKINS/Version+Number+Plugin verwenden, um interessante Build-Nummern zu generieren.

Wenn Sie herausgefunden haben, dass der Build stabil ist (z. B. Pass-Abnahmetests bestehen), können Sie die Version auf Nexus oder ein anderes Repository verschieben. Alle instabilen Builds gehen einfach in den Papierkorb.

14
Piotr Gwiazda

Es gibt einige großartige Diskussionen und Vorschläge, wie man mit der Versionsnummer und der Continuous Delivery (CD) von Maven umgehen kann (ich werde sie nach meinem Teil der Antwort hinzufügen).

Also zuerst meine Meinung zu SNAPSHOT-Versionen. In maven zeigt ein SNAPSHOT an, dass sich dieses derzeit an der spezifischen Version vor dem SNAPSHOT-Suffix befindet. Daher haben Werkzeuge wie Nexus oder das Maven-Release-Plugin eine spezielle Behandlung für SNAPSHOTS. Für Nexus werden sie in einem separaten Repository gespeichert und können mehrere Artefakte mit derselben SNAPSHOT-Release-Version aktualisieren. Ein SNAPSHOT kann sich also ändern, ohne dass Sie davon erfahren (weil Sie niemals eine Zahl in Ihrem Pom erhöhen). Aus diesem Grund empfehle ich nicht die Verwendung von SNAPSHOT-Abhängigkeiten in einem Projekt, insbesondere in einer CD-Welt, da der Build nicht mehr zuverlässig ist. 

SNAPSHOT als Projektversion wäre aus den oben genannten Gründen ein Problem, wenn Ihr Projekt von anderen verwendet wird.

Ein weiteres Problem von SNAPSHOT ist für mich, dass es nicht mehr wirklich nachvollziehbar oder reproduzierbar ist. Wenn ich eine Version 0.0.1-SNAPSHOT in der Produktion sehe, muss ich einige Nachforschungen anstellen, um herauszufinden, wann die Build-Version von welcher Version erstellt wurde. Wenn ich eine Version dieser Software auf einem Dateisystem finde, muss ich mir die Datei pom.properties oder MANIFEST ansehen, um zu sehen, ob es sich um alten Müll handelt oder vielleicht die neueste und beste Version.

Um zu vermeiden, dass die Versionsnummer manuell geändert wird (insbesondere wenn Sie mehrere Builds pro Tag erstellen), lassen Sie den Build Server die Nummer für Sie ändern. Also für die Entwicklung würde ich mit einem gehen 

<major>.<minor>-SNAPSHOT

version, aber beim Erstellen einer neuen Version könnte der Build Server den SNAPSHOT durch etwas Einzigartigeres und Rückverfolgbares ersetzen.

Zum Beispiel eins davon:

<major>.<minor>-b<buildNumber>
<major>.<minor>-r<scmNumber>

Die Haupt- und Nebenzahl kann also für Marketingfragen verwendet werden oder nur um zu zeigen, dass ein neuer Meilenstein erreicht ist, und er kann manuell geändert werden, wann immer Sie möchten. Und die buildNumber (Nummer von Ihrem Continuous Integration Server) oder die scmNumber (Revision von Subversion oder GIT) machen jede Version eindeutig und nachvollziehbar. Bei Verwendung der BuildNumber- oder Subversion-Version sind die Projektversionen sogar sortierbar (nicht mit GIT-Nummern). Mit der buildNumber oder der scmNumber können Sie auch leicht erkennen, welche Änderungen in dieser Version enthalten sind.

Ein anderes Beispiel ist die Versionierung von stackoverflow, die verwendet wird

<year>.<month>.<day>.<buildNumber>

Und hier die fehlenden Links:

9
mszalbach

TUN SIE NICHT!

<Major>.<minor>-<build>

wird Sie in den Rücken beißen, weil Maven alles nach einem Bindestrich als LEXICAL behandelt. Dies bedeutet, dass Version 1 lexikalisch höher als 10 ist.

Das ist schlecht, wenn Sie nach der neuesten Version von maven fragen, dann gewinnt der obige Punkt.

Die Lösung ist die Verwendung eines Dezimalpunkts anstelle eines Bindestrichs vor der Build-Nummer.

MACH DAS!

<Major>.<minor>.<build>

Es ist in Ordnung, SNAPSHOT-Versionen lokal zu haben, aber als Teil eines Builds ist es besser zu verwenden

mvn versions:set -DnewVersion=${major}.${minor}.${build.number}

Es gibt Möglichkeiten, die Haupt-/Nebenversion von pom abzuleiten, z. B. mithilfe von help: evaluieren und an eine Umgebungsvariable weiterleiten, bevor versions: set aufgerufen wird. Das ist schmutzig, aber ich habe mir wirklich den Kopf (und andere in meinem Team) gekratzt, um es einfacher zu machen, und Maven war (zu der Zeit) nicht reif genug, um damit fertig zu werden. Ich glaube, dass Maven 2.3.1 etwas hat, was dazu beitragen kann, so dass diese Informationen nicht mehr relevant sind.

Es ist in Ordnung für eine Reihe von Entwicklern, auf derselben Major.Minor-Version zu veröffentlichen - aber es ist immer gut, darauf zu achten, dass kleinere Änderungen nicht brüchig sind und große Versionsänderungen einige brechende API-Änderungen oder eine Abwertung der Funktionalität/des Verhaltens bewirken.

Aus einer Continuous Delivery-Perspektive ist jeder Build potentiell freigebbar, daher sollte jeder Check-In einen Build erstellen.

6
user924272

Als Ausgangspunkt können Sie einen Blick auf Maven: The Complete Reference werfen. Projektversionen.

Dann gibt es einen guten Beitrag zur Versionierungsstrategie.

2
dmitri

Bei meiner Arbeit für Web-Apps verwenden wir derzeit dieses Versionsmuster: 

<jenkins build num>-<git-short-hash> 

Beispiel: 247-262e37b9. 

Dies ist Nizza, weil es Ihnen eine Version gibt, die immer einzigartig und nachvollziehbar ist, zurück zu den Jenkins-Builds und -Git-Revisionen, die sie produziert haben.

In Maven 3.2.1+ haben sie schließlich die Warnungen für die Verwendung einer $ {-Eigenschaft} als Version beendet, sodass es wirklich einfach ist, diese zu erstellen. Ändern Sie einfach alle Ihre Poms, um <version>${revision}</version> zu verwenden, und erstellen Sie sie mit -Drevision=whatever. Das einzige Problem dabei ist, dass die Version in Ihren freigegebenen Poms bei ${revision} in der eigentlichen POM-Datei bleibt, was zu allen möglichen seltsamen Problemen führen kann. Um dieses Problem zu lösen, habe ich ein einfaches Maven-Plugin geschrieben ( https://github.com/jeffskj/cd-versions-maven-plugin ), das die Variablenersetzung in der Datei vornimmt.

1
Jeff S