一个计算机技术爱好者与学习者

0%

好好学GitLab:GitLab CI/CD入门篇

1. GitLab CI/CD是啥?

CI,CONTINUOUS INTEGRATION,持续集成。简单来说就是自动化构建和测试。
一个应用程序的代码存储在Git仓库中。开发人员推送的每个更改,甚至是开发分支,都可以通过一组脚本来自动地构建和测试。这些测试可确保更改通过您为应用程序建立的所有测试、指南和代码合规性标准。

CD,CONTINUOUS DELIVERY,持续交付。简单来说就是自动化构建和测试+支持手动触发部署。
每次将代码更改推送到代码库时,不仅会自动构建和测试应用程序,还支持一键部署应用程序,这里的部署需要手动触发。

CD,CONTINUOUS DEPLOYMENT,持续部署。简单来说就是自动化构建和测试+自动部署。
持续部署类似于持续交付,不同之处在于,不是手动触发部署应用程序,而是将其设置为自动部署。

而GitLab CI/CD,就是一种支持在GitLab中配置使用持续集成、持续交付和持续部署的工具。

参考文档:

2. GitLab CI/CD基本概念

  • pipeline:在每个仓库中,使用名为.gitlab-ci.yml的yaml文件配置gitlab ci/cd流水线(pipeline)
  • stage:一条流水线可以包含多个阶段(stage),一个阶段可以包含多个作业
  • job:作业(job)是具体要执行的任务,是命令脚本语句的集合
  • runner:runner是每个作业的执行节点;每个作业可以根据标签选择不同的执行节点

3. Gitlab CI/CD工作机制

1、在gitlab仓库中添加.gitlab-ci.yml文件,定义流水线

2、当仓库中发生commit、push、merge等事件时,根据.gitlab-ci.yml的定义触发流水线

3、流水线会调用gitlab runner,在gitlab runner中按照.gitlab-ci.yml的定义跑作业

4. GitLab CI/CD流水线语法

参考文档:

4.1. 典型示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
stages: #对stages的编排
- build
- test
- deploy

variables:
DEPLOY_ENV: "dev"

ciinit:
tags:
- build
stage: .pre
script:
- echo "Pipeline init first job"

ciend:
tags:
- build
stage: .post
script:
- echo "Pipeline end job"

before_script:
- echo "Before script section"
- echo "For example you might run an update here or install a build dependency"
- echo "Or perhaps you might print out some debugging details"

after_script:
- echo "After script section"
- echo "For example you might do some cleanup here"

build:
tags:
- k8s
stage: build
script:
- echo "Do your build here"

test1:
tags:
- k8s
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"

test2:
tags:
- k8s
stage: test
script:
- echo "Do a test here"
- echo "For example run a test suite"

deploy:
tags:
- k8s
stage: deploy
variables:
DEPLOY_ENV: "test"
script:
- echo "${DEPLOY_ENV}"
- echo "Do your deploy here"

4.2. stages阶段控制

  • stages里可以定义各个stage执行的前后顺序,但是.pre.post阶段不受其控制
  • .pre阶段的作业总是在流水线开始时执行
  • .post阶段的作业总是在流水线结束时执行
  • 如果两个或者多个作业,指向同一个阶段名称,则该阶段下的所有作业都并行运行;如果不能并行运行,需要检查runner的配置文件中的concurrent

4.3. variables环境变量

环境变量可以分为两类:全局变量和局部变量,局部变量优先级高于全局变量

  • 全局变量是整个流水线生效的,局部变量是仅在作业中生效的
  • 全局变量可以使用CI自带的预定义变量,也可以自定义变量
  • 全局变量定义在全局 variables 中,也可以定义在 workflow:rules:variables 中
  • 局部变量定义在 job:variables 中,也可以定义在 job:rules:variables 中

.gitlab-ci.yml解析顺序为:全局变量 -> workflow规则 -> job规则,因此:job中变量优先级 > workflow中变量优先级 > 全局变量优先级

常用全局预定义变量:

变量名称GitLabGitLab Runner描述
CIall0.4对CI/CD中的所有作业可见,值为true
CI_BUILDS_DIRall11.10构建时的最顶层目录
CI_COMMIT_AUTHOR13.11all提交的作者,格式为:名称<邮箱>
CI_COMMIT_BEFORE_SHA11.2all当前分支的上一个提交哈希值
CI_COMMIT_BRANCH12.60.5提交的分支名,在合并流水线和tag流水线时不可见
CI_COMMIT_DESCRIPTION10.8all提交的描述
CI_COMMIT_MESSAGE10.8all完整的提交信息
CI_COMMIT_REF_NAME9.0all项目的分支名或tag名
CI_COMMIT_REF_PROTECTED11.11all如果作业正在构建的是被保护的分支或tag,值为true
CI_COMMIT_REF_SLUG9.0allCI_COMMIT_REF_NAME的小写形式。
CI_COMMIT_SHA9.0all提交的完整哈希值
CI_COMMIT_SHORT_SHA11.7all8个字符的提交哈希值
CI_COMMIT_TAG9.00.5提交的tag,仅在tag流水线可见
CI_COMMIT_TIMESTAMP13.4all提交时的时间戳
CI_COMMIT_TITLE10.8all提交的标题
CI_DEFAULT_BRANCH12.4all项目的默认分支
CI_DEPLOY_FREEZE13.2all当流水运行是处于部署冻结阶段时可见,值为true。
CI_ENVIRONMENT_NAME8.15all当前作业的部署环境名,当设置了environment:name 时可见
CI_ENVIRONMENT_URL9.3all当前作业的部署环境地址,只有设置了environment:url可见
CI_JOB_ID9.0all当前作业的ID,系统内唯一
CI_JOB_IMAGE12.912.9当前作业使用的Docker镜像名
CI_JOB_NAME9.00.5当前作业名称
CI_JOB_STAGE9.00.5当前作业所属的阶段名
CI_PIPELINE_ID8.10all当前流水线ID(实例级),系统内唯一
CI_PIPELINE_SOURCE10.0all流水线触发方式,枚举值为push,web, schedule, api, external, chat, webide,merge_request_event, external_pull_request_event, parent_pipeline, trigger, 或者 pipeline
CI_PIPELINE_TRIGGEREDallall当作业是使用trigger触发的时为true
CI_PIPELINE_URL11.10.5流水线详情的地址
CI_PIPELINE_CREATED_AT13.10all流水线创建时间
CI_PROJECT_DIRallall存放克隆项目的完整路径,作业运行的目录。
CI_PROJECT_NAME8.100.5当前项目名称,不包含组名
CI_PROJECT_NAMESPACE8.100.5项目的命名空间(组名或用户名)
CI_PROJECT_PATH8.100.5包含项目名称的命名空间
CI_PROJECT_TITLE12.4all项目名称(网页上显示的)
CI_PROJECT_URL8.100.5项目HTTP(S)地址
CI_RUNNER_TAGS8.100.5逗号分割的runner标签列表
GITLAB_USER_EMAIL8.12all开始当前作业的用户邮箱
GITLAB_USER_LOGIN10.0all开始当前作业的登录用户名
GITLAB_USER_NAME10.0all开始当前作业的用户名
CI_MERGE_REQUEST_APPROVED (仅合并流水线)14.1all当合并流水线的MR被通过时值为true
CI_MERGE_REQUEST_ASSIGNEES (仅合并流水线)11.9all逗号分割的合并请求指派人列表
CI_MERGE_REQUEST_SOURCE_BRANCH_NAME(仅合并流水线)11.6all合并请求中的源分支名称
CI_MERGE_REQUEST_TARGET_BRANCH_NAME(仅合并流水线)11.6all合并请求中的目标分支名称
CI_MERGE_REQUEST_TITLE(仅合并流水线)11.9all合并请求的标题

预定义变量详情参考文档:

4.4. job关键字

  • variables:定义作业中的环境变量
  • tags:根据标签选择运行作业的节点,如果有多个标签,则匹配具有所有标签的节点
  • stage:指定当前作业所属的阶段名称
  • before_script:作业在运行前执行的Shell命令行
  • script:作业在运行中执行的Shell命令行,每个作业至少要包含一个script
  • after_script:作业在运行后执行的Shell命令行
  • only:作业控制,满足条件时执行
  • except:作业控制,满足条件时不执行
  • rules:作业控制,12.3之后引入的特性,不能与only/except混用,具体用法参考【jobs:rules作业控制】一节

有了before_script、script、和after_script,可以方便我们把通用的脚本抽象出来。

  • before_script:有命令执行结果非0,job判定失败,不再执行before_script的后续命令,跳过script,继续执行after_script
  • script:有命令执行结果为0,job判定失败,不再执行script的后续命令,继续执行after_script
  • after_script:有命令执行结果非0,job判定不受影响,不再执行after_script后续命令

4.5. job:rules作业控制

使用 job:rules 关键字来控制何时创建作业。

rules包含以下子关键字:

  • if:条件判断,为true时再看对应的其他规则。
    • if的语法和bash中的if语法很像
    • 不同1:模式匹配时添加了两个斜杠
    • 不同2:变量不能加花括号(版本14.0.5)
  • when:前面的作业成功或者失败时运行。on_success(默认值)前面作业成功时执行;on_failure 前面作业失败时执行;always 总是执行;manual 手动执行;delayed&start_in 延迟执行;never 永不执行。
  • allow_failure:是否允许作业失败,默认值为false。启用后,作业失败不会阻塞接下来的任务。
  • retry:作业遇到错误重新运行的次数。
  • timeout:作业运行超时时间。
  • needs:作业依赖控制。当前作业可能只依赖前一个stage的其中一个作业,就不用等前一个stage的作业全部完成。
  • parallel:生成多个作业,并行运行。值在2-50之间。
  • variables:定义特定作业条件下的变量。

参考文档:

4.6. workflow:rules流水线控制

使用 workflow:rules 关键字来控制何时创建流水线。
workflow:rules 关键字在作业之前进行评估。例如,将作业配置为针对标签运行,但工作流阻止标签流水线,则该作业永远不会运行。

rules包含以下关键字:

  • if:条件判断,为true时再看对应的when规则。
  • when:取值never表示流水线不运行,取值always或者缺省表示流水线运行。
    • 最后一个规则的if缺省,when: always表示其他所有流水线类型都运行。
    • 最后一个规则不是when: always,表示其他所有流水线类型都不运行。
  • variables:定义特定流水线条件的变量(引入于13.11版本)。例如不同分支,同一个变量可以定义不同的值。

参考文档:

4.7. include

使用 include 在 CI/CD 配置中包含外部 YAML 文件。 您可以将一个长的 .gitlab-ci.yml 文件拆分为多个文件以提高可读性,或减少同一配置在多个位置的重复。

您还可以将模板文件存储在中央仓库中并将它们包含在项目中。

include 文件说明:

  • 与 .gitlab-ci.yml 文件中的那些合并。
  • 无论 include 关键字的位置如何,始终先求值,然后与 .gitlab-ci.yml 文件的内容合并。

include 子键:

  • include:local
  • include:project,include:file,include:ref
  • include:remote
  • include:template

注意:如果include了多个文件中都包含stages,那么最后一个文件中的stages会生效。

参考文档:gitlab-ci - include

4.8. extends

使用 extends 来重用配置 section。它是 YAML 锚点 的替代方案,并且更加灵活和可读。

关键字类型:作业关键字。您只能将其用作作业的一部分。

可能的输入:

  • 流水线中另一个作业的名称。
  • 流水线中其他作业的名称列表(数组)。

注意:extends父作业时,如果不想执行父作业,那么父作业的名称应该以点.开头。

参考文档:gitlab-ci - extends

4.9. job:services

使用services可以指定job运行所需的服务镜像。
GitLab CI/CD会为每个任务创建一个Docker网络,并且把任务容器和服务容器都连接到这个网络上。
服务容器的别名就是它在这个网络上的主机名,所以任务容器可以通过别名来访问服务容器提供的端口。

使用Docker执行器的话,任务和服务都跑在容器中。
使用Shell执行器的话,任务跑在执行器所在的机器上,服务跑在容器中。同时,执行器所在机器需要安装Docker。

参考文档:

4.10. job:artifacts

job:artifacts的作用是将Job执行后生成的文件或目录存储在GitLab服务器上,供后续的Job或用户下载和使用。我们可以通过UI或API来下载Job artifacts。需要注意的是,Job artifacts的大小不能超过配置的最大值。

artifacts常用关键字:

  • paths:所有指定的路径中的文件,都会被放入artifacts目录。用于指定任意类型的Job artifact,例如编译后的二进制文件、日志文件、图片文件等,这些类型的Job artifact可以被后续的Job或用户下载和使用。只有在Job执行成功时才会上传,除非指定了when:always参数。
  • name:指定制品名称,默认制品名称是artifacts,下载时对应artifacts.zip
  • exclude:排除不要放入artifacts目录的文件。
  • expire_in:制品的过期时间,默认30天。每小时会自动删除一次过期制品。
  • expose_as:要在制品下载链接的UI中显示的名称。
  • public:制品是否可以公开下载。
  • reports:用于指定一些特定类型的Job artifact,例如JUnit测试报告、代码覆盖率报告、性能测试报告等,这些报告是可以在GitLab的流水线视图、性能仪表盘和安全仪表盘中查看的。总是上传制品,无论Job执行成功还是失败。
  • untracked:是否把.gitignore中忽略的文件也作为制品,默认false,不包含被忽略的文件。
  • when:什么时候上传制品。取值on_success、on_failure和always,只对paths生效,reports一定会上传。

下载制品的方法:进入CI/CD Pipelines页面,找到Job对应的Pipeline,最右边三个点,点击下载artifacts。

参考文档:

4.11. job:coverage

将覆盖率与自定义正则表达式一起使用,可以配置如何从作业输出中提取代码覆盖率。如果作业输出中至少有一行与正则表达式匹配,则覆盖率将显示在UI中。

参考文档:

5. 常用配置

5.1. 当流水线成功时合并分支

1、项目配置
Project -> Settings -> General -> Merge requests -> Expand -> Merge checks -> 勾选 Pipelines must succeed

2、gitlab-ci配置
gitlab-ci配置时,要保证workflow和job中都允许merge requests触发pipeline。

3、触发合并请求
gitlab页面上发起一次合并请求,或者使用glab发起合并请求

4、流水线成功时自动合并
打开合并代码的页面,当pipeline运行时,点击 Merge when pipeline succeeds

参考文档:

6. Gitlab Runner

参考文档《GitLab Runner入门篇》

7. TODO

  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-gitlab-cicd/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~