分享

基于Maven和SVN的项目版本管理

 yliu277 2019-08-26
流程demo.png

概述/背景

项目在开发过程中的版本,和在发布时的版本应该有所区别。发布的版本应该保证一个版本号对应唯一的内容。

之前遇到过一个项目,因为pom中的版本号没有-SNAPSHOT,导致两个环境依赖的项目虽然版本号相同,其实不是同一个。当时得出结论:相同的版本号只应该对应一个内容。

后来系统学习了下Maven,才具体了解到Maven体系中关于项目版本的标准,这里分享出来,希望大家在维护项目版本的时候有据可依。

另外,Maven中的版本管理需要结合软件版本控制工具使用,如Git、SVN等。虽然目前Git的使用已经很普遍了,我的工作环境使用的是SVN,就以SVN为例进行介绍。

Maven范围的版本和SVN范围的版本有不同的含义。前者面向的是项目,代码多次修改,项目的版本号可以不变;后者面向的是代码,每一次修改都是一个不同的版本。下文所说的版本一般是指项目的版本,特殊情况下会说明是代码版本。

快照版本和发布版本

快照版本对应开发过程中的版本,特点是快速的迭代更新,同样的版本号对应的是项目在一段时间内的开发过程。

发布版本应该是一个稳定的版本,它应该对应项目在某个时刻的状态 —— 它对应唯一的代码版本。

快照版本和发布版本.png

快照版本使用-SNAPSHOT后缀。

在Maven体系中的区别

Maven解析依赖的一般机制是:先从本地仓库找,找不到再从远程仓库找。换言之,在本地仓库找到了,就不会再去找远程仓库。

如果有2个项目并行开发,其中一个项目B依赖于另一个项目A。想象一下A和B都是持续更新的,项目B的开发人员如何确保能实时获取项目A的最新内容?

方案一:项目B的开发人员,每次构建之前都手动从本地仓库删除项目A,这样构建的时候就会从远程仓库下载最新的A。

方案二:项目B的开发人员,迁出项目A的代码,自己将A项目安装到本地仓库。

这两个个方案都不是Maven体系推荐的做法,方案二让项目B的开发人员不得不去搭建项目A的开发环境,而且项目A如果出现代码问题,项目B的开发人员可能就无能为力了。方案一增加了需要人工介入的工作量。

Maven使用SNAPSHOT来解决这个问题。如果项目依赖的是一个SNAPSHOT版本的依赖,Maven会定期从远程仓库获取最新的内容,默认频率是一天一次。也可以使用-U参数来强制更新。

所以,项目A使用SNAPSHOT版本,项目B就可以定期或者实时获取项目A的最新内容。

反之,如果项目A没有使用SNAPSHOT,项目B在第一次从远程仓库下载项目A到本地仓库之后,就一直使用本地仓库的这个备份。即使项目A更新了,项目B也不会知道,除非人工删除了项目A在本地仓库的副本。

所以,开发过程中的版本,应该使用SNAPSHOT版本。

发布版本的版本号约定

一般的情况下是下面这种结构:

<主版本>.<次版本>.<增量版本> 比如 1.1.2

各版本的作用如下:

  • 主版本
    项目的重大架构变更
  • 次版本
    较大范围的功能变化
  • 增量版本
    大量或紧急bug修复

这只是一个粗略的划分,大家可以根据自己的情况讨论每一个版本的使用场景。

通常主版本、次版本都会有,增量版本视情况而定。

更进一步的情况,可以添加里程碑版本,版本的结构如下:

<主版本>.<次版本>.<增量版本>—<里程碑版本>3.1.2-alpha-1

里程碑版本表示达成项目的某个里程碑,但通常不够稳定。大部分的公司应该不会使用里程碑版本,在此略过不表。

版本维护流程

主干、标签和分支

  • 主干
    无需多说
  • 标签
    标记某个有意义的代码版本,每一个发布版本都应该打一个标签。
  • 分支
    用于并行开发,通常用于已有版本的bug修复。

流程demo

流程demo.png
  1. 在主干进行1.0.0-SNAPSHOT的开发,开发完成之后提交修改的代码到主干。修改版本为1.0.0,再次提交,并添加标签。
  2. 随后将版本改为1.1.0-SNAPSHOT,提交。然后开始新一轮的开发,完成之后提交代码,修改版本为1.1.0,再次提交并打标签。
  3. 接着将版本号改为1.2.0-SNAPSHOT,提交,并开始新一轮的开发,在开发过程中1.1.0遇到一个紧急的bug,新建分支并1.1.1-SNAPSHOT,修改版本号为1.1.1-SNAPSHOT,提交并开始1.1.1-SNAPSHOT的开发。
  4. 1.1.1-SNAPSHOT开发完成,提交代码。修改版本号至1.1.1,提交并打上标签。此时可以及时把1.1.1发布出去。同步分支到主干。
  5. 随后,1.2.0-SNAPSHOT开发完成..

版本号的修改应该作为一次单独的提交。在发布的时候,项目版本号初始为SNAPSHOT版本,提交完所有的代码之后,修改版本号为发布版本,再提交;这次提交只修改版本号。
在开始新一轮的开发过程时,修改版本号为新的SNAPSHOT,然后立即提交而不是修改代码,版本号提交之后再开始开发,这次提交只修改版本号。

SVN相关操作

SVN简单介绍

SVN是一个很简单的版本控制工具,你可以下载VisualSVN Server来搭建自己的SVN服务器。

SVNServer存储结构.png

SVN的代码主要是在仓库里管理的,如上图demo就是一个仓库。完整的仓库目录结构如下:

仓库目录(Repositories) |-- 仓库1 |-- 项目1 |-- 主干(trunk) |-- 项目代码 |-- 标签目录(tags) |-- 标签1 |-- 项目代码 |-- 分支(branches) |-- 分支1 |-- 项目代码

可以看到,SVN的每一个标签或者分支,都是一份完整的代码副本

与仓库同一个级别的是用户等其他,可以控制对仓库的读写权限,具体没有深入研究,大家有需要自己研究下。

SVN操作

这里介绍上文版本维护流程中涉及到的操作。这里以命令的方式介绍,使用客户端界面的自己找一下操作的位置。

初始化项目

初始化项目首先要在VisulSVN Server的具体仓库下新建一个项目结构:

仓库-> 右键 -> 新建 –> Project Structure …

之后会生成一个标准的项目结构,包含了trunk、branches、tags,没有代码。

获取trunk的url地址,通过trunk -> 右键 -> Copy URL…

在本地项目所在目录,输入以下命令:

svn import -m 'initial import' . https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk

添加标签

版本号修改为发布版本之后,应该立即对当前状态添加一个标签:

svn copy https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/tags/1.0-RELEASE -m 'tag 1.0-RELEASE'

创建分支

svn copy https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/tags/1.0-RELEASE https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches/1.0.1-SNAPSHOT -m 'create branch 1.0.1-SNAPSHOT'

可以看到,添加标签和创建分支本质上都是复制。

切换分支

svn switch https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches/1.0.1-SNAPSHOT

合并分支

svn merge https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches/1.0.1-SNAPSHOT

合并分支的时候,pom文件中的版本号会有冲突。一般选择使用当前的版本号

Maven的release插件

在使用自动化的插件之前,建议先手动执行上面的流程,熟悉版本维护的流程之后,再去使用自动化插件。

配置pom文件

pom文件需要添加scm配置和插件配置。scm是Software configuration management的缩写。

project> ... scm> connection>scm:svn:https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunkconnection> developerConnection>scm:svn:https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunkdeveloperConnection> url>https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunkurl> scm> build> plugins> plugin> groupId>org.apache.maven.pluginsgroupId> artifactId>maven-release-pluginartifactId> version>2.5.3version> configuration> tagBase>https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/tagstagBase> branchBase>https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branchesbranchBase> configuration> plugin> plugins> build> project>

scm中配置了trunk的url,connection和developerConnection的值都以scm开头,之后跟着版本控制工具的类型svn。除了svn之外,Maven还支持其他的工具,如git。

插件里配置了标签的url和分支的url,其实如果项目的结构是标准的,trunk、tags和branches在同一级,可以不用配置这两项。

配置完之后,就可以通过mvn命令来自动发布、打标签、创建分支了。

自动发布

插件把发布分为2步,第1步执行上文中版本维护流程中介绍的发布流程,第2步使用mvn deploy部署构建至仓库。第1步由插件的prepare来完成,第2步由插件的perform目标来完成。

如果prepare执行失败,可以通过rollback目标来回滚,但是prepare生成的标签需要手动删除。

release:prepare

prepare负责预发布,在prepare之前,需要确保所有的修改都已经提交了,而当前的pom文件中的版本号还没有升级为发布版本号。

prepare所做的工作有:

  1. 检查系统是否有未提交的代码
  2. 询问用户发布版本号、标签和下一个开发版本号,并提供默认值。
    What is the release version for 'demo-version'? (com.hikvision.demo:demo-version) 1.2: :
    What is SCM release tag or label for 'demo-version'? (com.hikvision.demo:demo-version) demo-version-1.2: :
    What is the new development version for 'demo-version'? (com.hikvision.demo:demo-version) 1.3-SNAPSHOT: :
    
  3. 修改pom-根据用户的输入,将快照版本升级为发布版本
  4. 修改pom-根据用户的输入,将scm中的地址改为标签对应的地址
  5. 执行Maven构建
  6. 提交pom变更
  7. 根据用户的输入,新建标签
  8. 修改pom-根据用户的输入将version升级为新的快照版本,将scm信息更新。
  9. 提交pom变更。

上述的内容,正是我们在升级项目版本需要做的事情。

使用命令:mvn release:prepare

release:rollback

回退release:prepare的所执行的操作,并提交。但是历史记录会保留,创建的标签页不会删除。

使用命令:mvn release:rollback

release:perform

执行版本发布。是基于发布版本标签地址所对应的代码进行mvn deploy的结果。

使用命令:mvn release:perform

release:branch

自动创建分支。

使用命令:

mvn release:branch -DbranchName=1.1.1 -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false

参考

  1. 《Maven实战》 - 许晓斌

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多