LabHub
学习 学习路径 课程

GitLab CI/CD

读懂配置,答出会跑什么

在 LabHub 中继续学习

目标

.gitlab-ci.yml 不是程序,而是声明。因此不能停留在“运行一下就知道”,而必须能通过阅读得出答案。流水线运行结果与预期不符的事故,几乎都源于错误解读这个文件。

本实验不使用 GitLab,只查看配置并得出答案。

材料

/opt/lab/glci/pipeline.yml   잡 다섯 개짜리 파이프라인
/opt/lab/glci/broken.yml     문법은 맞는데 뜻이 틀린 곳이 네 군데
mkdir -p /root/glci && cp /opt/lab/glci/* /root/glci/ && cd /root/glci

需要留下的文件

01-jobs.txt     잡과 템플릿
02-vars.txt     같은 변수의 세 값
03-rules.txt    상황마다 도는 잡
04-broken.txt   틀린 네 군데와 고치는 법
fixed.yml       고친 파일
check.py        같은 실수를 다시 막는 검사
07-notes.md     왜 그런지

区分 job 与非 job

pipeline.yml 中找出实际 job 的数量和名称,写入 01-jobs.txt,并另加一行说明 .base 为什么不是 job。

名称以点开头的条目是隐藏模板,不会执行,只会通过 extends 被其他配置引用。

stagesvariables 等保留字也不是 job。job 一共有五个。

同名变量的三个值

RETRIES 出现在三个位置。请在 02-vars.txt 中写出 build、unit、lint 各自实际使用的值,并另写一行说明该值为何胜出。

全局 variables 的优先级最低,模板(.base)次之,job 自己的 variables 优先级最高。

buildunit 只继承 .base,而 lint 单独设置了自己的值。

什么情况下运行什么

针对 main 分支 push、merge request、tag 三种情况,分别把会运行的 job 写入 03-rules.txt。每种情况用以对应词语(main머지태그)开头的一行区分。

rules 会**从上往下检查,并在第一个匹配项处停止。**若没有任何匹配,该 job 就不会运行。

最后一行若只有 when: never,表示“其他情况下不运行”。

deploy-prod 在 tag 情况下设为 when: manual,因此会出现在流水线中,但必须由人工点击。也要把它列入“运行”的 job,并注明为手动。

找出语法正确但含义错误之处

broken.yml 中找出四处问题,写入 04-broken.txt,并分别说明如何修复。

这些内容都能被 YAML 正常解析,错误在于违反 GitLab 的规则。

实际修复并保存为文件

创建实际修复这四处问题的 fixed.yml。不得删除任何 job。

如果通过删除 job 来修复,检查也许能通过,但流水线的含义会改变。保持原有工作不变,只修正表达方式。

对于 publish,删除 cache,让它接收 build 生成的 artifacts。同一流水线中,前序阶段的 artifacts 会自动下载;只有需要缩小接收范围时才写 dependencies

让机器阻止同类错误

创建 check.py,使其拦截 broken.yml 并放行 fixed.yml。检查作为参数传入的文件,发现问题时必须以非零状态码退出。

检查四类问题:使用 stages 中不存在的阶段、only/exceptrules 共存、用 needs 等待后续阶段,以及试图用 cache 在阶段间传递文件。

**无法拦截错误的检查不算检查,而连修复后的文件也拦截的检查不会有人使用。**请用两个文件进行正反双向验证。

写给下一位阅读者

从本实验看到的内容中选择至少四项,整理到 07-notes.md。不要只写做了什么,而要写清楚为什么

设想这份笔记要留给流水线行为与预期不符时的自己。“查看了 rules”没有帮助;“rules 在首个匹配项处停止,因此若上方条件成立,下方条件永远不会被检查”才有帮助。