一、CI/CD概述:什么是持续集成、持续交付与持续部署
1.1 从一次痛苦的发布说起
我记得刚入行那会儿,在一家创业公司做后端开发。每次发布都像在走钢丝——周五下午四点,所有人盯着屏幕,项目经理喊一声「合并!」。十几个人的代码挤在一起,冲突像地雷一样炸开。修完冲突,编译挂了;修完编译,测试又红了。等一切搞定,已经是凌晨两点。
这种经历,我相信很多老开发都懂。说白了,那时候的「集成」就是一场赌博。赌你的代码不会覆盖别人的逻辑,赌测试能跑过,赌上线后不会出事故。
为什么会这样?因为缺少一个关键的东西——持续集成。
1.2 什么是持续集成?
持续集成,英文叫 Continuous Integration,简称 CI。它的核心思想很简单:让开发人员频繁地将代码合并到主干,每次合并都自动触发构建和测试。
我个人习惯把 CI 理解为「代码的安检机」。你每次提交代码,系统就自动帮你检查一遍——编译能不能过?单元测试有没有挂?代码风格是否规范?
CI 的核心动作:
- 开发者频繁提交代码(每天至少一次)
- 每次提交自动触发构建
- 自动运行测试套件
- 快速反馈结果(通常 10 分钟内)
我在项目中遇到过最典型的反例:一个团队两周才合并一次代码,结果每次合并都要花两天解决冲突。后来我们上了 CI,每天合并 3-5 次,冲突从「两天」降到了「半小时」。你想想看,这效率差距有多大。
1.3 持续交付 vs 持续部署
这两个概念经常被搞混。我简单解释一下:
| 概念 | 英文 | 核心区别 | 是否自动上线 |
|---|---|---|---|
| 持续集成 | CI | 自动构建 + 自动测试 | 否 |
| 持续交付 | CD (Delivery) | CI + 自动部署到预发布环境 | 手动触发上线 |
| 持续部署 | CD (Deployment) | CI + 全自动部署到生产环境 | 是 |
持续交付的意思是:代码随时可以发布,但要不要发布由人决定。比如你周五下午代码合并完了,系统自动部署到了 staging 环境,测试人员验证通过。但上线按钮在运维手里,他可以选择周一早上再点。
持续部署就更激进一些:只要代码通过所有检查,系统自动就推到生产环境了。嗯,这里要注意——不是所有业务都适合持续部署。金融、医疗这些强监管行业,通常只做到持续交付。
我的建议:刚开始做 CI/CD 的团队,先从持续集成做起。等构建和测试稳定了,再推进到持续交付。持续部署?等你们有足够的自动化测试覆盖和监控告警再说。
1.4 为什么需要 CI/CD?
说白了,就三个字:快、稳、省。
- 快:发现问题快。代码提交后几分钟就知道有没有问题,不用等到周五晚上。
- 稳:每次发布都是小步快跑。改动范围小,出了问题容易回滚,影响面也小。
- 省:省时间、省人力。自动化代替了手动构建、手动测试、手动部署这些重复劳动。
我曾经在一个项目里做过统计:上 CI/CD 之前,每次发布平均耗时 6 小时,其中 4 小时花在手动操作上。上了之后,发布耗时降到 20 分钟,而且 90% 的操作都是自动的。你想想看,这省下来的时间能干多少事。
1.5 CI/CD 的核心价值
我总结了几点,都是实际项目中验证过的:
- 降低集成风险——频繁集成,每次改动小,冲突少,问题早发现。
- 提高代码质量——自动跑测试、做静态检查,把低级错误挡在门外。
- 加速交付节奏——从「月发布」变成「周发布」甚至「日发布」。
- 增强团队信心——每次发布都有自动化流程兜底,大家敢改代码了。
- 可重复的发布流程——环境一致、步骤一致,不会出现「在我机器上能跑」这种鬼话。
一句话总结:CI/CD 不是工具,而是一种工程文化。它让「频繁发布」这件事变得安全、可靠、可预期。
1.6 常见的挑战与坑
做 CI/CD 不是一帆风顺的。我踩过不少坑,分享几个典型的:
挑战一:测试太慢
我曾经遇到一个项目,全量测试跑完要 40 分钟。开发者提交代码后,等反馈等到花儿都谢了。后来我们做了三件事:并行化测试、分层测试(单元测试跑快的,集成测试跑慢的)、只跑受影响的测试用例。最终把反馈时间压缩到了 8 分钟。
挑战二:环境不一致
「在我机器上能跑啊!」——这句话我听了不下 50 次。解决方案就是容器化。用 Docker 把开发、测试、生产环境统一起来,从根上解决环境差异问题。
挑战三:团队抵触
有些老开发觉得 CI/CD 是「多此一举」。「我手动编译也挺快的啊。」这时候别硬推。我一般先挑一个痛点最明显的项目做试点,跑出效果了,其他人自然就跟着来了。
1.7 一个简单的 CI 流程示例
光说不练假把式。我写一个最基础的 CI 配置,用 GitHub Actions 举例:
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 安装依赖
run: npm install
- name: 运行 lint 检查
run: npm run lint
- name: 运行单元测试
run: npm test
- name: 构建项目
run: npm run build
这个配置做了什么事?很简单:
- 有人往 main 或 develop 分支推送代码时,自动触发
- 先拉代码,然后安装依赖
- 跑 lint 检查代码风格
- 跑单元测试
- 最后构建项目
任何一个步骤失败,整个流程就红了,开发者会收到通知。这就是 CI 最基本的闭环:提交 → 检查 → 反馈。
1.8 本章小结
这一章我们聊了:
- 持续集成是「频繁合并 + 自动检查」
- 持续交付是「随时可发布,手动触发」
- 持续部署是「全自动上线」
- CI/CD 的核心价值是快、稳、省
- 常见的挑战包括测试慢、环境不一致、团队抵触
下一章,我会带大家搭建一个完整的 CI 流水线。从零开始,手把手教你配置。到时候咱们再细聊。
课后思考:你现在的团队发布一次要多久?如果让你优化,你会先改哪个环节?