【工具篇】Maven使用${revision}实现多模块版本统一管理

背景说明

在使用Maven多模块结构工程时,版本管理是一件很繁琐且容易出错的事情。每次升级版本号都要手动调整或者通过mvn versions:set -DnewVerion=xx命令去更改每一个子模块的版本号,非常的不方便,而且会改动所有的模块,出现如下效果:
【工具篇】Maven使用${revision}实现多模块版本统一管理_第1张图片

解决方法

其实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使用:

  • 默认值,不设置relativePath即为默认值,等价于../pom.xml,即遵循父子目录层次
    • 即优先查找上层目录…/pom.xml
    • 然后查找本地仓库
    • 最后查找远程仓库
    • 推荐自定义的开发项目遵循此种方式(即父子模块需遵循父子目录层次,且保持parent.relativePath的默认值)
  • 空值,即跳过本地文件目录查找
    • 直接查找本地仓库
    • 最后查找远程仓库
    • 适用于父依赖为第三方公有仓库中的依赖,如spring-boot-starter-parent
  • 其他值,可根据目录层次自行定义(推荐使用相对目录层次),如../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 / depoy

执行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多模块结构下版本管理的正确姿势

你可能感兴趣的:(#,工具使用,maven,java,intellij-idea)