Gitlab-CI使用及.gitlab-ci.yml配置
# Gitlab-CI使用及.gitlab-ci.yml配置
# Gitlab-CI/CD 持续集成测试篇
# Gitlab-CI/CD使用场景
首先,公司使用Gitlab作为工作仓库进行代码发布及版本控制,Gitlab内置了CI/CD的工具,这些工具可以用于代码提交的同时完成镜像构建、自动化测试、自动化部署等连续的工作:
- CI: Continuous Integration(持续集成)
- CD: Continuous Delivery(连续交付)
- CD: Continuous Deployment(持续部署) 这里暂时只讨论CI持续集成部分的工作,我们常用CI来做一些自动化工作,这种自动化工作会运行在一台集中的机器上,比如程序镜像的打包,单元测试,部署等,它可以节省项目开发迭代过程中维护正确的代码所耗费的时间。
例比如CI中自动测试,在多人协同开发的过程中,可能会有频繁的不同分支的代码推送更新,使用CI管道,可在代码发布的同时触发CI中定义的单元测试操作,以便于在开发早期发现错误,从而确保所有新代码的提交都不影响项目功能。
# 了解Gitlab-CI/CD工作流
参考下图先了解CI/CD的具体工作流和概念,黄色部分为主要涉及的概念,将在后文重点说明:
- 你当前的代码库托管在Gitlab上, 且已经为代码仓库配置了
gitlab-runner
服务, 它是用来实际执行CI任务的服务器; - 提交代码,且根目录中包含一个名为
.gitlab-ci.yml
文件,该文件是用来指定构建、测试和部署流程、以及CI触发条件的脚本,其概念类似于docker-compose.yml文件; - Gitlab检测到
.gitlab-ci.yml
文件,若当前提交符合文件中指定的触发条件,则会使用配置的gitlab-runner
服务运行该脚本进行测试等工作; - 若
.gitlab-ci.yml
中定义的某个自动化脚本运行失败,将判定为此次CI不通过,则需要提交者修复问题代码后重复提交,直至自动化CI通过。 - 没有问题的提交才能被项目负责人merge到主分支,进行后续的部署工作(此文暂不涉及CD自动化部署)
# 如何编写CI文件
.gitlab-ci.yml
文件中指定了CI的触发条件、工作内容、工作流程,编写和理解此文件是CI实战中最重要的一步,该文件指定的任务内容总体构成了1个pipeline
、1个pipeline
包含不同的stage
执行阶段、每个stage
包含不同的具体job
脚本任务。
.gitlab-ci.yml示例文件及常用说明
# Pipeline说明
一个.gitlab-ci.yml
文件触发后会形成一个pipeline
任务流由gitlab-runner
来运行处理,pipeline
中stage
、job
概念如下,需要按照项目实际情况定义不同stage
和job
, 自己绘制了一个流程示意图帮助理解:
示例 .gitlab-ci.yml
文件运行顺序及逻辑说明
按1.
所示在项目根目录中编写好yml文件,
首先绿色方框中定义了
stage
的阶段顺序,总共定义了3个阶段,按顺序依次命名为build、test、deploy;第一个蓝色方框定义了build阶段的一个
job
,该job
仅在tags阶段的分支提交时触发,执行script中的脚本,按照DockerfileCI文件将项目打包为成名为img的镜像,并推送到仓库中,然后移除本地镜像;第二个蓝色方框定义了test阶段的一个
job
,该job
没有限制触发条件,将在每次提交时执行。Image
指定了该阶段使用的基础镜像,该镜像为本地手动提前创建并推送;services
指定了该阶段依赖使用的服务,mongo和redis,该job运行时会初始化指定服务版本的容器,并分别暴露域名为mongo:27017、redis:6379,需要在配置文件中提前配置好CI专用的配置文件;befor_script
指定了在执行正式脚本之前预先执行的命令,打印python版本信息、将CI专用测试配置文件置为项目读取的配置文件、运行测试数据初始化脚本、npm构建前端部分;script
指定了正式脚本执行命令,开始执行django的单元测试。
其他gitlab-ci.yml文件参考
# Gitlab-Runner介绍和使用
上面讲了.gitlab.yml
文件如何编写以及其中的job执行顺序逻辑,那各个job实际的执行者是谁呢,答案就是gitlab-runner
,一般来说gitlab-runner
会和gitlab所在的服务器进行隔离,因为一个任务的构建、往往会执行编译、测试、发布的过程,这个过程会消耗大量的系统资源。gitlab-runner
几乎可以安装在任何的机器上,只要能和gitlab所在服务器及docker仓库服务器进行通信即可。
一般来说,gitlab上已由负责人配置好了gitlab-runner
,我们只需要编写好.gitlab.yml
文件提交代码即可触发runner进行工作。但对于初学者来说,你可能想能不能在提交代码前在本地先执行.gitlab.yml
文件的job,本地调试成功检查没有问题后再进行最终代码的提交,触发服务端的CI流程。答案当然也是可以的。之前已经说了,.gitlab.yml
文件中定义的job其实是某个服务器中的gitlab-runner
在运行,那我们也可以在本地安装好gitlab-runner
手动的来执行本地.gitlab.yml
中的job
。
# .gitlab-ci.yml
Gitlab CI使用YAML文件(.gitlab-ci.yml)来管理项目配置。该文件存放于项目仓库的根目录,它定义该项目如何构建。
YAML是一个可读性高,用来表达数据序列的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML,电子邮件的数据格式中获得灵感。 YAML是"YAML Ain't a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言),但为了强调这种语言以数据作为中心,而不是以标记语言为重点,而用反向缩略语重命名。 --- 维基百科
.gitlab-ci.yml文件定义了一系列带有约束说明的任务,这些任务都是以任务名开始要包含script
部分,一个.gitlab-ci.yml的例子:
stages:
- unit-test
UnitTest:
stage: unit-test
tags:
- spring-sample
script:
- echo "Hello one"
- echo "Hello two"
- echo "Hello three"
when: always
# 构建脚本解析
stages
定义可以被调用的阶段,默认定义为build,test和deploy,执行顺序:
- 相同stage的job可以平行执行。
- 下一个stage的job会在前一个stage的job成功后开发执行
这里定义了一个stage:unit-test
。
下面的UnitTest
是定义的一个任务,这个任务在stage为unit-test
时执行。
tags
表示他需要执行的gitlab-runner,这里在一个tag为spring-sample的tag中执行。
script
代表需要执行的脚本,该例子中执行的脚本包括三步:
- 运行gradle测试
- 进行单元测试覆盖情况检查
- 运行sonarqube进行代码质量检查
when
定义何时执行任务,可以是on_success,on_failure,always(每次代码更新都触发)或者manual(手动触发)。
另外,比较常用的字段还有:
before_script
用来定义所有job之前运行的命令,包括部署任务等,可以是一个数组或者是多行字符串
after_script
用来定义所有job之后运行的命令。它必须是一个数组或者多行字符串
例如:
job:
before_script:
- execute this instead of global before script
script:
- my command
after_script:
- execute this after my script
cache
用来指定需要缓存的文件或目录,例如:
job1:
script: test
cache:
paths:
- binaries/
- .config
更多字段可以参考官方文档。