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.


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

See also How to get package version at running Tomcat?


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


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

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