Im Gegensatz zu anderen denke ich, dass es viele Gründe gibt, warum Sie immer das Neueste wollen Version. Vor allem, wenn Sie kontinuierliche Bereitstellung tun (wir haben manchmal wie 5 Releases an einem Tag) und nicht wollen, um ein Multi-Modul-Projekt zu tun.
Was ich tue, ist Hudson/Jenkins machen die folgenden für jeden Build:
mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true
Das heißt, ich verwende das Versions-Plugin und das scm-Plugin, um die Abhängigkeiten zu aktualisieren, und checke es dann in die Versionskontrolle ein. Ja, ich lasse mein CI SCM-Check-Ins durchführen (was Sie ohnehin für das Maven Release Plugin tun müssen).
Sie sollten das Versions-Plugin so einrichten, dass es nur das aktualisiert, was Sie wollen:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includesList>com.snaphop</includesList>
<generateBackupPoms>false</generateBackupPoms>
<allowSnapshots>true</allowSnapshots>
</configuration>
</plugin>
Ich verwende das Release-Plugin für die Freigabe, das sich um -SNAPSHOT kümmert und überprüft, ob es eine Release-Version von -SNAPSHOT gibt (was wichtig ist).
Wenn Sie tun, was ich tue, erhalten Sie die neueste Version für alle Snapshot-Builds und die neueste Release-Version für Release-Builds. Ihre Builds werden auch reproduzierbar sein.
更新情報
Mir ist aufgefallen, dass in einigen Kommentaren nach den Besonderheiten dieses Arbeitsablaufs gefragt wurde. Ich möchte sagen, dass wir diese Methode nicht mehr verwenden und der Hauptgrund dafür ist, dass das Maven-Versionen-Plugin fehlerhaft ist und im Allgemeinen von Natur aus mangelhaft ist.
Es ist fehlerhaft, denn um das Versions-Plugin zum Anpassen von Versionen auszuführen, müssen alle vorhandenen Versionen vorhanden sein, damit das pom korrekt ausgeführt werden kann. Das heißt, das Versions-Plugin kann nicht auf die neueste Version von irgendetwas aktualisieren, wenn es die im Pom referenzierte Version nicht finden kann. Dies ist eigentlich ziemlich ärgerlich, da wir oft alte Versionen aus Speicherplatzgründen bereinigen.
Sie benötigen ein separates Tool von Maven, um die Versionen anzupassen (damit Sie nicht von der pom-Datei abhängig sind, um korrekt zu arbeiten). Ich habe ein solches Tool in der bescheidenen Sprache Bash geschrieben. Das Skript aktualisiert die Versionen wie das Versions-Plugin und checkt das Pom zurück in die Versionskontrolle. Es läuft auch etwa 100x schneller als das mvn versions plugin. Leider ist es nicht in einer Art und Weise für die öffentliche Nutzung geschrieben, aber wenn die Leute daran interessiert sind, könnte ich es so machen und es in einem Gist oder Github setzen.
Um auf den Arbeitsablauf zurückzukommen, nach dem in einigen Kommentaren gefragt wurde: Das ist es, was wir tun:
- Wir haben etwa 20 Projekte in ihren eigenen Repositories mit eigenen Jenkins-Jobs
- Bei der Veröffentlichung wird das Maven Release Plugin verwendet. Der Arbeitsablauf ist in der Dokumentation des Plugins beschrieben. Das Maven-Release-Plugin ist irgendwie ätzend (und das ist nett gemeint), aber es funktioniert. Eines Tages planen wir, diese Methode durch etwas Optimaleres zu ersetzen.
- Wenn eines der Projekte veröffentlicht wird, führt Jenkins einen speziellen Job aus, den wir den Update-All-Versions-Job nennen (woher Jenkins weiß, dass es sich um eine Veröffentlichung handelt, ist kompliziert, zum Teil weil das Maven-Jenkins-Release-Plugin auch ziemlich beschissen ist).
- Die Aufgabe "Alle Versionen aktualisieren" kennt alle 20 Projekte. Es ist eigentlich ein Aggregator pom, um genau zu sein, mit allen Projekten im Modulbereich in der Reihenfolge der Abhängigkeiten. Jenkins führt unser magisches groovy/bash foo aus, das alle Projekte abruft, die Versionen auf den neuesten Stand bringt und dann die Poms eincheckt (wiederum in Abhängigkeitsreihenfolge basierend auf dem Modulbereich).
- Für jedes Projekt, bei dem sich das Pom geändert hat (aufgrund einer Versionsänderung in einer Abhängigkeit), wird es eingecheckt, und dann pingen wir sofort Jenkins an, um den entsprechenden Job für dieses Projekt auszuführen (dies dient dazu, die Reihenfolge der Build-Abhängigkeiten beizubehalten, da man sonst der Gnade des SCM Poll Schedulers ausgeliefert ist).
An diesem Punkt bin ich der Meinung, dass es gut ist, die Freigabe- und Autoversion als separates Tool von der allgemeinen Version zu haben.
Nun könnte man meinen, dass Maven wegen der oben genannten Probleme ziemlich scheiße ist, aber das wäre tatsächlich ziemlich schwierig mit einem Build-Tool, das keine einfach zu analysierende Deklaration hat ausziehbar Syntax (auch XML genannt).
In der Tat fügen wir benutzerdefinierte XML-Attribute durch Namespaces hinzu, um Hinweise auf Bash/Groovy-Skripte zu geben (z. B. "Diese Version nicht aktualisieren").
227 Stimmen
Ich empfehle diese Praxis (ebenso wie die Verwendung von Versionsbereichen) nicht, um die Reproduzierbarkeit der Builds zu gewährleisten. Ein Build, der plötzlich aus einem unbekannten Grund fehlschlägt, ist viel ärgerlicher als die manuelle Aktualisierung einer Versionsnummer.
17 Stimmen
@PascalThivent Manuelles Aktualisieren einer Versionsnummer in einem pom ist ein Schmerz, wenn Sie kontinuierliche Releases tun. Ich verwende das versions-Plugin in Kombination mit dem scm-Plugin, um dies zu umgehen (siehe meine Antwort).
5 Stimmen
@PascalThivent Beide sind ärgerlich, aber auf unterschiedliche Weise. Ich möchte je nach Situation zwischen beiden wählen können und nicht gezwungen werden, eines zu benutzen, weil jemand anderes entschieden hat, dass dieses besser ist.
0 Stimmen
Die Guava-Bibliothek ist ein gutes Beispiel dafür, dass in der neuesten Version Klassen aus früheren Versionen entfernt wurden, was zu einem Bruch im Build führt. Die Maven-Mentalität besagt, dass jede neuere Version jede frühere ersetzen kann, was in der Praxis nicht zutrifft.
0 Stimmen
@Martin Ich bin mir der x.y.z-SNAPSHOT-Konvention bewusst, aber ich dachte an Bibliotheken, die in endgültigen Versionen für das Repository freigegeben werden (d.h. von dream-library-1.2.3.jar zu dream-library-1.2.4.jar, und so weiter).