背景
个人进行多模块项目开发工作,由于模块仓库较多,且依赖错综复杂,在模块开发时进行版本管理越发困难。
因此在检索相关文章时发现了maven的maven-release-plugin
插件可以实现我想要的功能,并且立即在一个实验模块上测试了结果,且完美达成了目的,因此编写此文章来记录整个实践过程。
由于在CSDN上众多文章上踩了不少坑,本文主要参考官方maven release plugin来实践
环境准备
首先maven环境
mvn -v
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: /opt/maven/apache-maven-3.8.6
Java version: 17.0.4, vendor: GraalVM Community, runtime: /opt/java/graalvm-ce-java17-22.2.0/Contents/Home
Default locale: zh_CN_#Hans, platform encoding: UTF-8
OS name: "mac os x", version: "13.4", arch: "aarch64", family: "mac"
maven pom项目与git仓库,由于使用到release发布,还需要部署私有maven制品库(这里我使用Artifactory)。
配置
配置方式在Maven官方案例中描述如下:
To be able to make a solid start with the maven-release-plugin, there are 2 things you should include in your pom:
· the scm-
section with a developerConnection
· the maven-release-plugin with a locked version
1. 配置scm
(部分无关配置省略)
在<project>
中添加<scm>
标签,然后添加<developerConnection>
,该标签内容以scm:
起始,声明scm-provider
类型,例如这里使用git
仓库作为scm开发者连接URL,因此使用git:
前缀。(更多前缀与示例代码可以参考这里Apache Maven SCM – Overview of SCMs)
代码如下:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!--...-->
<scm>
<developerConnection>scm:git:https://xxx.xxx.com/union-project/union-common</developerConnection>
</scm>
</project>
2. 配置插件
Maven提供了两个插件,一个是maven-release-plugin
,一个是scm-maven-plugin
。
-
scm-maven-plugin
中为我们集成了软件配置管理的(SCM:Software Configuration Management)功能,他可以支持我们常用SVN、Git等。 -
maven-release-plugin
该插件用于使用 Maven 发布项目,节省了大量重复的手动工作。发布项目分两步进行:准备和执行。
基于需求,这里我们选用maven-release-plugin
来配置制品发布与管理。
-
首先配置插件到
<plugins>
中
这里锁定最新版本为3.0.1
,使用该版本首先要确保maven
版本在3.x
以上。
<!--项目配置...-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
</plugin>
</plugins>
</build>
<!--项目配置...-->
-
配置
<distributionManagement>
配置远端仓库发布URL来确保后续的操作可以被执行
<!--项目配置...-->
<distributionManagement>
<repository>
<!--这里请使用自己的配置-->
<id>airness-central</id>
<!--这里请使用自己的配置-->
<name>xxx-release</name>
<!--这里请使用自己的配置-->
<url>https://repo.xxx.xxx/artifactory/libs-release</url>
</repository>
</distributionManagement>
<!--项目配置...-->
构建与发布
Maven提供了18种命令,用于对工程进行各种操作,具体命令可参考Maven Release plugin – Plugin Documentation (apache.org)
下面列举了本次需要使用到的命令:
Goal | Description |
---|---|
release:perform | Perform a release from SCM, either from a specified tag, or the tag representing the previous release in the working copy created by release:prepare . For more info see https://maven.apache.org/plugins/maven-release-plugin/usage/perform-release.html. |
release:prepare | Prepare for a release in SCM. Steps through several phases to ensure the POM is ready to be released and then prepares SCM to eventually contain a tagged version of the release and a record in the local copy of the parameters used. This can be followed by a call to release:perform . For more info see https://maven.apache.org/plugins/maven-release-plugin/usage/prepare-release.html. |
release:prepare-with-pom | Prepare for a release in SCM, fully resolving dependencies for the purpose of producing a "release POM". |
本次演示仅包含交互式命令执行,但此插件是支持非交互演示的,以便Devops以流水线形式进行版本构建与发布,具体可参考Maven Release plugin – Performing a Non-interactive Release (apache.org)
在执行之前还需要进行相关账号用户名与密码的配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<username>devops</username>
<password>devops@2023</password>
<!--覆盖插件tag-->
<tagBase>${project.artifactId}-${project.version}</tagBase>
</configuration>
</plugin>
</plugins>
</build>
预演发布
因为发布插件会执行许多改变项目的操作,所以在大型发布之前或在新项目中做一次预演可能是明智的。
要做到这一点,就像要运行一个完整的发布版本一样,提交所有文件,然后运行
在预演之前需要先对项目version
进行修改,例如当前项目版本为1.0.3
,修改为1.0.3-SNAPSHOT
。
由于这里使用默认<projectVersionPolicyId>
,默认的VersionPolicy对常见的java版本控制方案进行版本比较和增量:建议的发布版本是没有-SNAPSHOT的当前版本,而建议的下一个开发版本是-SNAPSHOT的版本的小增量。形如x-SNAPSHOT
的版本命名。
当然也可手动覆盖maven的默认版本规则,这里演示覆盖使用语义化版本规则。
在插件配置中增加配置如下:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<projectVersionPolicyId>SemVerVersionPolicy</projectVersionPolicyId>
</configuration>
</plugin>
</plugins>
...
</build>
...
</project>
projectVersionPolicyId
支持以下种类的规则
-
default
: 增量版本规则, -
OddEvenVersionPolicy
: 偶数版本号表示发布版本,奇数版本号表示开发版本, -
SemVerVersionPolicy
: 语义化版本规则。
执行预演
mvn release:prepare -DdryRun
执行过程中终端会进行交互式提示,如无特殊需求,直接回车即可,执行结果如下:
![](https://img.haomeiwen.com/i15398882/624cf04bb0f8c66b.png)
执行完成后可以看到项目pom所在目录生成了一些文件。
![](https://img.haomeiwen.com/i15398882/d71cbc4747c2f73d.png)
在pom.xml.next
中可以看到下一个版本的pom文件version
已经被替换为1.0.4-SNAPSHOT
;在pom.xml.tag
文件中可以检查version
已经被替换为1.0.3
,且<scm>
中增加了<tag>union-common-1.0.3</tag>
。
检查确认无误即可进行版本准备,执行命令进行清理工作:
mvn release:perform -DdryRun
![](https://img.haomeiwen.com/i15398882/efc44329fad52336.png)
这将显示执行操作,然后清理项目,即删除上面创建的所有文件,项目将准备执行适当的发布。
在执行过程中可能存在问题,例如项目中存在未提交的变更,执行将会失败。
![](https://img.haomeiwen.com/i15398882/ebc1380915b0ae99.png)
准备发布
默认情况下,准备发布会经历以下发布阶段:
- 检查源代码中是否没有未提交的更改
- 检查是否没有快照依赖
- 将POMs中的版本从
x-SNAPSHOT
更改为新的发布版本(您将被提示使用该版本,并使用由配置为projectVersionPolicyId
的版本策略建议的默认值) - 转换POM中的SCM信息,以包括标签的最终目标
- 针对修改后的POMs运行项目测试(准备目标),以确认一切都在正常工作
- 提交修改后的POMs
- 用版本名标记SCM中的代码(这将被提示)
- 将POMs中的版本提升到一个新的值
y-SNAPSHOT
(这些值也会被提示,由配置为projectVersionPolicyId
的版本策略建议的默认值) - 最终运行项目的完成目标(从2.2开始)
- 提交修改后的POMs
以上基本我们都已经完成了操作,并且预演无任何异常,执行以下命令:
mvn release:prepare
若无任何异常情况将看到如下结果:
![](https://img.haomeiwen.com/i15398882/4353a3afd6828546.png)
并且在项目目录中会增加以下两个文件
![](https://img.haomeiwen.com/i15398882/d840e75792d421ec.png)
-
pom.xml.releaseBackup
:用于mvn release:rollback
命令执行使用,如在回滚时无此文件,回滚将会失败, -
release.properties
:记录本次scm版本相关配置与信息,供发布使用。
执行发布
默认情况下,执行发布会运行以下发布阶段:
- 从带有可选标记的SCM URL检出到
workingDirectory
(默认为/target/checkout
) - 运行
perform
Maven目标来发布项目(默认情况下是deploy
site-deploy
),最终激活发布配置文件
执行发布命令:
mvn release:perform
如无任何异常将看到如下结果:
![](https://img.haomeiwen.com/i15398882/5b9bea8a8cf93792.png)
- 此时检查工程pom文件可以观察到版本已经来到了
1.0.4-SNAPSHOT
, - 在已发布的maven仓库中检查
deploy
的制品版本为1.0.3
- 检查git仓库中的tag标签存在
1.0.3
的标签
![](https://img.haomeiwen.com/i15398882/615c51cd94be8155.png)
![](https://img.haomeiwen.com/i15398882/6823290a31e81023.png)
记录到这里就结束了,接下来说说坑点。
踩坑记录
首先叠甲,这里不针对任何其他文章,仅记录在我个人查找解决方案时的问题。
文章问题
首先我参考了maven scm 配置git_<connection>scm:git_马美丽的博客-CSDN博客,在配置git时采用了文章的配置,其中选用了jgit作为提供者实现,但在执行过程中,存在各种的java.lang.NoClassDefFoundError
,可能版本问题导致,补充了部分依赖也无法正常运行配置,因此放弃该文章的方案。
问题配置如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.0-beta-7</version>
<configuration>
<providerImplementations>
<git>jgit</git>
</providerImplementations>
<username>xxxusername</username>
<password>xxxxpasswrod</password>
<tagBase>${project.artifactId}-${project.version}</tagBase>
<goals>-f pom.xml deploy</goals>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-jgit</artifactId>
<version>1.9.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
该配置问题所在于这个maven-scm-provider-jgit
依赖,导致一些版本问题报错,这里直接采用官方示例的配置即可,在<scm>
中也仅需要配置<developerConnection>
即可
网友评论