Using maven to output the version number to a text

2019-01-08 11:00发布

I want to generate an 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. Is this possible?

EDIT: I successfully did it using the maven Assembly Plugin and two descriptor 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 up date the maven repo with the whole updated folder. If there is a better way to do this please let me know.

10条回答
太酷不给撩
2楼-- · 2019-01-08 11:18

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
查看更多
聊天终结者
3楼-- · 2019-01-08 11:18

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>
查看更多
贪生不怕死
4楼-- · 2019-01-08 11:20

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>
查看更多
做自己的国王
5楼-- · 2019-01-08 11:25

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>
查看更多
登录 后发表回答