还没写够呢,就结束了??怎么行,还有40多分钟,还可以记一篇,接着干!!!
任性.jpg
这篇我们来谈谈版本控制相关的东西,很实用的东西,快快藏兜里
在团队开发过程中,我们都应该使用maven的快照版本,maven根据快照版本机制解析这种特殊的版本。当项目需要发布时,我们需要把快照版本改成发布版本,这样唯一的定位到某一个构件,太泛了?没关系,且听我娓娓道来
项目开发过程中版本切换流程如下:
项目开发版本流程.png
SNAPSHOT表示的是一个开发过程,1.0,1.1,1.2表示项目发布的某一个时刻,在这个时刻项目是比较稳定的
快照版本要切换到发布版本应该满足以下几个条件:
- 所有自动化测试应当全部通过
- 项目没有快照版本的依赖存在
- 项目没有快照版本的插件依赖存在
- 项目包含的代码已经全部提交到版本控制系统中
项目发布与tag的关系
版本控制系统记录着代码的每一个变化,通常这些变化都被维护在master主干上,但是当项目发布的时候就应该用tag记录这一特殊时刻的状态,这样我们就可以快速的回到项目发布的那个tag时刻
maven版本号定义
以1.3.4-beta-2版本为例作说明,它的含义是在一个重大的版本的第三个次要版本的第四次增量版本beta-2里程碑
以上面的例子来讲
1 - 表示重大版本更变,包括项目的结构,比如struct1与structs2
3 - 表示次要版本,通常意味着大范围的功能功能增加变化以及bug修复,但从总体架构来说没有发生变化
4 - 增量版本,一般表示重大的bug修复,比如1.4.0发布之后,用户反馈了一个非常重大的bug,需要立即修复,那么就需要针对1.4.0发布版开一个1.4.1-SNAPSHOT增量版本解决这个BUG并发布1.4.1版本,同时将更变同步到后面的版本开发分支中
beta-2 - 表示一个版本的里程碑,但是相比于发布版本,这种里程碑又是不稳定的
主干、标签、分支
主干(master),项目开发代码的主体,从项目开始到当前都处于活动状态,所有的分支最终都会合并到主干上,在主干中可以得到所有的历史更变
分支(branches),从主干某一个点分离出来的代码拷贝,用于独立主干进行实验性功能开发、bug修复等
标签(tag),用于标识主干某一个点的状态,通常在发布项目的时候使用
下面是一个项目开发流程,其中涉及了主干、分支、标签之间的相互使用:
项目从1.0.0-SNAPSHOT开始,经过长时间的开发,1.0.0发布版上线,接着进入1.1.0-SNAPSHOT开发,又经过长时间开发,1.1.0发布版上线,项目进入1.2.0-SNAPSHOT,但是在1.1.0版本中用户反馈了一个重大bug,需要及时修复,于是从1.1.0从独立出一个1.1.1-SNAPSHOT增量分支,用于修复这个bug,修复测试完成后1.1.1发布版上线,同时将1.1.1所做的更变同步到项目1.2.0-SNAPSHOT开发中,一段时间后发布1.2.0,项目继续进入1.3.0-SNAPSHOT开发中......
项目开发版本控制流程.png
自动化版本发布(发布项目)
maven提供了可以自动化发布版本的一系列插件,这样可以将项目发布这一复杂流程仅仅通过几个简单的maven命令就可以轻松搞定,其中maven-release-plugin就是专门干这事儿的插件
release插件有三个目标:prepare,rollback,perform用于项目自动发布
release:prepare项目发布前准备配置,具体涉及:
- 检查项目是否有未提交的代码,存在则报错
- 检查项目是否有快照版本依赖
- 根据用户输入将快照版本替换为发布版
- 将
pom中的scm信息更新为标签地址 - 基于修改后的
pom执行maven构建 - 提交
pom更变 - 基于用户输入为项目打发布版标签
- 将代码从发布版更变为新的快照版
- 提交
pom更变
release:rollback回退release:prepare所执行的操作,pom退回至release:prepare之前的状态,但是它并不会删除生成的标签,需要手动删除:
# 查看本地标签
git tag -l
# 删除本地指定的tagname标签
git tag -d tagname
# 删除远程仓库中生成的标签
git push origin --delete tag tagname
release:perform,执行版本发布,签出release:prepare生成的标签中的源代码,并在此基础上执行mvn deploy命令打包并部署到项目仓库中,所以这里需要为项目配置部署仓库
为了使用maven-release-plugin进行项目的自动发布,我们的项目pom需要进行下面的配置
- 配置scm版本控制信息
<project>
...
<!--配置项目发布信息-->
<scm>
<!--项目git地址,这里是只读的-->
<connection>scm:git:https://github.com/zl736732419/account-parent.git</connection>
<!--项目git地址,这里是可写的-->
<developerConnection>scm:git:https://github.com/zl736732419/account-parent.git</developerConnection>
<!--master分支的浏览器地址,这里需要点击分支master-->
<url>https://github.com/zl736732419/account-parent/tree/master</url>
<tag>HEAD</tag>
</scm>
</project>
url:是项目分支的地址,具体需要进入项目的分支页面
github分支页面.png
github分支页面1.png
- 配置好scm后,需要配置maven-release-plugin插件
<!--版本发布插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<!--配置tag,用于版本发布,mvn release:prepare,rollback,perform-->
<tagBase>https://github.com/zl736732419/account-parent/tags</tagBase>
<!--用于切换分支,修复bug mvn release:branch-->
<branchBase>https://github.com/zl736732419/account-parent/branches</branchBase>
<!--用于解决release与gpg之间的一个bug-->
<mavenExecutorId>forked-path</mavenExecutorId>
</configuration>
</plugin>
注意如果直接运行mvn release:prepare可能会遇到error: no such device or address错误,这需要提供仓库的访问权限,具体通过下面方式运行prepare命令
mvn clean release:prepare -Dusername=username -Dpassword=password -DautoVersionSubmodules=true
autoVersionSubmodules=true表示在运行过程中,子项目版本跟随父项目变化,如果没有配置这项参数,那么在运行过程中,会让用户自己手动确认每一个子项目的发布版本以及新的快照版本
在这个过程中我们已经在本地和远程仓库中创建了标签,可以去远程仓库项目标签页面进行查阅比如github:
自动部署后的标签.png
执行成功后,使用perform将项目部署到本地仓库
mvn release:perform -Dusername=username -Dpassword=password
通过这条命令,maven会将刚才release:prepare生成的标签对应的发布版源码进行打包部署,在项目中生成.jar -sources.jar,-javadoc.jar,后面两项是超级pom中设置的profile出发导致的结果:
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
上面的这种隐式设置maven官方不推荐这么做,可能在将来pom中的这项设置会被移除,所以建议在开发时显示设置出来,这样也更清晰
自动化创建分支(修改bug)
在上面提到的项目开发流程中,在1.1.0发布版出现了重大bug,于是需要独立出1.1.1-SNAPSHOT增量版本对bug进行修复,这一过程通过maven-release-plugin也可以做到自动化
需要使用到release插件的branch命令
为了使用branch命令,所以插件需要配置分支的信息
<!--版本发布插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<!--配置tag,用于版本发布,mvn release:prepare,rollback,perform-->
<tagBase>https://github.com/zl736732419/account-parent/tags</tagBase>
<!--用于切换分支,修复bug mvn release:branch-->
<branchBase>https://github.com/zl736732419/account-parent/branches</branchBase>
<!--用于解决release与gpg之间的一个bug-->
<mavenExecutorId>forked-path</mavenExecutorId>
</configuration>
</plugin>
mvn release:branch -DbranchName=1.1.1 -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false -Dusername=username -Dpassword=password -DautoVersionSubmodules=true
updateBranchVersions表示分支使用新的版本
updateworkingCopyVersion 表示不更新本地代码的版本,这时本地和远程已经生成了分支,但是需要手动切换分支
gpg签名(防盗改)
这里有两种方式,一种是通过手动方式进行gpg验证配置,还有一种是借助maven插件完成gpg自动配置
手动方式
gpg主要是用于检查当前用户下载的依赖包是否是完整的,在发布过程中,是否经过非法修改,全名为pretty good privacy
当从中央仓库中下载下来构建之后,你可能需要验证这些构件的合法性,比如是否是原版,没有被篡改过,要达到上面的验证功能,需要下载pgp,支持windows和linux多种版本
这里我下载的是windows版
gpg工作原理是首先通过gpg生成一对公、私密匙串、通过私匙对目标文件进行签名,生成.asc二进制的签名文件,将源文件与签名文件发给用户,同时将公匙发布到公钥服务器,用户得到签名文件与源文件,再到公钥服务器下载指定的公钥验证源文件是否一致
gpg官网地址:https://www.gnupg.org/download/index.html
gpg下载.png
设置gpg环境变量.png
如此gpg就可以正常使用了,我们可以在cmd中查看gpg版本进行验证
gpg --version
查看gpg版本.png
安装完成后我们在为目标文件进行签名时,还需要做一步:生成一对密匙串
gpg --gen-key
会提示输入自己的名称、邮箱、密码
公钥会被公开发布到公钥服务器上,所以请务必填写密码
生成密匙之后可以通过
gpg --list-keys
查看本机存在的公钥
查看本机gpg公钥.png
通过gpg --list-secret-keys查看私钥
查看本机gpg私钥.png
有了公钥和私钥之后,就可以对目标文件进行签名了
gpg -ab account-web.war
-a表示gpg创建ascII格式的输出,-b表示gpg创建一个独立的签名文件,因此会生成一个account-web.war.asc的签名文件
将公钥上传至公钥服务器
gpg --keyserver hkp://pgp.mit.edu --send-keys 49CFD654
这里的49CFD654是通过gpg --list-keys查看的公钥的id
将源文件account-web.war,与签名文件account-web.war.asc发给用户,用户需要对
源文件account-web.war进行签名验证,需要从公钥服务器中下载公钥
gpg --keyserver hkp://gpg.mit.edu --recv-keys 49CFD654
然后执行
gpg --verify account-web.war.asc对源文件签名进行验证,如果是没有被篡改的一致的文件,则会给出Good signature,否则给出Bad signature
插件方式
手动配置·pgp是一项啰嗦的事情,能不能在项目发布的时候自动签名,省去用户一切烦恼,这岂不是更爽,如此maven-pgp-plugin`就发挥作用了
- 首先要确保的是你的
pgp是可用的,也就是安装上且在命令行中可以访问 - 已经生成了密匙对
为了修复release插件与pgp插件结合是的一个bug,需要提供mavenExecutorId配置
<!--版本发布插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<!--配置tag,用于版本发布,mvn release:prepare,rollback,perform-->
<tagBase>https://github.com/zl736732419/account-parent/tags</tagBase>
<!--用于切换分支,修复bug mvn release:branch-->
<branchBase>https://github.com/zl736732419/account-parent/branches</branchBase>
<!--用于解决release与gpg之间的一个bug-->
<mavenExecutorId>forked-path</mavenExecutorId>
</configuration>
</plugin>
<project>
......
<profiles>
<!--在项目发布时对构建进行签名,这里是结合release使用-->
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
配置完成后,需要修改release插件执行目标perform的命令
mvn release:perform -Dusername=username -Dpassword=password -Darguments=-Dgpg.passphrase=pgp password
下面是运行后私服中存在的asc文件
image.png
好啦,又折腾了2个小时,还有其他的事情要干呢,今天的笔记就到这里啦












网友评论