在使用Maven多模块结构工程时,版本管理是一件很繁琐且容易出错的事情。每次升级版本号都要手动调整或者通过mvn versions:set -DnewVerion=xx
命令去更改每一个子模块的版本号,非常的不方便,而且会改动所有的模块,出现如下效果:
其实Maven已经提供了这种CI版本的管理方式,下面来介绍一下具体使用方法。
Maven官方文档说:自 Maven 3.5.0-beta-1 开始,可以使用 ${revision}, ${sha1} and/or ${changelist} 这样的变量作为版本占位符。
即在maven多模块项目中,可配合插件flatten-maven-plugin
及${revision}
属性来实现全局版本统一管理。
Maven Version:Apache Maven 3.5.0-beta-1及以上版本
Maven Plugin:flatten-maven-plugin
IDE: IntelliJ IDEA 2021.3
JDK: 1.8.0_301
POM文件:使用占位符${revision}
① 只能命名成revision
,不可以更改成其他命名;
② Idea下使用${revision}
定义Parent版本时会提示错误“Reports that usage of properties in modules parent definition is prohibited”
,但并不影响使用,只是Idea不支持这种写法而已,升级IDea版本也可以解决 【可忽略】。
在properties标签中定义revision标签:
<project>
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.4.RELEASEversion>
<relativePath/>
parent>
<groupId>org.sssss.mavengroupId>
<artifactId>sssss-parentartifactId>
<version>${revision}version>
<packaging>pompackaging>
<properties>
<revision>1.0.0-SNAPSHOTrevision>
properties>
<modules>
<module>sssss-child1module>
...
modules>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>flatten-maven-pluginartifactId>
<version>1.5.0version>
<executions>
<execution>
<id>flattenid>
<phase>process-resourcesphase>
<goals>
<goal>flattengoal>
goals>
execution>
<execution>
<id>flatten.cleanid>
<phase>cleanphase>
<goals>
<goal>cleangoal>
goals>
execution>
executions>
<inherited>trueinherited>
<configuration>
<updatePomFile>trueupdatePomFile>
<flattenMode>resolveCiFriendliesOnlyflattenMode>
configuration>
plugin>
plugins>
build>
project>
关键点:
① 父子模块需遵循父子目录层次;
② 在父模块中引入插件flatten-maven-plugin
;
③ 修改.gitignore文件,增加一行.flattened-pom.xml
;
④ 不可混合使用${revision}
和明确字符串版本号,若出现父子模块版本号混合使用${revision}和明确字符串形式如1.0.0.-SNAPSHOT,在mvn package会出现类似如下错误:
[FATAL] Non-resolvable parent POM for org.sssss.maven:child1:[unknown-version]:
Could not find artifact org.sssss.maven:sssss-parent:pom:1.0.0-SNAPSHOT and ‘parent.relativePath’ points at wrong local POM @ line 5, column 13
关于子模块中parent.relativePath使用:
../pom.xml
,即遵循父子目录层次
../module-1/pom.xml
子模块可以直接使用${revision}指定父模块的版本:
<project>
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.sssss.mavengroupId>
<artifactId>sssss-parentartifactId>
<version>${revision}version>
<relativePath>../pom.xmlrelativePath>
parent>
<artifactId>sssss-child1artifactId>
<packaging>jarpackaging>
project>
多模块工程结构下,会有子模块相互依赖的情况,使用${revision}
会导致构建失败,应该使用${project.version}
来定义依赖 (同父工程下的依赖) 的版本,请勿使用${parent.version}
。
<project>
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.sssss.mavengroupId>
<artifactId>sssss-parentartifactId>
<version>${revision}version>
<relativePath>../pom.xmlrelativePath>
parent>
<artifactId>sssss-child2artifactId>
<packaging>jarpackaging>
<dependencies>
<dependency>
<groupId>org.sssss.mavengroupId>
<artifactId>child1artifactId>
<version>${project.version}version>
dependency>
dependencies>
执行install/deploy后,会将该模块的pom文件中的${revision}替换为实际的版本,每个模块下都会生成一个.flattened-pom.xml
文件。
基于以上操作,每次版本号变更,只需要修改父模块POM文件中的revision
即可。还可以用另一种动态添加参数的方式来指定版本:
mvn clean install -Drevision=1.0.0-SNAPSHOT # -D代表设置环境变量
maven-ci-friendly
flatten-maven-plugin
spring-boot-project
maven-relativepath
Maven多模块结构下版本管理的正确姿势