十、版本管理

还没写够呢,就结束了??怎么行,还有40多分钟,还可以记一篇,接着干!!!


任性.jpg

这篇我们来谈谈版本控制相关的东西,很实用的东西,快快藏兜里
在团队开发过程中,我们都应该使用maven的快照版本,maven根据快照版本机制解析这种特殊的版本。当项目需要发布时,我们需要把快照版本改成发布版本,这样唯一的定位到某一个构件,太泛了?没关系,且听我娓娓道来
项目开发过程中版本切换流程如下:

项目开发版本流程.png

SNAPSHOT表示的是一个开发过程,1.0,1.1,1.2表示项目发布的某一个时刻,在这个时刻项目是比较稳定的
快照版本要切换到发布版本应该满足以下几个条件:

  1. 所有自动化测试应当全部通过
  2. 项目没有快照版本的依赖存在
  3. 项目没有快照版本的插件依赖存在
  4. 项目包含的代码已经全部提交到版本控制系统中

项目发布与tag的关系

版本控制系统记录着代码的每一个变化,通常这些变化都被维护在master主干上,但是当项目发布的时候就应该用tag记录这一特殊时刻的状态,这样我们就可以快速的回到项目发布的那个tag时刻

maven版本号定义

1.3.4-beta-2版本为例作说明,它的含义是在一个重大的版本的第三个次要版本的第四次增量版本beta-2里程碑
以上面的例子来讲
1 - 表示重大版本更变,包括项目的结构,比如struct1structs2
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项目发布前准备配置,具体涉及:

  1. 检查项目是否有未提交的代码,存在则报错
  2. 检查项目是否有快照版本依赖
  3. 根据用户输入将快照版本替换为发布版
  4. pom中的scm信息更新为标签地址
  5. 基于修改后的pom执行maven构建
  6. 提交pom更变
  7. 基于用户输入为项目打发布版标签
  8. 将代码从发布版更变为新的快照版
  9. 提交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需要进行下面的配置

  1. 配置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
  1. 配置好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,支持windowslinux多种版本
这里我下载的是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`就发挥作用了

  1. 首先要确保的是你的pgp是可用的,也就是安装上且在命令行中可以访问
  2. 已经生成了密匙对
    为了修复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个小时,还有其他的事情要干呢,今天的笔记就到这里啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容