项目版本管理的最佳实践测试
一、Git设置
1、添加公钥
打开 git bash (mac 下直接打开终端即可)
#: ssh-keygen -t rsa -C "邮箱"
#: cat ~/.ssh/id_rsa.pub
会生成:以ssh-rsa 开头的字符串,复制,贴到git公钥管理里面
测试是否可以通过公钥,免密拉取上传代码
#: ssh -T git@gitee.com (我这里用的gitee,对应的域名请自行切换)
成功:
Hi 柴梧炫 (DeployKey)! You've successfully authenticated, but GITEE.COM does not provide shell access.
Note: Perhaps the current use is DeployKey.
Note: DeployKey only supports pull/fetch operations
失败:
The authenticity of host 'gitlab.com (172.65.251.78)' can't be established.
ECDSA key fingerprint is SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw.
[图片上传失败...(image-3a059f-1590112256704)]
二、项目版本
在web开发的过程中,maven 除了作为项目的依赖管理之外,还处理着项目的版本控制
1、maven 的多项目的标准结构
1.1、如何组织项目
[MavenMultiProject]
├── module-1
│ ├── pom.xml
│ └── src
├── module-2
│ ├── pom.xml
│ └── src
├── module-3
│ ├── pom.xml
│ ├── module-3-1
│ ├── pom.xml
│ └── src
│ ├── module-3-2
│ ├── pom.xml
│ └── src
├── pom.xml
├── README.en.md
├── README.md
其中子模块也可以有其子模块
1.2、POM文件中的内容
1.2.1、parent pom.xml
父模块的pom文件一般存放公用的信息,以及定义标准,打包的格式:pom
除了上述的信息,一般不要引入其他的元素,因为一旦引入,子模块就会继承这些依赖,导致子模块的依赖被污染
<!-- 属性定义-->
<properties>
<java.version>1.8</java.version>
....
</properties>
<!-- 仓库的定义 -->
<distributionManagement>
<repository>
<id>local nexus</id>
<name>local nexus</name>
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>local nexus</id>
<name>local nexus</name>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<!-- 软件配置管理(项目git地址信息)如果git需要权限,则需要加入公钥,免密访问-->
<scm>
<connection>
scm:git:https://gitee.com/wuxuanchai_admin/m-v.git
</connection>
<developerConnection>
scm:git:https://gitee.com/wuxuanchai_admin/m-v.git
</developerConnection>
<url>
https://gitee.com/liang.liang/version-mangement-best-practices
</url>
<tag>HEAD</tag>
</scm>
<!--开发者-->
<developers>
<developer>
<name>wuxuan.chai</name>
<email>wuxuan.chai@gmail.com</email>
<organizationUrl>www.shuyun.com</organizationUrl>
</developer>
</developers>
<!--模块定义-->
<moudles>
<moudle>../moudle1</moudle>
</moudles>
<build>
<!--插件定义-->
<pluginManagement>
</pluginManagement>
</build>
<!--依赖定义-->
<dependencyManagement>
</dependencyManagement>
pom文件中可被继承的元素:
- 可继承的POM元素如下:
- groupId:项目组ID,项目坐标的核心元素
- version:项目版本,项目坐标的核心因素
- description:项目的描述信息
- organization:项目的组织信息
- inceptionYear:项目的创始年份
- url:项目的URL地址
- developers:项目的开发者信息
- contributors:项目的贡献者信息
- distributionManagement:项目的部署配置
- issueManagement:项目的缺陷跟踪系统信息
- ciManagement:项目的持续集成系统信息
- scm:项目的版本控制系统西溪
- malilingLists:项目的邮件列表信息
- properties:自定义的Maven属性
- dependencies:项目的依赖配置
- dependencyManagement:项目的依赖管理配置
- repositories:项目的仓库配置
- build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
- reporting:包括项目的报告输出目录配置、报告插件配置等
1.2.2、子模块
子模块是具体依赖的配置,一般以jar包的格式提供服务(使用springboot后,war包格式会被打成jar)
在子模块中,所有的version都不应该存在,要放在parent.pom 中进行统一管理
- 模块本身:version 继承父模块的versoin
- 所有依赖version,在父模块的dependencyManagement 元素中进行定义
<!-- 父模块的坐标-->
<parent>
</parent>
<!-- 当前模块的坐标,不需要写版本信息,会继承父模块的版本号-->
<artifactId>com.example</artifactId>
<name>demo</name>
<!-- 模块描述-->
<description>xxx</description>
<!-- 模块依赖列表-->
<dependencies>
</dependencies>
<!-- 模块的构建所需要的插件-->
<build>
</build>
1.3、语义化的版本号(Semantic Versioning)
1.3.1、版本号的格式
版本号的格式: 主版本号.次版本号.修订号
版本号的递增的规则:
1、主版本号:当你做了不兼容的API修改
2、次版本号:当你做了向下兼容的功能性新增
3、修订号:当你做了向下兼容的问题修正
先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
也就是说可以支持这种版本号:
4.7.5.202005
- 4 主版本号
- 7 次版本号
- 5 修订号
- 202005 编译元数据-编译日期
其他的语义描述:
- Alpha:内测版
- Beta:公测版
- Gamma:比较成熟的测试版,与即将发行的正式版相差无几
- RC:是 Release Candidate 的缩写,意思是发布倒计时,候选版本
- Stable:稳定版
1.4、版本性质: Snapshot 与Release
1.4.1、概念
Snapshot:快照,他是一个不稳定的版本,处于开发中的,经常变化的版本
Release:发行版,功能稳定的版本,将停止代码的更新,用于发行到生产环境
1.4.2、理想的流程
日常的开发
基于Snapshot的版本进行开发,snapshot版本会有一些特性
- 执行 mvn complie 时会去仓库中尝试拉最新打包,因为他可以被多次构建,使用时必须保证最新
- 可以被重复构建
版本发布
在发布版本的时候,我们需要做以下的几件事:
1、创建Tag分支,tag/v版本号(例如:tag/v0.0.1)
2、在仓库中构建发布包(release 的jar)
3、创建新的开发分支,升级本地pom文件版本,根据实际的需求提升版本号
- 如果hotfix发布,则:x.y.z -> x.y.z+1 例如:4.7.5 > 4.7.6
- 次版本发布, 则: x.y.z -> x.y+1.0 例如:4.7.5 > 4.8.0
- 大版本更新,则:x.y.z -> x+1.0.0 例如:4.7.5 > 5.0.0
4、非hotfix版本发布,还需要创建hotfix分支,用于以后修复
现有的项目如何做?
插件管理:maven-release-plugin
插件地址:http://maven.apache.org/maven-release/maven-release-plugin/
parent pom配置文件配置:
<scm>
<!-- git项目地址可以用SSH 也可以用 HTTPS的-->
<connection>scm:git:https://gitee.com/wuxuanchai_admin/m-v.git</connection>
<!-- #git项目地址可以用SSH 也可以用 HTTPS的-->
<developerConnection>scm:git:https://gitee.com/wuxuanchai_admin/m-v.git</developerConnection>
<!-- #git项目浏览器里的地址-->
<url>https://gitee.com/liang.liang/version-mangement-best-practices</url>
<tag>HEAD</tag>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<!-- tag分支的名称,project.version只包含版本,不包含SNAPSHOT后缀 -->
<tagNameFormat>v@{project.version}</tagNameFormat>
<!-- 升级子模块 -->
<autoVersionSubmodules>true</autoVersionSubmodules>
<!-- 跳过单元测试 -->
<arguments>-DskipTests</arguments>
<!-- 执行目标,此句可省 -->
<goals>-f pom.xml deploy</goals>
</configuration>
</plugin>
</plugins>
</build>
如何使用??
1) release:branch(创建分支 )
创建的分支是用于hotfix修复的基础分支,在第一次创建次要版本是,要一并创建,以后的修改都基于此分支,后续如果有需要的hotfix来修复问题,则基于此分支创建一个新的分支hotfix-xxx,然后提交代码后,将release一个hotfix的版本:x.y.z+1(z表示当前的修订号)
命令:
mvn release:branch -DbranchName=0.2.x -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false
命令含义:
- -DbranchName=0.2.x:创建一个叫 0.2.x 的分支
- -DupdateBranchVersions=true :分支会升级版本号,如果当前的版本号为0.0.1-snapshot,则新的分支版本号为: 0.0.2-snapshot
- DupdateWorkingCopyVersions=false 当前工作空间的pom文件不做更改,方便后面的release操作
2) release:prepare(预处理,升级pom-version)
预处理阶段,release插件会:
- 执行一次打包过程
- 在git仓库里面创建好Tag分支
- 升级pom文件版本,并提交到本地仓库(此处不会更改远程仓库的分支)
mvn release:prepare
在默认的情况下,他是一个交互式的命令,有如下问题需要确认:
What is the release version for "mvc-test"? (com.fruits.mvc:mvc-test) 0.1.15: :
What is SCM release tag or label for "mvc-test"? (com.fruits.mvc:mvc-test) v0.1.15: :
What is the new development version for "mvc-test"? (com.fruits.mvc:mvc-test) 0.1.16-SNAPSHOT: :
//要发布的版本是哪一个?默认当前版本
//要打的tag叫什么?现在的样子
//创建一个新的开发版本吗?默认当前版本+1 修订(此处我们可以手工改成 子版本号更新)
执行了 release:prepare命令后,在git仓库中,我们可以看到一个叫:v0.1.15的tag被创建,这操作是可以回滚的,插件在项目里面创建了一个,pom.xml.releaseBackup的文件,用于回滚pom.xml,同时还会生成:release.properties 里面会记录release版本的属性
3) release:rollback(回滚)
Release:prepare 阶段都是进行了本地的提交,因此可以进行回滚,但tag分支必须手工删除,插件不能帮你删除已经创建好的本地Tag
除此之外,可以还行发布预览:
mvn release:prepare -DdryRun=true
干跑会生成预览文件:
pom.xml.next
pom.xml.releaseBackup
pom.xml.tag
release.properties
但是不会提交。
4) release:perform (执行)
执行命令,会在release仓库里面构建发布包
可能碰到的问题
release:rollback不会回滚git的tag,需要手动删除tag
maven配置的优先级(idea下) pom.xml>.m2/setting.xml>setting.xml
pom.xml 发生改变,无法执行release:prepare
私服的设置和maven的配置文件如果配置不正确,无法执行命令
效果
私服中release的jar:
私服中的snapshot的jar:
git中的tag:发布release后创建的tag分支