一、引言:你为什么要关心 CI/CD?
想象这样一个场景——
你是一个三人团队的开发者。每次发布新功能,你们需要:
手动拉取最新代码
在本地跑一遍测试(有时忘了跑)
手动打包编译
手动上传到服务器
手动重启服务
流程繁琐不说,更可怕的是——总有人在某个环节出错。忘了 npm install,忘了跑单元测试,打包漏了文件,生产环境用了本地配置……每一次事故复盘,大概率都能归结为:人是不靠谱的。
而 CI/CD(持续集成 / 持续交付)解决的就是这个问题。它的核心理念很简单:
把重复性的、容易出错的"人肉操作"交给机器自动执行。
在 GitLab 的生态中,这个自动化任务就是由 .gitlab-ci.yml 文件来定义的。这个 YAML 文件相当于一份"施工图纸"——你只需把它放在项目根目录,GitLab 在检测到代码推送后,就会自动按照图纸执行构建、测试、部署等一系列操作。
根据 JetBrains 2025 年的开发者生态报告,GitLab CI/CD 已经成为全球使用率最高的 CI/CD 工具之一,与其竞争对手 GitHub Actions 并驾齐驱。对于使用 GitLab 作为代码托管平台的团队而言,它更是零额外成本、开箱即用的首选方案。
二、核心概念:三个词搞懂整个流程
要理解 GitLab CI/CD,你只需要先记住三个核心概念以及一个"执行者":
2.1 Pipeline(流水线)
Pipeline 就是"整个自动化流程的总称"。
每次你推送代码到 GitLab,系统就会自动创建一条 Pipeline。一条 Pipeline 包含了从代码检出到最终部署的全部自动化步骤。你可以把 Pipeline 理解成一个工厂的整条流水线——原材料(代码)从一头进去,经过多道工序,最终产出成品(可部署的应用)。
在 GitLab 的 UI 中,Pipeline 通常以一个有向图的形式展示,每一步都标明了当前状态:通过(绿色 ✓)、失败(红色 ✗)、运行中(蓝色 ⟳)或等待中(灰色 ⚬)。
2.2 Stage(阶段)
Stage 是 Pipeline 中的一个"大工序分组"。
一条 Pipeline 由若干个 Stage 组成,它们按你定义的顺序串行执行。最常见的三个 Stage 是:
build → test → deploybuild:编译代码、安装依赖、打包
test:运行单元测试、代码风格检查、安全扫描
deploy:将构建产物部署到目标环境
前一个 Stage 中的所有任务都成功了,后一个 Stage 才会开始。如果 build 阶段挂了,test 和 deploy 根本不会执行——这正是 CI/CD"尽早失败"的核心思想。
2.3 Job(任务)
Job 是 Pipeline 中最小的执行单元。
每个 Stage 内部可以包含一个或多个 Job,同一 Stage 内的 Job 并行执行。每个 Job 就是一个具体的"活":比如"用 ESLint 检查代码风格"、"执行 pytest 测试套件"、"构建 Docker 镜像并推送"等等。
用一个类比来总结三者的关系:
Pipeline 是一场考试 → Stage 是语文、数学、英语三科 → Job 是每科的每一道大题。
考试按科目顺序进行(Stage 串行),每科内部可以同时做不同的大题(Job 并行)。
2.4 Runner(运行器)
Runner 是真正干活的"工人"。
你在 .gitlab-ci.yml 中定义的 Job,最终是由 Runner 来执行的。Runner 是一个独立的进程,它:
持续轮询 GitLab 服务器,看看有没有新任务
收到任务后,拉取代码、按配置执行脚本
把执行结果回传给 GitLab
如果你用的是 GitLab.com(SaaS 版),GitLab 已经为你提供了免费的共享 Runner,可以直接使用,无需任何额外配置。如果你用的是私有化部署的 GitLab,则需要自己安装和注册 Runner——这正是我们下一篇要详细讲解的内容。
三、YAML 极简速览
.gitlab-ci.yml 使用的是 YAML 格式。如果你之前只接触过 JSON,这里花 1 分钟就能上手。
YAML 的核心规则就三条:
# 1. 用缩进表示层级(不能用 Tab,只能用空格,通常 2 个空格)
stages: # 顶层键
- build # 列表项:前面有 "-"
- test
- deploy
# 2. 键值对用 "键: 值"(冒号后必须有空格)
image: node:20 # ✅ 正确
image:node:20 # ❌ 缺少空格会报错
# 3. 多行文本用 | 或 >(| 保留换行,> 折叠为一行)
script:
- echo "第一行"
- echo "第二行"
# 也可以用 |
script: |
echo "第一行"
echo "第二行"对比 JSON 的话:
掌握这些就足够读懂 .gitlab-ci.yml 了。如果遇到语法问题,直接用 GitLab 内置的 CI Lint 工具校验(详见第六节)。
四、你的第一份 .gitlab-ci.yml
4.1 前置条件
开始之前,请确保:
你有一个 GitLab 项目(
Maintainer或Owner权限)项目中有可用的 Runner(使用 GitLab.com 的用户可以直接跳过,共享 Runner 开箱即用)
🔍 如何确认 Runner 可用?
进入项目 → Settings → CI/CD → 展开 Runners 区域,看到至少一个带绿色圆点的 Runner 就说明一切就绪。在 GitLab.com 上,你应该能看到 "Shared runners" 标记为可用。
4.2 最小可运行配置
在项目根目录创建一个名为 .gitlab-ci.yml 的文件(注意前面的点号,这是 Linux 的隐藏文件命名方式),填入以下内容:
# 你的第一份 .gitlab-ci.yml
stages:
- build
- test
- deploy
build-job:
stage: build
script:
- echo "🔨 开始构建..."
- echo "项目分支:$CI_COMMIT_BRANCH"
- echo "提交者:$GITLAB_USER_LOGIN"
test-job:
stage: test
script:
- echo "🧪 运行测试..."
- echo "所有测试通过!"
deploy-job:
stage: deploy
script:
- echo "🚀 部署到生产环境..."
- echo "部署完成!"
environment: production就这么几行代码,让我们逐段拆解:
(1) stages —— 定义流水线的三个阶段
stages:
- build
- test
- deploy这里告诉 GitLab:我这条流水线有 3 个阶段,按 build → test → deploy 的顺序执行。这是 YAML 的列表语法,- 代表一个列表项。
(2) build-job —— 第一个 Job
build-job:
stage: build
script:
- echo "🔨 开始构建..."
- echo "项目分支:$CI_COMMIT_BRANCH"
- echo "提交者:$GITLAB_USER_LOGIN"build-job是 Job 的名称(你可以随便起,但不能有空格)stage: build表示这个 Job 属于build阶段script是 Job 的核心——里面是 Runner 要依次执行的 Shell 命令$CI_COMMIT_BRANCH和$GITLAB_USER_LOGIN是 GitLab 的预定义变量,运行时会自动替换为当前分支名和用户名
(3) deploy-job 的 environment 声明
environment: production这一行告诉 GitLab:"这个 Job 是一个部署到 production 环境的操作"。GitLab 会自动在 Deployments → Environments 页面中追踪这个环境的部署历史,方便你随时回滚。
4.3 提交并触发 Pipeline
在 GitLab Web 界面中操作:
进入项目 → Code → Repository
确认当前分支(建议在
main或master分支上操作,后面会说原因)点击 + → New file
文件名填入
.gitlab-ci.yml粘贴上面的配置
填写 Commit message,点击 Commit changes
提交完成后,进入 Build → Pipelines,你应该会看到一条崭新的 Pipeline 正在运行!
五、查看 Pipeline 执行结果
5.1 Pipeline 列表视图
在 Build → Pipelines 页面中,你会看到类似这样的信息:
#123456789 │ ●●● │ passed │ main │ 3 minutes ago#123456789:Pipeline 的唯一 ID,点击可查看详情●●●:三个圆点代表三个阶段,颜色表示各自的状态passed:整体状态(绿色=通过,红色=失败,蓝色=运行中)
5.2 Pipeline 流程图
点击 Pipeline ID 进入详情页,你会看到一个可视化流程图:
build-job test-job deploy-job
(✓ 通过) → (✓ 通过) → (✓ 通过)这就是 Pipeline 的有向无环图(DAG),直观展示了 Job 之间的依赖关系和执行顺序。后续教程中我们会看到更复杂的图——有并行分支、有条件跳过等。
5.3 Job 日志
点击任意一个 Job(比如 build-job),你会看到该 Job 的完整执行日志:
Running with gitlab-runner 17.x.x
on runner-xxx
Preparing the "docker" executor
Using Docker image ruby:3.0
...
$ echo "🔨 开始构建..."
🔨 开始构建...
$ echo "项目分支:main"
项目分支:main
$ echo "提交者:NaGiARaShi"
提交者:NaGiARaShi
Job succeeded这就是你每一次 git push 后 GitLab 自动帮你做的事情。如果某一步失败了,日志中会有红色的错误信息,帮你快速定位问题。
六、常用预定义变量:让流水线"知道自己在哪"
在上面的示例中,我们用到了 $CI_COMMIT_BRANCH 和 $GITLAB_USER_LOGIN。这些是 GitLab 在每次运行 Pipeline 时自动注入的预定义变量(Predefined Variables),无需你手动设置。
以下是入门阶段最常用的几个:
这些变量的威力在于——你可以用它们来动态控制构建行为。比如:
deploy-prod:
stage: deploy
script:
- echo "正在将 $CI_COMMIT_SHORT_SHA 部署到生产环境"
- docker tag myapp:$CI_COMMIT_SHORT_SHA registry.example.com/myapp:$CI_COMMIT_SHORT_SHA
- docker push registry.example.com/myapp:$CI_COMMIT_SHORT_SHA💡 提示:想查看所有预定义变量?在任意 Job 的
script中加入env | sort,就可以在 Job 日志中看到完整的运行时环境变量列表。这在调试时非常有用。
七、CI Lint:你的语法检查助手
在开始自己写配置之前,还有一个小技巧要告诉你——CI Lint。
GitLab 内置了一个 YAML 配置校验工具,可以帮你检查 .gitlab-ci.yml 的语法是否正确,不需要提交代码就能验证:
Web 端:项目 → Build → Pipeline Editor → 编辑 YAML → 点击 Validate 标签页。如果语法正确,你会看到 ✅
Syntax is correct以及解析出的 Job 列表。IDE 插件:主流编辑器(VS Code、JetBrains 系列)都有 GitLab CI/CD 的语法高亮和自动补全插件,基于官方 JSON Schema 做实时校验。
⚠️ 重要提醒:CI Lint 检查的是语法,不是逻辑!它不会告诉你"这个命令不存在"或"那个镜像拉不到",那些问题只能在 Pipeline 实际运行时暴露。
八、小结与下篇预告
本篇核心要点回顾
你现在应该能做到的事
✅ 理解 Pipeline / Stage / Job / Runner 的关系
✅ 创建一份包含 3 个阶段的
.gitlab-ci.yml文件✅ 提交代码后看到 Pipeline 自动运行并查看结果
✅ 使用预定义变量获取运行时上下文
✅ 用 CI Lint 校验配置语法
下篇预告
在这篇文章中,我们一直使用 GitLab.com 的共享 Runner(也就是 GitLab 官方帮你搭好的)。但在实际工作中,你可能需要:
在你的私有服务器上部署 Runner
在 Docker 容器中运行 Runner
在 Kubernetes 集群中弹性伸缩 Runner
下一篇《Runner 部署详解:Shell / Docker / Kubernetes 三种执行器全指南》,我们将从 Runner 的架构原理开始,手把手带你完成三种主流执行方式的安装、注册和验证,为后续更复杂的流水线配置打下坚实基础。
参考资料: