还没写够呢,就结束了??怎么行,还有40多分钟,还可以记一篇,接着干!!!
这篇我们来谈谈版本控制相关的东西,很实用的东西,快快藏兜里
在团队开发过程中,我们都应该使用maven
的快照版本,maven
根据快照版本机制解析这种特殊的版本。当项目需要发布时,我们需要把快照版本改成发布版本,这样唯一的定位到某一个构件,太泛了?没关系,且听我娓娓道来
项目开发过程中版本切换流程如下:
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
开发中......
自动化版本发布(发布项目)
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
:是项目分支的地址,具体需要进入项目的分支页面
- 配置好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
:
执行成功后,使用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
就可以正常使用了,我们可以在cmd
中查看gpg
版本进行验证
gpg --version
安装完成后我们在为目标文件进行签名时,还需要做一步:生成一对密匙串
gpg --gen-key
会提示输入自己的名称、邮箱、密码
公钥会被公开发布到公钥服务器上,所以请务必填写密码
生成密匙之后可以通过
gpg --list-keys
查看本机存在的公钥
通过gpg --list-secret-keys
查看私钥
有了公钥和私钥之后,就可以对目标文件进行签名了
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文件
好啦,又折腾了2个小时,还有其他的事情要干呢,今天的笔记就到这里啦