背景
- 随着时间的推移,我们维护的代码仓库越来越多,基本上每个组都有快10个仓库,甚至远超这个数。基于目前的架构而言,我们每个代码仓库有一个
.gitlab-ci.yml, 此文件维护的是CI配置文件。 每个仓库 对应的在argocd项目里面有 2个[*.yaml]文件,这两个文件维护的是CD配置文件。 - 基于上述背景,我们一个代码仓库需要维护 有 3个
[*.yaml]配置文件,分别是1个CI配置文件,2个CD配置文件。 且 2个CD配置文件维护在argocd两个仓库,对应的一个是state环境argocd仓库,一个prod环境argocd仓库。 - 前端组每个项目有一个
lark文档,此文档上 维护CI /CD发布流程 & 该前端项目在 两个argocd仓库需要编辑的[*.yaml]文件 地址。(因为 CD 的时候需要变更tag, 所以需要维护stage环境的[*.yaml]发布文件 &prod环境的[*.yaml]发布文件)
痛点
- 我们每次
CI都是通过Merge request触发,因为每个 项目 配置的CI job不太一样,有的需要配置CDN, 有的需要启动SSR服务,造成的问题就是CI构建时间不确定。 我们没办法确定CI具体多久才能跑完,可能几分钟也可能十几分钟跑完。因为 我们需要拿着CI产生的tag去 进行CD。所以我们需要打开浏览器的页面 一直等待pipeline, 查看pipeline状态。 有时候我们比较忙的时候,一边编写代码,过几分钟来看一下CI状态, 看有没有构建完成 - 因为维护的仓库较多,我们可能 也记不清每次
CI完成的时候, 对应的业务代码仓库 在argocd上面 需要 CD 的[*.yaml]文件具体的文件名。我们可能要去查看一下 该项目的文档,确认一下需要编辑的 具体是argocd仓库 哪个[*.yaml]发布文件 - 新人加入团队,在 CI 完成的时候,不知道去哪里进行后续的 CD,因为不确定 具体要编辑
argocd仓库 哪个[*.yaml]配置文件
前端组作出的调整
-
我们通过在
CI完成阶段,通过curl发送一个json给lark机器人,明确告知CI已经完成。 这样,大家不需要一直刷新gitlab页面,只需要看群消息即可 查看pipeline构建状态 -
发送给
lark的消息卡片里面,包含了 此次构建产生的tag,这个tag就是我们去argocd仓库 编辑[*.yaml]的 重要变更。 且包含变更的仓库名字,方便我们确定哪个仓库在构建 -
发送给
lark的消息卡片里面,还包含本次CD需要编辑 的argocd仓库 具体的某一个文件绝对路径
-
上图中, 在
CI完成阶段,会发出一个消息到lark群,且明确告知tag版本号 和 仓库名称。 图中 点击我跳转到CD仓库链接 这个超链接文字,当用户点击 会 跳转到对应的 环境的argocd需要编辑的CD文件,基于不同的环境构建 可以跳转到不同的argocd仓库文件, 可以明确跳转到stage环境编辑的 文件 还是Prod环境编辑的文件 (图例: 区分了stage环境 和prod环境 需要编辑的 文件) -
我们直接点击 点击我跳转到CD仓库链接 这个超链接文字,会在浏览器自动定位到需要改动的文件,我们直接复制
tag号 ,选择Edit single file即可在浏览器直接编辑此文件,且自动创建一个分支
-
基于上述,我们在 业务代码 提完
Merge Request, 可以不关心pipeline状态,等着群里的消息。等群里有消息之后,点击lark消息卡片,复制对应的tag号,直接粘贴进CD文件,点击argocd merge按钮 即可 -
且 开发同学也不需要记住 具体 某个仓库 在
CD时,需要编辑argocd仓库具体 哪个[*.yaml]文件 -
新人入职之后也不需要问来问去,直接点击群消息编辑文件即可完成CD 工作
如何接入
- 在对应的
lark群, 添加机器人,添加机器人文档在这里 open.larksuite.com - CI 仓库接入,
LARK_WEBHOOK_URL是lark群的webhook地址。ARGOCD_STAGE_URL是需要编辑的argocd仓库CD文件,这里默认是stage环境文件
variables:
LARK_WEBHOOK_URL: 'xxx'
ARGOCD_STAGE_URL: 'test-url'
publish-job:
...
variables:
REQUEST_STAGE_JSON: |
{
"msg_type":"post",
"content":{
"post":{
"zh_CN":{
"title":"platform-web-ui 仓库 stage 环境 CI 执行成功",
"content":[
[
{"tag":"text","text":"请去 执行 CD 工作, CD tag 版本号是: $CI_COMMIT_SHORT_SHA"},
{"tag":"a","text":"点击我跳转到 测试环境 CD仓库链接, ","href":"$ARGOCD_STAGE_URL"},
{"tag":"text","text":"触发者: $GITLAB_USER_NAME"}
]
]
}
}
}
}
script:
- docker build -t $APP_REPO_NAME:$CI_COMMIT_SHORT_SHA .
- docker push --all-tags $APP_REPO_NAME
after_script:
- 'curl -X POST -H "Content-Type: application/json" -d "$REQUEST_JSON" $LARK_WEBHOOK_URL'
publish-job-prod:
variables:
ARGOCD_PROD_URL: 'prod--url'
REQUEST_PROD_JSON: |
{
"msg_type":"post",
"content":{
"post":{
"zh_CN":{
"title":"platform-web-ui 仓库 prod 环境 CI 执行成功",
"content":[
[
{"tag":"text","text":"请去 执行 CD 工作, CD tag 版本号是: $CI_COMMIT_TAG"},
{"tag":"a","text":"点击我跳转到 生产环境 CD仓库链接, ","href":"$ARGOCD_PROD_URL"},
{"tag":"text","text":"触发者: $GITLAB_USER_NAME"}
]
]
}
}
}
}
script:
- echo Docker-Image-Tag=${CI_COMMIT_TAG}
- docker build -t $APP_REPO_NAME:${CI_COMMIT_TAG} -f Dockerfile .
- docker push $APP_REPO_NAME:${CI_COMMIT_TAG}
after_script:
- 'curl -X POST -H "Content-Type: application/json" -d "$REQUEST_JSON" $LARK_WEBHOOK_URL'
3. 上面的 yaml 在 CI 期间明确区分了 不同的 job,分别对应的 stage 环境 job 和 prod 环境 job。默认给了一个 stage 环境需要编辑的 [*.yaml]发布文件,执行 prod job 在变更 [*.yaml]发布文件地址
4. REQUEST_JSON 就是发送给 lark 的消息体, CI_COMMIT_TAG gitlab 自带的
- 因为前端需要执行
build,俗称的 打包操作,所以这个发送 消息到lark,目前前端放在 打包完成之后发送,这样确保打包完成,在发送消息到lark, 所以放在after_script - 各个组的业务不一样,但是最终
CI构建完成都有一个docker镜像,可以在 构建docker镜像完成之后,触发CI通知到lark的机器人 - 至于
CD完成之后,需要不要同步到lark群,我觉得暂时没必要,因为CD很快,点击完merge按钮就 立马开始CD了