Использование maven для вывода номера версии в текстовый файл - PullRequest
49 голосов
/ 20 августа 2010

Я хочу создать zip-файл, который обновит приложение с помощью maven. Zip будет размещен на сервере, и я использую плагин сборки для создания Zip. Однако я бы хотел, чтобы maven автоматически генерировал текстовый файл, в котором хранится текущий номер версии за пределами zip. Как это возможно?

EDIT: Я успешно сделал это, используя maven Assembly Plugin и два дескриптора для создания двух пользовательских сборок. У каждого есть одна цель каталога, и он просто создает папку с обновленным version.txt на основе фильтрации. Затем другой с единственной целью фактически упаковывает zip-файл. Это кажется очень не элегантным, и я думаю, что он не будет корректно обновлять репозиторий Maven со всей обновленной папкой. Если есть лучший способ сделать это, пожалуйста, дайте мне знать.

Ответы [ 10 ]

87 голосов
/ 20 августа 2010

Конечно. Создайте текстовый файл где-нибудь в src / main / resources, назовите его version.txt (или как угодно)

Содержимое файла:

${project.version}

теперь в вашем pom.xml, внутри элемента сборки, поместите этот блок:

<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>

после каждой сборки файл (который вы можете найти в target / classes) будет содержать текущую версию.

Теперь, если вы хотите автоматически переместить файл в другое место, вам, вероятно, потребуется выполнить задачу ant с помощью maven-antrun-plugin .

Примерно так:

  <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>
16 голосов
/ 11 марта 2013

Используйте стандарт META-INF\MANIFEST.MF (тогда вы можете использовать Java-код getClass().getPackage().getImplementationVersion() для получения версии)

Для .war используйте эту конфигурацию:

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1</version>
    <configuration>
        <archive>                   
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
            </manifest>
        </archive>
    </configuration>
</plugin>

Это добавит манифест во время сборки, или вы можете позвонить mvn war:manifest

См. также Как получить версию пакета при запуске Tomcat?

12 голосов
/ 20 августа 2010

То, на что вы ссылаетесь, называется фильтрацией

Вам необходимо включить фильтрацию для определенного ресурса, а затем использовать ${project.version}, который будет заменен как часть вашей сборки

6 голосов
/ 01 июля 2015

в Maven 3, используйте ответ Шона , чтобы создать файл version.txt (здесь отображается мое, наряду с датой сборки и активным профилем):

${project.version}-${profileID}
${buildDate}

добавление свойства profileID к каждому из профилей, например ::

<properties>
    <profileID>profileName</profileID>
</properties>

Используйте ресурсы копирования Maven для копирования файла в более доступный каталог, такой как ${basedir} или ${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>

вывод выглядит так:

1.2.3-profileName
yymmdd_hhmm
6 голосов
/ 12 августа 2011

Вы также можете использовать скрипт Groovy для создания файла информации о версии. Мне больше нравится этот метод, потому что вам не нужно исключать материал в дескрипторе ассемблера. Вы также можете использовать этот метод, чтобы при желании включить материал, доступный только в том случае, если вы строите из Jenkins / Hudson (например, проверьте ou BUILD_ID и т. Д.).

Таким образом, в pom.xml у вас будет скрипт для генерирования файлов:

  <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>

А потом ваш плагин сборки в pom.xml, который будет выглядеть так:

  <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>

И, наконец, ваш дескриптор сборки dist-all.xml будет выглядеть так:

<?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>
2 голосов
/ 15 ноября 2018

Для приложения Spring Boot следуйте принятому ответу сверху, но заменив

${project.version}

на

@project.version@

Вот ссылка на документацию https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.3-Release-Notes#maven-resources-filtering

2 голосов
/ 11 июля 2017

Я только что сделал это с задачей муравья.

<echo file="version.txt">${project.version}</echo>
0 голосов
/ 12 ноября 2018

Я предпочитаю write-properties-file-maven-plugin , потому что я не хочу, чтобы все maven-project-properties были в одном файле:

  <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>
0 голосов
/ 04 июля 2017

Чтобы добавить ответ Шона, вы можете переместить файл версии в папку в банке с помощью параметра targetpath в ресурсе. Следующий код создает папку с именем 'resources' внутри jar, и в ней находится текстовый файл (version.number).

<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>
0 голосов
/ 23 апреля 2017

Одной из возможностей является сохранение всех свойств проекта во встроенном .jar с использованием maven-properties-plugin.
Затем вы можете прочитать эти свойства, используя стандартный (хотя и не слишком практичный) API свойств Java .

        <!-- 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>

Будьте осторожны с этим подходом, поскольку он может привести к утечке свойств, которые, как предполагается, не будут опубликованы, также из settings.xml.

...