字节流的博客

极狐 Gitlab CI/CD 之模板复用

极狐 Gitlab CI/CD Pipeline Infograph

由于秉承着 easy 大佬的能全自动的全自动,不能全自动的半自动的理念(🙃),使用极狐 Gitlab 的时候,CI/CD 那自然是必不可少。一来可以避免由于人工失误产生一些问题,毕竟是人他总是会犯错(从不犯错的他不是人),还是机器更忠诚可靠。二来可以趁机器给你干活儿期间,起来伸个懒腰接壶茶,对日渐僵硬的颈椎也是有好处的,回来看 pipeline 他已经全绿勾了,你啜着绿茶,巴适~

但随着微服务的流行,该拆不该拆的服务,都拆开了。并且采用的多仓库的代码存储模式,加一个服务,就加一个仓库,这个仓库再加一个 .gitlab-ci.yml 文件。这么个模式倒没啥问题,前端和后端各自的 CI/CD 脚本大同小异。从别的仓库 copy 一个过来 CI 文件,改吧改吧变量,甚至改都不用改,拎过来就可以直接用了。

直到有一天,客户提出了私有部署的需求,所有的服务需要在客户的云环境复刻一套,并且和我们的生产保持同步的更新频率。这就不好玩了😯,那几十个代码仓库,每个.gitlab-ci.yml都得改一遍,并且需要改的地方也基本上都一样,无脑复制粘贴就可以。但,如果再来个客户,也要加一套环境呢?并且作为程序员,怎么能干这么 ↓ 作的事儿呢?琢磨着看看官方文档,有没有好的方案可用,让我发现了有 include 这么一个关键字,是这么描述的:

使用 include 在 CI/CD 配置中包含外部 YAML 文件。 您可以将一个长的 .gitlab-ci.yml 文件拆分为多个文件以提高可读性,或减少同一配置在多个位置的重复。
您还可以将模板文件存储在中央仓库中并将它们包含在项目中。

基本上的逻辑就是相当于 C 语言的 include ,或者其他语言的 import 来引入其他封装好的模块。相同的逻辑只写一次,封装个方法来引用,就不用复制粘贴了。说搞就搞,参考着官方文档对原来的一个比较大的 CI 文件,拆拆补补调调整整,做了一个模板仓库(😔 又多了一个),大致这样的结构:

1
2
3
4
5
6
7
8
.
├── common # common scripts
│ ├── build.yml # build scripts
│ ├── deploy.yml # deploy scripts
│ ├── lint.yml # code lint scripts
│ └── ut.yml # unit tesing scripts
├── be.yml # backend ci template
└── fe.yml # frontend ci template

其中 common 目录包括前后端通用镜像构建、代码 lint 和各自单元测试的脚本等。

fe.yml内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stages:
- es-lint
- ut
- build
- deploy-dev
- deploy-sit
- deploy-prod

include:
- project: 'jihu-show/ci-template'
file: '/common/es-lint.yml'
- project: 'jihu-show/ci-template'
file: '/common/ut.yml'
- project: 'jihu-show/ci-template'
file: '/common/build.yml'
- project: 'jihu-show/ci-template'
file: '/common/deploy.yml'

其中共有 6 个 stage,通过 include 指令,引入 3 个文件,通过这样组合搭配,一个完整的前端 CI 流程就跑起来了:

Pipeline

因为我们采用 main-dev 分支模型进行开发,代码 push 到 dev 分支后,会自动执行上图的流程,并把构建结果部署 dev 环境。

dev 代码 mergemain 分支后,会自动执行下图流程:

Pipeline

会自动把构建结果部署 sit 环境。当在 sit 测试没问题后,手动点击下 deploy-prod 即可完成部署生产环境。后端项目也基本相似,就不再示例了。需要的话,可参考文末的仓库链接。

👌 这样基本上就搞定啦,可以说是一劳永逸啊 ^_^|||

(哦,几十个代码仓库还得挨个改 .gitlab-ci.yml 文件去,采用 include 模式… 👋


相关链接

  1. CI 模板仓库地址:ci-template
  2. 后端示例项目仓库地址:project-be
  3. 前端示例项目仓库地址:project-fe
Thanks! 😊