#67: Konsistente Versionierung via Maven CI-friendly revision
- ${revision}-Property im Parent-POM eingeführt; alle Kind-POM-<parent>-Blöcke
verwenden ${revision} statt hartkodierter Version
- flatten-maven-plugin 1.6.0 in <build><plugins> des Parent-POM aktiviert
(resolveCiFriendliesOnly), sodass installierte POMs keine unaufgelösten
${revision}-Referenzen enthalten
- MANIFEST.MF des Shade-JARs enthält Implementation-Version und Implementation-Title
- app.version im Packaging-Modul auf ${revision} umgestellt (war 2.5.0)
- ApplicationVersionProvider: neue Utility-Klasse im Bootstrap-Modul liest
Implementation-Version aus MANIFEST.MF, Fallback "dev" bei ungepacktem Betrieb
- ApplicationVersionProviderTest: prüft Fallback-Verhalten im Testlauf
- .gitignore: .flattened-pom.xml-Dateien ausgeschlossen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
# =========================================================
|
||||
**/target/
|
||||
dependency-reduced-pom.xml
|
||||
# Generierte Flat-POM-Dateien des flatten-maven-plugin (CI-friendly Versioning)
|
||||
**/.flattened-pom.xml
|
||||
|
||||
# =========================================================
|
||||
# Eclipse / IDE
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-adapter-in-cli</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-adapter-in-gui</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-adapter-out</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-application</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-bootstrap</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -105,6 +105,11 @@
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>de.gecheckt.pdf.umbenenner.bootstrap.PdfUmbenennerApplication</mainClass>
|
||||
<manifestEntries>
|
||||
<!-- Versionseintrag wird zur Laufzeit via getImplementationVersion() ausgelesen -->
|
||||
<Implementation-Version>${revision}</Implementation-Version>
|
||||
<Implementation-Title>PDF KI Renamer</Implementation-Title>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
<!-- Merge META-INF/services entries from all JARs instead of overwriting -->
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package de.gecheckt.pdf.umbenenner.bootstrap;
|
||||
|
||||
/**
|
||||
* Liest die Anwendungsversion aus dem MANIFEST.MF des ausführbaren Fat-JARs.
|
||||
* <p>
|
||||
* Im gepackten Betrieb wird der Eintrag {@code Implementation-Version} aus dem
|
||||
* JAR-Manifest gelesen, der beim Build durch das Shade-Plugin befüllt wird.
|
||||
* Im IDE-Betrieb und in Testumgebungen ohne gepacktes JAR steht kein Manifest
|
||||
* zur Verfügung; in diesem Fall wird der Fallback {@code "dev"} zurückgegeben.
|
||||
* <p>
|
||||
* Diese Klasse ist eine reine Hilfsklasse ohne Zustand; alle Methoden sind statisch.
|
||||
* Die Verdrahtung mit der GUI-Statuszeile erfolgt in einer späteren Ausbaustufe.
|
||||
*/
|
||||
public final class ApplicationVersionProvider {
|
||||
|
||||
/** Fallback-Version, wenn kein Manifest-Eintrag verfügbar ist. */
|
||||
private static final String FALLBACK_VERSION = "dev";
|
||||
|
||||
/** Utility-Klasse – kein öffentlicher Konstruktor. */
|
||||
private ApplicationVersionProvider() {
|
||||
// nicht instanziierbar
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Anwendungsversion zurück.
|
||||
* <p>
|
||||
* Die Version wird aus dem {@code Implementation-Version}-Eintrag des Pakets
|
||||
* {@code de.gecheckt.pdf.umbenenner.bootstrap} gelesen. Dieser Eintrag wird
|
||||
* beim Build durch das Shade-Plugin mit dem Wert der Property {@code ${revision}}
|
||||
* befüllt.
|
||||
* <p>
|
||||
* Ist der Eintrag nicht vorhanden (IDE-Start, Tests, ungepackter Betrieb),
|
||||
* wird der Wert {@code "dev"} zurückgegeben.
|
||||
*
|
||||
* @return die aufgelöste Versionsnummer, niemals {@code null}
|
||||
*/
|
||||
public static String resolveVersion() {
|
||||
String version = ApplicationVersionProvider.class.getPackage().getImplementationVersion();
|
||||
if (version == null) {
|
||||
// Fallback für IDE-Start und ungepackten Betrieb
|
||||
return FALLBACK_VERSION;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package de.gecheckt.pdf.umbenenner.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Unit-Tests für {@link ApplicationVersionProvider}.
|
||||
* <p>
|
||||
* Im Testlauf ist kein gepacktes JAR mit Manifest vorhanden; der Test prüft deshalb
|
||||
* ausschließlich das Fallback-Verhalten und stellt sicher, dass die Methode niemals
|
||||
* {@code null} zurückgibt.
|
||||
*/
|
||||
class ApplicationVersionProviderTest {
|
||||
|
||||
/**
|
||||
* Im Testlauf (kein Fat-JAR, kein Manifest-Eintrag) muss der Fallback-Wert
|
||||
* {@code "dev"} zurückgegeben werden.
|
||||
*/
|
||||
@Test
|
||||
void resolveVersion_ohneGepacktesJar_gibtDevZurueck() {
|
||||
// Wenn kein MANIFEST.MF mit Implementation-Version vorhanden ist (IDE / Test),
|
||||
// wird der Fallback-Wert geliefert.
|
||||
String version = ApplicationVersionProvider.resolveVersion();
|
||||
assertThat(version).isEqualTo("dev");
|
||||
}
|
||||
|
||||
/**
|
||||
* Das Ergebnis von {@link ApplicationVersionProvider#resolveVersion()} darf
|
||||
* niemals {@code null} sein – weder im IDE-Betrieb noch im gepackten Betrieb.
|
||||
*/
|
||||
@Test
|
||||
void resolveVersion_gibtNiemalsNull() {
|
||||
assertThat(ApplicationVersionProvider.resolveVersion()).isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-coverage</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-domain</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>pdf-umbenenner-packaging</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
@@ -21,12 +21,11 @@
|
||||
|
||||
<properties>
|
||||
<!--
|
||||
Anwendungsversion des erzeugten Windows-Installers. Bewusst entkoppelt von
|
||||
${project.version}, damit die ausgelieferte Installer-Version unabhaengig
|
||||
vom Maven-Snapshot-Zyklus gepflegt werden kann. Wird ausschliesslich
|
||||
vom Profil "release" in der jpackage-Konfiguration ausgewertet.
|
||||
Anwendungsversion des erzeugten Windows-Installers. Wird direkt aus ${revision}
|
||||
abgeleitet, damit Installer-Version und JAR-Version konsistent sind.
|
||||
Beim Release-Build: -Drevision=MAJOR.MINOR.BUILD_NUMBER
|
||||
-->
|
||||
<app.version>2.5.0</app.version>
|
||||
<app.version>${revision}</app.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.gecheckt</groupId>
|
||||
<artifactId>pdf-umbenenner-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>${revision}</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>pdf-umbenenner-domain</module>
|
||||
@@ -18,6 +18,10 @@
|
||||
<module>pdf-umbenenner-packaging</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<!-- Zentrale Versionsproperty für Maven CI-friendly Versioning.
|
||||
Kann per -Drevision=MAJOR.MINOR.BUILD überschrieben werden (z. B. im CI). -->
|
||||
<revision>0.0.1-SNAPSHOT</revision>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
|
||||
@@ -230,6 +234,39 @@
|
||||
</pluginManagement>
|
||||
|
||||
<plugins>
|
||||
<!--
|
||||
flatten-maven-plugin: löst ${revision} in installierten POMs auf, sodass
|
||||
keine unaufgelösten Property-Referenzen in ~/.m2 erscheinen.
|
||||
flattenMode=resolveCiFriendliesOnly beschränkt die Auflösung auf CI-friendly
|
||||
Properties (${revision}, ${sha1}, ${changelist}) und lässt alle anderen
|
||||
Properties unverändert.
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>flatten-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<updatePomFile>true</updatePomFile>
|
||||
<flattenMode>resolveCiFriendliesOnly</flattenMode>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>flatten</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>flatten</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>flatten.clean</id>
|
||||
<phase>clean</phase>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user