'Using maven to output the version number to a text file
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.
Solution 1:[1]
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>
Solution 2:[2]
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
Solution 3:[3]
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
Solution 4:[4]
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
Solution 5:[5]
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
Solution 6:[6]
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>
Solution 7:[7]
I just did this with an ant task.
<echo file="version.txt">${project.version}</echo>
Solution 8:[8]
you can use the maven-antrun-plugin and regex expressions to input the version into the file. PS: version.txt file content is any string ex:version.
...
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<replaceregexp file="resources/version.txt" match=".*" replace="${project.version}" byline="true" />
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Solution 9:[9]
Adding below plugin in pom.xml worked for me. This is a combination of above answers only:-
<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target><echo file="version.txt">${project.version}</echo> </target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
Solution 10:[10]
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
.
Solution 11:[11]
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>
Solution 12:[12]
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>
Solution 13:[13]
Just use the maven-help-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>generate-version-file</id>
<phase>prepare-package</phase>
<goals>
<goal>evaluate</goal>
</goals>
<configuration>
<expression>project.version</expression>
<output>${project.build.directory}/version.txt</output>
</configuration>
</execution>
</executions>
</plugin>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow