GitLab-CI + Maven 版本自动发布流程
九月 18, 2018
GitLab-CI + Maven 版本自动发布流程
微服务架构的流行,为项目大军团作战中各个小团队协作提供了新的方式。项目被拆分成若干个服务,每个服务独立开发演进,服务之间又存在依赖关系。这种情况下需要遵照严格的版本策略,确保各个服务之间调用到正确的版本。快速迭代的开发模式,使得版本发布成为了家常便饭,几日一个版本甚至一日几个版本都是可能的,因此需要在持续集成流程中加入版本自动发布的功能,将自动化发布流程中最后的人工干预去掉。
目前项目大部分是 Java 项目,使用 Maven 管理项目版本,Maven 提供了版本号的管理约定,我们可以使用 Maven 的插件 org.codehaus.mojo:versions-maven-plugin
进行手工的版本管理,使用 Maven 官方插件 org.apache.maven.plugins:maven-release-plugin
进行自动版本发布。
一、启用 Maven 插件
在项目根目录上 pom.xml 中,增加如下配置:
<current-project.scm.url>https://git.cnbss.net/youre-group/your-projectcurrent-project.scm.url>
properties>
${current-project.scm.url}url>
scm:git:${current-project.scm.url}.gitconnection>
scm:git:${current-project.scm.url}.gitdeveloperConnection>
HEADtag>
scm>
releasesid>
Internal Releasesname>
${default.deploy.nexus.releases.url}url>
repository>
snapshotsid>
Internal Snapshotsname>
${default.deploy.nexus.snapshots.url}url>
snapshotRepository>
distributionManagement>
org.codehaus.mojogroupId>
versions-maven-pluginartifactId>
2.3version>
plugin>
org.apache.maven.pluginsgroupId>
maven-release-pluginartifactId>
2.5.3version>
tags-v@{project.version}tagNameFormat>
trueautoVersionSubmodules>
configuration>
plugin>
plugins>
build>
|
说明:
scm
节点定义 maven-release-plugin 插件使用的提交代码和 tags 的代码库配置信息;distributionManagement
节点定义mvn deploy
所需的私有仓库配置信息;versions-maven-plugin
插件用于手工修改版本号使用;maven-release-plugin
插件用于 Maven 自动发布版本使用,其中tagNameFormat
定义了正式发版后的 tag 命名规则。
二、配置版本发布者信息
release 插件的使用,涉及到需要生成提交,推送到 gitlab 服务的操作。所以需要配置具有提交权限的用户。用户信息保存在 ~/.m2/settings.xml
中的 settings.servers.server
节点的信息,其中 git.cnbss.net
取值和前文中 GitLab 的域名保持一致,示例中隐去了 password 的明文,实际项目应用时填写具有项目提交权限的用户名密码。示例:
git.cnbss.netid>
ReleaseVersionCommitusername>
***************password>
server>
servers>
settings>
三、正式版本发布流程
我们以 GitFlow 的研发流程为例,生产版本以 Product 分支管理,开发中的版本以 Develop 分支管理。以下版本变更流程图描述了生产版本发布的操作过程(其他研发流程类似)。
- 开发分支测试通过,代码封版,此时的版本号是
1.2.0-SNAPSHOT
; - 开发分支(Develop)合并到生产分支(Product),生产分支的最新提交版本号是
1.2.0-SNAPSHOT
; - 生产分支(Product)的版本号变更为
1.2.0
正式版本,生成新的提交; - 生产分支(Product)在正式版本的提交上打标签
tags-v1.2.0
; - 生产分支(Product)的版本号变更为
1.2.1-SNAPSHOT
,将最后一位修订版本升级,加上-SNAPSHOT
后缀,生成新的提交,开启下个版本的开发; - 生产分支(Product)合并到开发分支(Develop),开发分支的最新版本号变更为
1.2.1-SNAPSHOT
,当前版本自动发布流程完成。
四、版本发布融合到自动化运维流程
自动化运维流程使用 GitLab-CI 编排管理。应用的发布流程,从类型上我们可以分为两个阶段:
- 第一阶段,触发“正式版本发布”流程,完成版本号升级,正式版本发布到 Nexus 私服的操作。
- 第二阶段,触发“生产环境部署”流程,完成生产环境的打包或者安装包下载、推送、数据库脚本升级、应用升级并重启等操作。
以上两个流程中,第二阶段的“生产环境部署”流程依赖第一阶段的正式版发布。因此版本发布的流程触发只需要提供“正式版本发布”这个流程的触发控制即可。按照上一节中的描述,“正式版本发布”流程会在生产分支(Product)上打标签,这个 tag 指向了正式版本,并且可以作为 Deploy-Pipeline 部署流水线的触发条件。以下对这两个 pipeline 的配置详细描述。
(一)使用 Trigger 触发生产分支的“正式版本发布”流程
-
参照模板编写
gitlab-ci.yml
配置文件,定义ReleaseVersion
流程。如下:
before_script:固定变量。(不能修改)
判断是否是自动提交的 commit
- git_message={CI_PROJECT_DIR};git log --pretty=format:'%cn#%cd#%s' -1)
- commit_user={git_message}"|cut -d# -f1)
- commit_message_ref={git_message}"|cut -d# -f3|awk '{print $4}')
- if [[ "KaTeX parse error: Expected 'EOF', got '&' at position 42: …VersionCommit" &̲& "{commit_message_ref}" != "{is_robot}";fi
判断是否符合上线条件
- if [[ "{do_not_deploy_prod}";fi
stages:
- releaseVersion
- deploy
########## releaseVersion 发布正式版本 #############################
发布分支不能直接提交,只能接受 merge 操作
1. 如果是 master 发布,分支开发模式,在发布分支 master 出现 merge 的时候触发
2. 如果是 master 开发,分支发布的 gitlab 模式,需要使用 trigger 触发 master 上执行发布 job
release_version:
stage: releaseVersion
script:判断是否是自动提交的 commit
- echo "${is_robot}"
- if [[ "${is_robot}" == "true" ]];then echo "机器账户提交,跳过部署!";exit 0;fi
- git fetch --all
- set -x;git checkout ${CI_COMMIT_REF_NAME};set +x
- set -x;git reset --hard origin/${CI_COMMIT_REF_NAME};set +x
- git clone -b master https://ronly:Ypsi*********VaxhF3V@git.cnbss.net/${CI_PROJECT_NAMESPACE}/inventory.git;
release:prepare 实现去掉-SNAPSHOT 提交,按照配置打 tag,升级为下一个 SNAPSHOT 版本,推送 tag 和 commit 到远程仓库
- mvn -s inventory/settings.xml release:prepare --batch-mode -Darguments="-DskipTests"
release:perform 确认版本发布,checkout 出来 tag 对应的版本,执行 deploy 到 nexus 私服操作
- mvn -s inventory/settings.xml release:perform --batch-mode -Darguments="-DskipTests" -DuseReleaseProfile=false
tags 指定执行 job 的 runner 对应的 tags 名称
tags:
- QCLOUD
only:
prod 发布模式,有到 prod 的 merge 触发发布动作
#- prod
master 主干开发,分支发布模式下,此处取值可选:web,表示在 gitlab 界面上点击“Run pipeline”按钮触发,triggers,表示使用 trigger 触发:
- trigger
############ releaseVersion 发布正式版本结束 ###########################
|
-
为项目开启 Trigger 触发 pipeline 的功能,设置 token。操作步骤:GitLab 项目左侧管理菜单中”Settings -> CI/CD”,在右侧工作区打开”Pipeline triggers”右侧的”Expand”。点击”Add trigger”或者直接使用已有的 Token。如下图:
-
使用命令行
curl
工具或其他 Web 请求发起工具,使用 token 发起触发流程执行的 Trigger。命令行示例如下(其中token
参数的取值需要使用对应项目中的值,ref
参数的取值填写用于发布正式版本的分支名,projects/154/trigger/pipeline
中的 154 是对应项目的 ID):curl -X POST -F token=3799xxxxxxxxxxxxxxxxxxxxxxx4cd -F ref=master https://git.cnbss.net/api/v4/projects/154/trigger/pipeline
说明:选用 Trigger 触发的原因是“正式版本发布”这个流程具有人工操作的属性,不能通过流程或规则定义实现自动触发。手工触发安全性较好,具有良好权限控制的就是 Trigger 触发,且后续此触发功能可以使用项目版本发布管理平台进行统一管控。
(二)使用 tag 触发生产分支的“生产环境部署”流程
为你的项目设置“生产环境部署”流程,这个流程根据需要自己定制即可,一般可参考 DevOps/ci_template 提供的示例。针对 tag 触发“生产环境部署”的特殊配置,说明如下:
deploy_service:
stage: deploy
script:
- git clone -b master https://ronly:Ypsi*********VaxhF3V@git.cnbss.net/${CI_PROJECT_NAMESPACE}/inventory.git;
- mvn -DskipTests=true -U -s inventory/settings.xml clean deploy;
tags: - QCLOUD
only: - /^tags-v([0-9]+).([0-9]+).([0-9]+)/
when: manual
except: - trigger
- prod
脚本说明:
deploy_service.only
配置定义仅符合条件提交才触发 pipeline。取值/^tags-v([0-9]+).([0-9]+).([0-9]+)/
是正则表达式,以”tags-v”开头的分支名才会触发当前 Job。deploy_service.when=manual
配置定义当前 Job 需要手工执行。deploy_service.except
配置项定义需要排除的触发条件,取值是数组。deploy_service.except=trigger
说明 trigger 触发时不触发当前部署的 Job。deploy_service.except=prod
说明 prod 分支中的提交不触发当前部署的 Job。
通过以上排除的规则定义,避免在不需要的时候触发生产环境部署 Pipeline。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于