I want to generate a zip file that will update an application with maven. The zip will be hosted on a server and I am using the assembly plugin to generate the zip. However I would like maven to automatically generate a text file that stores the current version number outside the zip. How is this possible?
EDIT: I successfully did it using the maven Assembly Plugin and two descriptors to create two custom assemblies. One has a directory-single goal and it just creates a folder with the updated version.txt based on filtering. Then another one with a single goal actually packages the zip file. This seems to be very inelegant and I guess it will not properly update the maven repo with the whole updated folder. If there is a better way to do this, please let me know.
Sure. Create a text file somewhere in src/main/resources, call it version.txt (or whatever)
File content:
${project.version}
now in your pom.xml, inside the build element, put this block:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/version.txt</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/version.txt</exclude>
</excludes>
</resource>
...
</resources>
</build>
after every build, the file (which you can find in target/classes) will contain the current version.
Now if you want to move the file somewhere else automatically, you are probably going to need to execute an ant task via the maven-antrun-plugin.
Something like this:
<build>
...
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<copy file="${project.build.outputDirectory}/version.txt"
toFile="..." overwrite="true" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Use standard META-INF\MANIFEST.MF (Then you can use Java code getClass().getPackage().getImplementationVersion() to get version)
For .war use this configuration:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
That will add manifest during build, or you can call mvn war:manifest
What you are referring to is called filtering
You need to enable filtering on a particular resource, and then use ${project.version} which will be substituted as part of your build
You could also use a Groovy script to produce a version info file. I like this method more because you don't have to exclude stuff in the assembly-plugin's descriptor. You can also use this method to optionally include stuff only available if you are building from Jenkins/Hudson (e.g. check oug BUILD_ID etc...).
So you would have a file-generating groovy script in pom.xml like this:
<plugin>
<groupId>org.codehaus.mojo.groovy</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
<![CDATA[
println("==== Creating version.txt ====");
File mainDir = new File("src/main");
if(mainDir.exists() && !mainDir.isDirectory()) {
println("Main dir does not exist, wont create version.txt!");
return;
}
File confDir = new File("src/main/conf");
if(confDir.exists() && !confDir.isDirectory()) {
println("Conf dir is not a directory, wont create version.txt!");
return;
}
if(!confDir.exists()) {
confDir.mkdir();
}
File versionFile = new File("src/main/conf/version.txt");
if(versionFile.exists() && versionFile.isDirectory()) {
println("Version file exists and is directory! Wont overwrite");
return;
}
if(versionFile.exists() && !versionFile.isDirectory()) {
println("Version file already exists, overwriting!");
}
println("Creating Version File");
BufferedWriter writer = new BufferedWriter(new FileWriter(versionFile));
writer.write("groupId = ${project.groupId}");
writer.newLine();
writer.write("artifactId = ${project.artifactId}");
writer.newLine();
writer.write("version = ${project.version}");
writer.newLine();
writer.write("timestamp = ${maven.build.timestamp}");
String buildTag = "";
String buildNumber = "";
String buildId = "";
try {
buildTag = "${BUILD_TAG}";
buildNumber = "${BUILD_NUMBER}";
buildId = "${BUILD_ID}";
writer.write("BUILD_TAG = " + buildTag + "\n");
writer.write("BUILD_NUMBER = " + buildNumber + "\n");
writer.write("BUILD_ID = " + buildId + "\n");
} catch (Exception e) {
println("============= Could not find BUILD_TAG probably this is not a Jenkins/Hudson build ===========");
}
writer.close();
]]>
</source>
</configuration>
</execution>
</executions>
</plugin>
And then your assembly plugin plugin in pom.xml that would look like this:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<!-- Produce the all-dependencies-included jar for java classloaders -->
<executions>
<execution>
<id>all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>${project.artifactId}</finalName>
<descriptors>
<descriptor>dist-all.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
And finally your assembly descriptor dist-all.xml would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>all</id>
<formats>
<format>dir</format>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/conf</directory>
<outputDirectory></outputDirectory>
<includes>
<include>**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
in Maven 3, Use Sean's answer to create your version.txt file, (mine is shown here, along with build date and active profile):
${project.version}-${profileID}
${buildDate}
adding property profileID to each of the profiles, e.g.:
<properties>
<profileID>profileName</profileID>
</properties>
Use Maven copy-resources to copy the file to an easier to reach directory such as ${basedir} or ${basedir}/target:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}</outputDirectory>
<resources>
<resource>
<directory>${basedir}/target/.../[version.txt dir]/version.txt</directory>
<includes>
<include>version.txt</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
output looks like this:
1.2.3-profileName
yymmdd_hhmm
I just did this with an ant task.
<echo file="version.txt">${project.version}</echo>
For a Spring Boot application, follow the accepted answer from above however substituting
${project.version}
with
@project.version@
Here's the link to the documentation https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.3-Release-Notes#maven-resources-filtering
One possibility is to store all project properties to the built .jar using maven-properties-plugin.
Then you can read these properties using standard (though not too practical) Java Properties API.
<!-- Build properties to a file -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals> <goal>write-project-properties</goal> </goals>
<configuration>
<outputFile> ${project.build.outputDirectory}/build.properties </outputFile>
</configuration>
</execution>
</executions>
</plugin>
Be careful with this approach as it may leak properties that are not supposed to end up published, also from settings.xml.
To add to Sean's answer, you can move the version file to a folder location within the jar by using the targetpath parameter within resource. The following code creates a folder called 'resources' within the jar and the text file (version.number) is found in that folder.
<resource>
<directory>resources</directory>
<targetPath>resources</targetPath>
<filtering>true</filtering>
<includes>
<include>version.number</include>
</includes>
</resource>
<resource>
<directory>resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>version.number</exclude>
</excludes>
</resource>
I prefer the write-properties-file-maven-plugin, because I don't want all maven-project-properties in one file:
<plugin>
<groupId>com.internetitem</groupId>
<artifactId>write-properties-file-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>one</id>
<phase>compile</phase>
<goals>
<goal>write-properties-file</goal>
</goals>
<configuration>
<filename>test.properties</filename>
<properties>
<property>
<name>one</name>
<value>1</value>
</property>
<property>
<name>artifactId</name>
<value>My Artifact ID is ${project.artifactId}</value>
</property>
</properties>
</configuration>
</execution>
</executions>
</plugin>
来源:https://stackoverflow.com/questions/3532135/using-maven-to-output-the-version-number-to-a-text-file