一、什么是版本管理
首先,这里说的版本管理(version management)不是指版本控制(version control),但是本文假设你拥有基本的版本控制的知识,了解subversion的基本用法。版本管理中说得版本是指构件(artifact)的版本,而非源码的版本(如subversion中常见的rXXX,或者git中一次提交都有个sha1的commit号)。
比如我有一个项目,其artifactId为myapp,随着项目的进展,我们会生成这样一些jar:myapp-1.0-SNAPSHOT.jar,myapp-1.0.jar,myapp-1.1-SNAPSHOT.jar,myapp-1.0.1.jar等等。你可能会说,这很简单啊,我在POM中改个version,mvn clean install不就完了?但这只是表面,本文我将讲述,snapshot和release版本的区别,如何自动化版本发布(如果你的项目有几十个module,你就会觉得手工改POM来升级版本是很痛苦的事情),结合maven-release-plugin自动化发布的过程。
二、插件介绍
2.1 scm
soft configuration manager
<!-- scm配置,具体路径为待打包代码分支的根路径(trunk、branckes/v1.1.x、/tags/v1.1.5等) -->
<scm>
<!-- 用于发布的链接,用 HTTPS-->
<connection>scm:git:https://xxx</connection>
<!-- 用于指定开发者的链接,用HTTPS-->
<developerConnection>scm:git:https://xxx</developerConnection>
<!-- #git项目浏览器里的地址-->
<url>https://gitee.com/devtao/TestEveryThing.git</url>
<tag>v1.0.1</tag>
</scm>
2.1 maven-release-plugin
该插件的主要功能是通过mavn自动发布项目,减少人工干预。它依赖于POM的SCM信息。其主要包括的阶段1.准备阶段,2.执行阶段,3.回滚,4.清除。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tagBase>${project.artifactId}-${project.version}</tagBase>
<!-- tag分支的名称,project.version只包含版本,不包含SNAPSHOT后缀 -->
<tagNameFormat>v@{project.version}</tagNameFormat>
<!-- 升级子模块 -->
<autoVersionSubmodules>true</autoVersionSubmodules>
<!-- 是否生成release-pom.xml-->
<generateReleasePoms>false</generateReleasePoms>
<!-- 跳过单元测试 -->
<arguments>-DskipTests</arguments>
<!-- 执行目标,此句可省 -->
<goals>deploy</goals>
</configuration>
</plugin>
执行过程:
- mvn release:prepare mvn relesase:prepare前要保证所有的代码都已提交,Maven会进入交互模式:
# 询问需要发布release的版本,默认是将当前版本的“-SNAPSHOT去掉”
What is the release version for "TestEveryThing"? (com.devtao:test-everything) 1.1.2: :
# 询问tag标签,默认是release插件中tagNameFormat配置的,可以自定义更改
What is SCM release tag or label for "TestEveryThing"? (com.devtao:test-everything) v1.1.2: :
# 询问发布后snapshot版本的版本号,默认当前版本增加一位小版本号
What is the new development version for "TestEveryThing"? (com.devtao:test-everything) 1.1.3-SNAPSHOT: :
然后插件开始工作,主要进行的操作有:
- 替换父工程和子模块的pom.xml中的version字段为1.1.2;然后在本地git仓库当前分支Commit一个版本
- 在本地git仓库,创建一个tag,默认命名为XXX-1.1.2
- 再将父工程和子模块的pom.xml中的version字段替换成1.1.3-SNAPSHOT;然后本地git仓库当前分支再Commit一个版本
-
将以上本地版本push到git remote仓库。
-
mvn release:perform
主要进行的操作是将第一步生成的tag clone到本地,然后对其进行build和deploy|install操作,如果是deploy完成之后能看到私服中maven release仓库中已经有了对应的版本。
- mvn release:clean
这一步将上述过程中生成的临时文件删除。
2.2 distributionManagement
Maven仓库如果发布snapshot,只需要执行mvn clean deploy。
当上述稳定版本发布之后,将其加入到对应的maven仓库(nexus)中,需要distributionManagement了。
** 快照仓库和发布仓库:**
maven仓库分为两种:快照仓库(snapshot reposity)与发布仓库(release reposity).快照仓库用于保存项目的不稳定版本。发布仓库既保存稳定版本。一般发布版本需要在版本号后加入-SNAPSHOT(要大写)。其详细列子如下:
<distributionManagement>
<repository>
<!-- id 要和maven/conf/settings.xml中配置的一致-->
<id>myserver</id>
<url>http://127.0.0.1:18081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<!-- id 要和maven/conf/settings.xml中配置的一致-->
<id>myserver</id>
<url>http://127.0.0.1:18081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
三、实战演示
新建一个项目,完成以下操作:
- 自动升级版本号并打tag到git
- 发布一个快照版到nexus
- 发布一个稳定版到nexus
3.1 配置
scm配置git地址:
<!-- scm配置,具体路径为待打包代码分支的根路径(trunk、branckes/v1.1.x、/tags/v1.1.5等) -->
<scm>
<!-- 用于发布的链接,用 HTTPS-->
<connection>scm:git:https://gitee.com/xxxg.git</connection>
<!-- 用于指定开发者的链接,用HTTPS-->
<developerConnection>scm:git:https://gitee.com/xxxg.git</developerConnection>
<!-- #git项目浏览器里的地址-->
<url>https://gitee.com/xxxx.git</url>
<tag>v1.0.1</tag>
</scm>
build配置maven-release-plugin插件:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<tagBase>${project.artifactId}-${project.version}</tagBase>
<!-- tag分支的名称,project.version只包含版本,不包含SNAPSHOT后缀 -->
<tagNameFormat>v@{project.version}</tagNameFormat>
<!-- 升级子模块 -->
<autoVersionSubmodules>true</autoVersionSubmodules>
<!-- 是否生成release-pom.xml-->
<generateReleasePoms>false</generateReleasePoms>
<!-- 跳过单元测试 -->
<arguments>-DskipTests</arguments>
<!-- 执行目标是install还是deploy,install安装本地,deploy部署到nexus仓 -->
<goals>deploy</goals>
</configuration>
</plugin>
</plugins>
</build>
distributionManagement配置私服仓库地址:
<distributionManagement>
<repository>
<!-- id 要和maven/conf/settings.xml中配置的一致-->
<id>myserver</id>
<url>http://127.0.0.1:18081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<!-- id 要和maven/conf/settings.xml中配置的一致-->
<id>myserver</id>
<url>http://127.0.0.1:18081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
还需要在maven的setting.xml中配置nexus的认证
3.2 发布快照SNAPSHOT版本
构件定义:
<groupId>com.devtao</groupId>
<artifactId>test-everything</artifactId>
<version>1.1.8-SNAPSHOT</version>
<name>TestEveryThing</name>
<description>测试Everything</description>
执行mvn deploy进行发布,发布后可在nexus的snapshots仓中看到对应的构件。
3.3 发布稳定release版本
1)mvn release:prepare
- 把你项目打一个 release版本
- 在git的tag中打一个tag
- 自动升级 SNAPSHOT 并提交更新后的pom文件到git
例如当前version为1.5-SNAPSHOT,当执行mvn release:prepare时,会在git上面打一个1.5的release版本并打tag,并自动升级SNAPSHOT版本为1.6。
(注:一定要把本地代码都提交上去,否则会提示你“Cannot prepare the release because you have local modifications”)
2)mvn release:perform
- 去git的tag上拿代码
- 用tag上的代码,打一个 release版的 包
- deploy上你的maven私服
发布后可在nexus的release仓中看到对应的构件,没有加SNAPSHOT的即为release版本。