Использование maven для вывода номера версии в текстовый файл
Я хочу создать ZIP-файл, который обновит приложение с помощью Maven. Zip будет размещен на сервере, и я использую плагин сборки для создания Zip. Однако я бы хотел, чтобы maven автоматически генерировал текстовый файл, в котором хранится номер текущей версии вне почтового индекса. Это возможно?
РЕДАКТИРОВАТЬ: я успешно сделал это с помощью maven Assembly Plugin и двух дескрипторов для создания двух пользовательских сборок. У каждого есть одна цель каталога, и он просто создает папку с обновленным version.txt на основе фильтрации. Тогда другой с единственной целью фактически упаковывает файл почтового индекса. Это кажется очень не элегантным, и я думаю, что он не будет должным образом обновлять репозиторий Maven со всей обновленной папкой. Если есть лучший способ сделать это, пожалуйста, дайте мне знать.
15 ответов
Конечно. Создайте текстовый файл где-нибудь в 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>
Используйте стандарт 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?
То, что вы имеете в виду, называется фильтрацией
Вам необходимо включить фильтрацию для определенного ресурса, а затем использовать ${project.version}
который будет заменен как часть вашей сборки
Для приложения Spring Boot, следуйте принятому ответу сверху, заменяя
${project.version}
с
@project.version@
Вот ссылка на документацию https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.3-Release-Notes
В 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
Вы также можете использовать скрипт Groovy для создания файла информации о версии. Мне больше нравится этот метод, потому что вам не нужно исключать материал в дескрипторе ассемблера. Вы также можете использовать этот метод, чтобы при желании включать материал, доступный только в том случае, если вы строите из Jenkins/Hudson (например, проверьте oug 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>
Я только что сделал это с задачей муравья.
<echo file="version.txt">${project.version}</echo>
Просто используйте 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>
Я предпочитаю https://github.com/internetitem/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>
Вы можете использовать maven-antrun-plugin и выражения регулярного выражения для ввода версии в файл. PS: содержимое файла version.txt - это любая строка, например: версия.
...
<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>
Добавление ниже плагина в pom.xml сработало для меня. Это только комбинация приведенных выше ответов: -
<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>
[...]
Одна возможность - сохранить все свойства проекта в .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
,
Если вы хотите написать текстовый файл, используя доступные свойства maven, вы можете сделать то, что предложил Dr.Octoboz (спасибо). Это правда, что весь файл перезаписан. Возможно, это лучший совет (используйте блок CDATA) для будущих читателей.
<echo file="C:/var/install/myapp/${thisProfile}/${maven.build.timestamp}/myapp_install.txt"><![CDATA[
# Profile ${thisProfile}
bmix api https://api.eu-de.bluemix.net
bmix login -u myapp@mydomain.com -p "********"
bmix target --cf
bmix cf push myapp1-${service} -p C:\var\install\myapp\${thisProfile}\${maven.build.timestamp}\myapp1.war
bmix cf push myapp2-${service} -p C:\var\install\myapp\${thisProfile}\${maven.build.timestamp}\myapp1.war
]]></echo>
Создайте файл version.txt со следующим содержимым в /src/version.txt.
Build version: ${project.version}
Используйте плагин сборки и добавьте шаг в dist.xml с фильтрацией =true
<files>
<file>
<source>${basedir}/src/version.txt</source>
<outputDirectory>${root.dist.folder}</outputDirectory>
<filtered>true</filtered>
</file>
</files>
Чтобы добавить ответ Шона, вы можете переместить файл версии в папку в jar-файле, используя параметр 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>