GitLab-CI + Maven 版本自动发布流程

本贴最后更新于 2019 天前,其中的信息可能已经斗转星移

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 编排管理。应用的发布流程,从类型上我们可以分为两个阶段:

  1. 第一阶段,触发“正式版本发布”流程,完成版本号升级,正式版本发布到 Nexus 私服的操作。
  2. 第二阶段,触发“生产环境部署”流程,完成生产环境的打包或者安装包下载、推送、数据库脚本升级、应用升级并重启等操作。

以上两个流程中,第二阶段的“生产环境部署”流程依赖第一阶段的正式版发布。因此版本发布的流程触发只需要提供“正式版本发布”这个流程的触发控制即可。按照上一节中的描述,“正式版本发布”流程会在生产分支(Product)上打标签,这个 tag 指向了正式版本,并且可以作为 Deploy-Pipeline 部署流水线的触发条件。以下对这两个 pipeline 的配置详细描述。

(一)使用 Trigger 触发生产分支的“正式版本发布”流程

  1. 参照模板编写 gitlab-ci.yml 配置文件,定义 ReleaseVersion 流程。如下:
    before_script:

    固定变量。(不能修改)

    判断是否是自动提交的 commit

    • git_message=(cd {CI_PROJECT_DIR};git log --pretty=format:'%cn#%cd#%s' -1)
    • commit_user=(echo "{git_message}"|cut -d# -f1)
    • commit_message_ref=(echo "{git_message}"|cut -d# -f3|awk '{print $4}')
    • if [[ "{commit_user}" == "ReleaseVersionCommit" && "{commit_message_ref}" != "{CI_COMMIT_REF_NAME}" ]];then export is_robot="true";echo "{is_robot}";fi

    判断是否符合上线条件

    • if [[ "{commit_user}" != "ReleaseVersionCommit" ]];then export do_not_deploy_prod="true";echo "{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 发布正式版本结束 ###########################

    |

  2. 为项目开启 Trigger 触发 pipeline 的功能,设置 token。操作步骤:GitLab 项目左侧管理菜单中”Settings -> CI/CD”,在右侧工作区打开”Pipeline triggers”右侧的”Expand”。点击”Add trigger”或者直接使用已有的 Token。如下图:

  3. 使用命令行 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。

  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    14 引用 • 7 回帖
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    185 引用 • 318 回帖 • 353 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...