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

0%

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

1. GitLab CI/CD是啥?

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

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

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

而GitLab CI/CD,就是一种支持在GitLab中配置使用持续集成、持续交付和持续部署的工具。GitLab CI/CD通过使用YAML文件定义作业流程和流水线(pipelines),可实现复杂的应用程序的自动化构建和部署。

参考文档:

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. 配置第一个流水线

4.1. 配置.gitlab-ci.yml

为了配置GitLab CI/CD流水线,首先需要在项目根目录创建一个.gitlab-ci.yml文件,并定义需要执行的作业和阶段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
stages:
- build
- test
- deploy

build_job:
stage: build
script:
    - echo "Building the project..."
    - ./build-script.sh

test_job:
stage: test
script:
    - echo "Running tests..."
    - ./run-tests.sh

deploy_job:
stage: deploy
script:
    - echo "Deploying application..."
    - ./deploy-script.sh

这个简单的例子定义了三个作业,每个作业分别执行构建、测试和部署脚本。

4.2. 注册Runner

为了让流水线工作,我们需要至少一个注册的Runner。可以使用GitLab提供的共享Runner,或者自己安装和注册一个专用的Runner。

注册Runner步骤如下:

1、在GitLab页面上,进入我们的项目设置。
2、寻找CI/CD设置,找到Runners部分。
3、我们会看到用于注册Runner的URL和Token。
4、在具有网络访问权限的机器上安装Runner并运行注册命令,使用提供的URL和Token。

更多Runner相关内容,参考文档《好好学GitLab:GitLab Runner入门篇》

5. 流水线典型示例

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"

6. 流水线语法

6.1. 流水线语法概述

GitLab CI/CD流水线是由 .gitlab-ci.yml 文件中定义的一系列规则和指令组成。这个文件使用YAML语法来描述CI/CD的过程。

GitLab CI/CD 流水线配置包括:

  • 配置流水线行为的全局关键字
  • 配置作业行为作业关键字

参考文档:

6.2. 全局关键字

  • default 作业关键字的自定义默认值。
  • stages 流水线阶段的名称和顺序。
  • workflow 控制运行的流水线类型。
  • include 从其他 YAML 文件导入配置。

6.3. 作业关键字

6.3.1. 执行命令

  • before_script:作业在运行前执行的Shell命令行
  • script:作业在运行中执行的Shell命令行,每个作业至少要包含一个script
  • after_script:作业在运行后执行的Shell命令行

有了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后续命令

6.3.2. 环境变量

  • variables:在作业级别定义作业变量。
  • environment:作业部署到的环境的名称。
  • secrets:作业所需的 CI/CD secret 信息。secret属于enviroment。

6.3.3. 作业条件

  • stage:定义作业阶段,指定当前作业所属的阶段名称,从而确定作业顺序
  • only:满足条件时执行作业
  • except:满足条件时不执行作业
  • rules:12.3之后引入的特性,不能与only/except混用,具体用法参考【jobs:rules作业控制】一节
  • when:何时运行作业。
  • needs:在 stage 顺序之前执行的作业。
  • tags:根据标签选择运行作业的Runner节点,如果有多个标签,则匹配具有所有标签的Runner节点
  • image:指定执行作业的脚本时应该启动哪个 Docker 镜像作为执行环境,成为主容器。这个 Docker 镜像应包含所有必要的依赖和工具,以便能够运行定义在 script 部分的命令。需要Runner支持Docker。
  • services:指定与主容器相连的额外容器服务。这些服务可以是数据库、缓存等。
  • allow_failure:允许作业失败。失败的作业不会导致流水线失败。
  • parallel:应该并行运行多少个作业实例。
  • resource_group:限制作业并发。
  • trigger:定义下游流水线触发器。

6.3.4. 超时与重试

  • retry:在失败的情况下可以自动重试作业的时间和次数。
  • timeout:定义优先于项目范围设置的自定义作业级别超时。

6.3.5. 继承

  • extends:此作业继承自的配置条目。
  • inherit:选择所有作业继承的全局默认值。

6.3.6. 其他

  • artifacts:成功时附加到作业的文件和目录列表。
  • cache:应在后续运行之间缓存的文件列表。
  • coverage:给定作业的代码覆盖率设置。
  • dast_configuration:在作业级别使用来自 DAST 配置文件的配置。
  • dependencies:通过提供要从中获取产物的作业列表,来限制将哪些产物传递给特定作业。
  • interruptible:定义当新运行使作业变得多余时,是否可以取消作业。
  • pages:上传作业的结果,与 GitLab Pages 一起使用。
  • release:指示运行器生成 release 对象。

7. 流水线部分关键字详解

7.1. 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合并请求的标题

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

7.2. 全局关键字

7.2.1. workflow:rules流水线控制

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

rules包含以下关键字:

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

参考文档:

7.2.2. stages阶段控制

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

7.2.3. 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

7.3. 作业关键字

7.3.1. 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:定义特定作业条件下的变量。

参考文档:

7.3.2. extends

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

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

可能的输入:

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

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

参考文档:gitlab-ci - extends

7.3.3. job:services

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

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

参考文档:

7.3.4. 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。

参考文档:

7.3.5. job:coverage

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

参考文档:

8. 常用配置

8.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

参考文档:

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