工作中可能会遇到这种场景,存在上游项目A和下游项目B,项目B的功能依赖项目A(比如B负责日志解析,A是日志描述语言代码),这种相互依赖的项目更新流程一般如下:
-
A项目更新,通知B项目开发人员进行更新
-
B项目开发人员收到通知,重新clone A项目代码到本地
-
将clone后的代码在本地重新编译打包生成可用的代码包
-
将代码包上传到线上服务器(或通过运维平台部署)
-
手动重启服务(如需要)
这个流程是这个场景下需要手动操作的必需的5个步骤。第4和第5步的自动化可以依赖运维平台的建设,基于.gitlab-ci.yml的配置实现自动化。本文主要讲述如何通过配置gitlab和.gitlab-ci.yml文件实现1-3步。
第一步:实现A项目更新触发B项目CICD
如果你拿这个问题去咨询chatgpt,那么它会给你类似下面这个答案
那么实现这个功能,又需要分解成两步
1.在B项目中生成触发器令牌
进入Gitlab B项目页面->Settings->CI/CD->Pipeline triggers
gitlab提供了3种使用pipeline triggers的方式,我们这里使用.gitlab-ci.yml,注意示例里提供的项目地址就是需要在配置文件里填写的地址,填写完触发器名称后,点击Add trigger即可获取B项目的触发器token
2.配置A项目的.gitlab-ci.yml文件
在获取了B项目的token后,就可以配置A项目的.gitlab-ci.yml了
这里我需要实现几个功能点
- 只有A项目指定的某些分支更新才触发B项目pipeline运行
- 触发B项目pipeline需要传入A项目更新的分支名,用于B项目拉取A项目指定分支
before_script:
- echo "The name of the branch is ${CI_COMMIT_BRANCH}" -- 这一步非必须,只未了在cicd时校验A项目的分支名
stages:
- trigger
trigger_pipeline:
stage: trigger
script:
- "curl -X POST --fail
-F token=ABCXXXXXX_1234_44 -- B项目触发器令牌
-F ref=master -- 要触发pipeline的B项目分支名
-F variables[PROTO_VERSION_DEV]=${CI_COMMIT_BRANCH} -- 触发pipeline传入A项目分支名参数
https://gitlab.example.com/api/v4/projects/YOUR_TARGET_PROJECT_ID/trigger/pipeline" -- 上一步提供的项目pipeline地址
only:
- /^.*abc$/ -- 只有A项目abc结尾的分支更新时会触发
tags:
- java
第二步:B项目CICD中自动clone A项目代码
通常情况下clone代码需要通过个人账密或SSH密钥认证,这两种方式都不适合用于打包机。因此我用到了gitlab中的项目访问令牌(Project access tokens).项目访问令牌允许通过API对一个特定的项目进行认证和授权,不同于个人访问令牌,项目访问令牌与特定项目关联,并用于控制对该项目资源的访问。它通常用于自动化、CI/CD流程、部署以及任何需要在没有人为直接交互的情况下与项目资源交互的场景。
下面时创建一个A项目访问令牌的步骤:进入Gitlab A项目页面->Settings->Access Tokens,设置token名称、过期日期、以及权限范围后即可创建一个可用的访问令牌。注意:在生成token后要记录下token内容,如果忘记录就无法查看到token内容,再生成一个新的即可。
生成A项目访问令牌后,就可以在B项目中添加bash脚本做代码拉取
#!/bin/bash
PROJECT_BRANCH_NAME=$xxx --分支名,由外部传参获取
PROJECT_ACCESS_TOKEN=xxxx
USERNAME=xxx -- 经过测试用户名可以随意配置,但建议使用有意义的字符
PROJECT_GIT_URI=xxx -- clone时候使用的路径
TARGET_DIR_NAME=xxx -- clone的目标文件夹,使用相对路径
git clone -b $PROJECT_BRANCH_NAME https://$USERNAME:$PROJECT_ACCESS_TOKEN@$PROJECT_GIT_URI $TARGET_DIR_NAME
第三步:配置B项目的.gitlab-ci.yml文件
由于不同语言编译打包的方式不同,这里不再给出统一的编译打包文件,只需要注意在编译打包前,执行第二步的bash脚本
script:
- bash ./bash脚本所在路径/xx.sh $PROJECT_BRANCH_NAME
测试效果
正确完成上面三个配置步骤后,即可向A项目推送代码测试效果。预期达到的效果为:
1.A项目代码推送完成后,开始执行CICD
2.B项目的CICD被触发,完成代码编译打包和部署
3.建议在B项目中的.gitlab-ci.yml中配置altert stage,增加通知模块。这样每次CICD完成都会发送通知