Gitlab CI 进阶之共享 CI 库
一 背景
目前对于gitlab CI是在单独的项目下创建.gitlab-ci.yaml文件来定义部署过程,对于共同的一些步骤比如构建部署等,在每一个gitlab CI文件中编写,为了能够使代码在不同项目复用,将其存放在一个专门用于构建的gitlab CI仓库,其他项目想要使用该stage可以引用公共的CI文件,后续仅需要维护公共的gitlab CI库即可,但是需要公共CI库将一些特征数据提取出来,由 CI 确保代码风格一致,并执行单元测试和静态检查等。由于仓库数量众多,如何有效地组织和管理 CI 配置成了问题。经过长时间的探索和优化,我整理了一些经验,希望对你有所帮助。公共库需要较好的扩展性与兼容性。
二 基础语法解析
在共享仓库中将单个操作抽象为一个原子jobs,单独写在一个文件中,这样可以在模版中引用这些原子jobs,根据不同的变量,tags的runner,及branch可以任意组合成需要的模版。对此主要用到两个Gitlab CI中的关键字,include和extends。
include和extends是配合使用的,include为引用项目中的yaml文件,extends,为继承文件中的具体jobs
2.1 Include
2.1.1 功能
利用include
关键字能够引用其他外部的yaml文件,这有助于将CI/CD配置分解为多个文件,并提高长配置文件的可读性。
可以将通用的一些操作,抽象为单个原子jobs,编写共享gitlab ci库,在模版中incloud这些原子操作jobs,来组合成模版。
在单个的项目中,可以include共享库中预定于好的模版,仅重写项目中的一些变量即可。
2.1.2 方式
include加载其他外部yaml文件,文件名称扩展必须为.yaml
或.yml
。
include支持加载方法包含以下四种:
| Method | Description |
| :----------------------------------------------------------- | :----------------------------------------------------------- |
| local | Include a file from the local project repository. |
| file | Include a file from a different project repository. |
| remote | Include a file from a remote URL. Must be publicly accessible. |
| template | Include templates which are provided by GitLab. |
2.1.3 示例
include:local:
include:本地包含与.gitlab来自同一存储库的文件-词yml. 它是使用相对于根目录(/)的完整路径引用的。
您只能在配置文件所在的同一分支上使用Git当前跟踪的文件。换句话说,当使用包括:本地,确保两者都是。gitlab-词yml本地文件在同一个分支上。
或者简短的方法:
include:file
要在同一个GitLab实例下包含来自另一个私有项目的文件,请使用包括:文件。使用相对于根目录(/)的完整路径引用此文件。例如:
也可以指定ref.
include:remote
Remote用于包含来自不同位置的文件,使用HTTP/HTTPS,通过使用完整的URL引用。远程文件必须通过简单的GET请求公开访问,因为远程URL中的身份验证架构不受支持。例如:
include:template
利用template可以加载gitlab上已经预置的一些模版,
https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates
也可以引用多个模版
2.2 Extends
2.2.1 功能
可以把一些公共属性或者方法(主要是Script)也进行统一管理。将其抽离在单独的jobs中,在具体的stages中进行继承。
extends定义使用extends的作业将从中继承的条目名。
它的使用相较于yaml anchors,更灵活和更易读。
2.2.2 示例
在上述的示例中,rspec 的job内嵌了.tests模版的job,gitlab将要执行深度合并,结果为:
三 实战
3.1 项目结构
将原子操作抽象成单个jobs
在templates中定义后端私有化几saas 的CI模版,在其中引用
3.2 CI jobs及模版
3.2.1 jobs
在jobs中定义原子操作,在此实例build
我们可以其中定义build和upload多个操作,在其中不定义stage/branch/tags等。
3.2.2 templates
在templates中定义不同场景的CI模版,在其中可以自己根据项目是私有化部署或是saas 来include不同的jobs文件,并继承其中具体jobs。
在自定义模版中,主要包含四个部分:
导入jobs的yaml文件
定义全局就stage中变量
定义模版运行CI的stage
实现具体stage,管理具体stages,继承jobs。
在此义deploy来示例:
在该模版中利用stage中的image/tags/runner/branch进行灵活组合,从而实现适应不同场景的CI。
至此共享CI模版库就已经创建完成,需要在具体的项目中进行应用。
3.3 项目中引用
在具体的项目中引用非常简单,只需要在代码仓库中编写.gitlab-ci.yaml
即可实现CI继承,在此我们示例一个python的后端saas项目,继承backend的saas模版。
可以看到在具体的项目中集成gitlab CI引用模版库非常的简单,只用引用文件,并根据项目来定义变量即可完成集成。
四 注意事项
4.1 引用注意
引用的时候如果为同一个仓库可以使用include:local进行同一个仓库文件本地引用
对于在同一个gitlab服务器上的项目,可以使用project来引用,注意引用末尾没有.git
4.2 共享库注意事项
jobs中的原子操作不用定义stages,和branch,及运行的gitlab runner的tags
将公共变量提出来,将根据项目定义的变量也提出来,提高共享库的可扩展性及灵活性
在具体项目中引用模版,重新定义变量,将覆盖全局变量
五 反思
为了提升CI复用性和扩展性及规范CI流程,gitlab CI共享库非常好的解决了此问题,但是要求编写的具体jobs需要能无状态化,需要具备很高的扩展性和维护行,对于前期的规划和编写jobs都提出了很高的要求。
六 参考链接
https://docs.gitlab.com/ee/ci/yaml/#include
https://docs.gitlab.com/ee/ci/yaml/includes.html
https://www.jianshu.com/p/cc07db6de12d
版权声明: 本文为 InfoQ 作者【雪雷】的原创文章。
原文链接:【http://xie.infoq.cn/article/8cda2ece06d2f73fc7796a58a】。文章转载请联系作者。
评论