[原创]Maven 打包时自动生成包含 SVN 时间戳 的版本号

本文档详细介绍了如何使用Maven和buildnumber-maven-plugin插件,通过配置POM.xml,实现构建时自动获取SVN版本号、日期,并生成自增版本号,最终更新env.properties文件中的buildCode。过程中涉及到的步骤包括设置SVN环境、在POM中配置scm、创建和读取自增版本号的properties文件,以及使用maven-resources-plugin过滤资源文件,确保在打包过程中自动替换占位符,完成版本信息的更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目标

使用mvn install时修改/config/env.properties中的buildCode 格式是
buildCode=Build1038 rev3083 @2021/12/27 16:42:15
build是自增版本号,rev是svn版本

所以一共有以下几个步骤
1、生成新的buildCode----获取SVN版本号和打包时间,想办法生成一个每次打包自增的版本号
2、打包时修改env.properties,把新的buildCode写入其中

生成新的buildCode

此处使用的是插件buildnumber-maven-plugin,它可以获取SVN版本号,构造时间戳和自增版本号。

获取SVN版本号

按照Maven和buildnumber-maven-plugin的官方文档构造的POM并不能获取到SVN版本号,以下说说自己的步骤和POM。
  • 检查SVN环境,在项目根目录下cmd运行svn info,查看是否有正确输出,若没有,检查SVN环境变量是否配置,若已有环境变量,应该是没安装svn的命令行客户端,重新安装一遍即可。
  • 我的项目是一个parent下面有很多子工程,一开始buildnumber-maven-plugin完全没生效,原因是只在parent的POM中配置了插件,还需要再Child中也声明一遍,这样才会在打包时调用插件
<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
  • 官方文档中没有配置scm的相关配置,在parent的POM中添加了scm。如果只是想要获取SVN版本号,这里就已经完成了,后续和文档一样,通过${buildNumber}调用即可。
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<scm>
		<connection>scm:svn:https://xxxxxx:8888/java</connection>
	</scm>
	<build>
		<plugins>
	      <plugin>
	        <groupId>org.codehaus.mojo</groupId>
	        <artifactId>buildnumber-maven-plugin</artifactId>
	        <version>1.4</version>
	        <executions>
	          <execution>
	            <phase>validate</phase>
	            <goals>
	              <goal>create</goal>
	            </goals>
	          </execution>
	        </executions>
	        <configuration>
	          <doCheck>false</doCheck>
	          <doUpdate>false</doUpdate>
	        </configuration>
	      </plugin>
	    </plugins>
	</build>
</project>

获取日期

这里可以直接参考官方的POM样例,后续通过${buildTime}调用

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>buildnumber-maven-plugin</artifactId>
	<version>1.4</version>
	<executions>
		<execution>
			<id>create-timestamp</id>
			<phase>process-resources</phase>
			<goals>
				<goal>create-timestamp</goal>
			</goals>
			<configuration>
				<timestampFormat>yyyy/MM/dd HH:mm:ss</timestampFormat>
				<timestampPropertyName>buildTime</timestampPropertyName>
			</configuration>
		</execution>
	</executions>

</plugin>

获取自增版本号

官方文档其实有提及这个部分,只是说得很简单

When you specify the special items of “buildNumber\d*” or “timestamp”, then some magic is performed. For each unique buildNumber, a properties file ( see buildNumberPropertiesFileLocation ) will be created (or read if it exists) which holds an integer, starting at 1. That number will be incremented on each access. Of course, the given example is somewhat non-sensical, since it will increment all 3 numbers on each build, but it shows the type of flexibility available. For each timestamp, you simply get the current date and time.

简单来说就是在<goal>create</goal>中创建buildNumber时,若配置了<format>,且<item>中有buildNumber这样的的项,会自动生成一个properties文件,以此维护一个自增的build号。这里直接放上我的POM来举例。

解释一下{0,number,#}是什么意思,调用<items>中的第一个item,视作number且去除千位后面的","。具体可以参考MessageFormat class的文档。

<items>中的buildNumber0插件会自己去<buildNumberPropertiesFileLocation>下面创建/读取properties文件,用于维护自增版本号。

<buildNumberPropertyName>是配置输出的buildNumber属性名,因为我同时需要SVN版本号和一个自增版本号,所以有两个<execution>,第一个<execution>获取SVN版本号,并存到${svnNo}中。

参考文档可以看出在使用<format>时可以直接生成时间戳,所以去掉了上面生成时间戳的<execution>

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>buildnumber-maven-plugin</artifactId>
	<version>1.4</version>
	<executions>
		<execution>
			<phase>process-resources</phase>
			<goals>
				<goal>create</goal>
			</goals>
			<configuration>
				<doCheck>false</doCheck>
				<doUpdate>false</doUpdate>
				<useLastCommittedRevision>true</useLastCommittedRevision>
				<buildNumberPropertyName>svnNo</buildNumberPropertyName>
			</configuration>
		</execution>
		<execution>
			<id>buildnumberFromPropertiesFile</id>
			<phase>process-resources</phase>
			<goals>
				<goal>create</goal>
			</goals>
			<configuration>
				<format>Build{0,number,#} rev${svnNo} @{1,date,yyyy/MM/dd HH:mm:ss}</format>
				<items>
					<item>buildNumber0</item>
					<item>timestamp</item>
				</items>
				<doCheck>false</doCheck>
				<doUpdate>false</doUpdate>
				<buildNumberPropertiesFileLocation>${project.basedir}/conf/build.properties</buildNumberPropertiesFileLocation>
			</configuration>
		</execution>
	</executions>
</plugin>

更新properties文件

要直接读取并修改properties很困难,起码我还没找到一个简单的办法,现在的实现是使用maven-resources-pluginfiltering功能实现的。

首先是通过<resource>标签将properties引入,注意配置<filtering>

然后设置newBuildSVNVersion属性

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<resources>
		<resource>
			<directory>${project.basedir}/conf</directory>
			<filtering>true</filtering>
		</resource>
	</resources>
	<properties>
		<newBuildSVNVersion>${buildNumber}</newBuildSVNVersion>
	</properties>
	<build>
	...
	</build>
</project>

最后在原始的properties文件中存入一个占位符,例如

buildCode=${newBuildSVNVersion}

这样Maven在<phase>process-resources</phase>中复制资源的时候会用<newBuildSVNVersion>属性去替换占位符。

好的,之前每一步都没有问题,但是为什么最后输出的properties文件内容是buildCode=${buildNumber}

原因是Maven处理资源是调用的插件maven-resources-plugin的<goal>resources</goal>,该阶段bind到了<phase>process-resources</phase>,且是在再上一层的parent中,导致处理资源的时候我们创建BuildNumber的插件还没被调用,即便是把BuildNumber插件也配置到<phase>process-resources</phase>。
解决方法是在当前POM中再配置一次maven-resources-plugin的<goal>resources</goal>,并放到BuildNumber插件的phase之后。

通过配置<id>default-resources</id>,该execution会覆盖parent中的execution,这样当拷贝资源的时候BuildNumber已经生成,自然就可以获取到正确的版本号了

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-resources-plugin</artifactId>
	<executions>
		<execution>
			<id>default-resources</id>
			<phase>compile</phase>
			<goals>
				<goal>resources</goal>
			</goals>
			<configuration>
				<outputDirectory>${project.build.outputDirectory}/resource</outputDirectory>
			</configuration>
		</execution>
	</executions>
</plugin>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值