什么是 CI/CD?
CI/CD 是一套把代码从提交到交付给用户的过程自动化、可重复化的方法。CI 是 Continuous Integration(持续集成),强调开发者频繁地把小批量代码合并到共享分支,并自动构建和验证;CD 有两种常见含义:Continuous Delivery(持续交付)和 Continuous Deployment(持续部署),前者让代码随时处于可发布状态,后者在自动化检查通过后直接发布到生产环境。

CI/CD 主要解决三个问题:代码合并太晚导致冲突难解、测试和环境配置不一致导致返工,以及手工部署不可重复导致线上事故。它通常由 Git 仓库、流水线服务器、构建与测试工具、制品仓库和部署平台共同组成。
一句话总结:CI/CD 就是让代码交付像流水线一样自动运行、快速反馈,并且每一步都可以追溯和重复。
为什么没有 CI/CD 的发布会变成高风险事件?
没有 CI/CD 时,团队往往把集成、测试和上线都推迟到某个“发布日”。问题会在同一时间集中爆发,而不是在提交发生的几分钟内被发现。

一个五六人的团队如果两周才合并一次代码,常见流程是:每个人在自己的分支上开发,合并日一次性处理几十个冲突,测试人员手动点完流程,运维再按照文档逐条执行命令。这个流程有四类具体成本:
- 冲突成本:分支存活时间越长,代码上下文差异越大,冲突越难判断谁是正确版本。
- 等待成本:开发要等测试,测试要等部署,发布要等运维窗口,反馈周期被人为拉长。
- 返工成本:问题直到合并或上线才出现,修复一次可能牵动一批已经完成的功能。
- 事故成本:手动命令、临时配置和口头约定无法保证每次都一致,回滚也常常缺少现成制品。
因此,CI/CD 的第一价值不是“让按钮更酷”,而是把大而晚的风险拆成小而早的反馈。
CI、持续交付和持续部署有什么区别?
三者都使用自动化流水线,但自动化终点不同:
| 概念 | 自动化终点 | 是否需要人工确认 | 适合场景 |
|---|---|---|---|
| 持续集成 CI | 代码构建、单元测试、静态检查 | 通常不需要 | 每次提交或合并请求都验证代码 |
| 持续交付 Continuous Delivery | 部署到测试、预发布,并准备好生产发布 | 生产发布通常需要 | 有合规、产品验收或发布窗口的团队 |
| 持续部署 Continuous Deployment | 自动通过所有关卡并部署生产 | 不需要最后确认 | 高度自动化、可快速回滚的高频迭代产品 |

持续交付和持续部署不是“先进”和“落后”的关系。金融、医疗等业务可能保留人工审批,但仍然可以自动构建、测试、部署和生成审计记录;关键是让人工只做必要的决策,而不是重复敲命令。
一条 CI/CD 流水线如何工作?
典型流水线把一个提交依次变成可验证、可部署、可回滚的制品:

- 触发:开发者 push、创建合并请求、合并主分支或创建版本标签时触发任务。
- 构建:安装锁定的依赖,编译代码,生成二进制包或 Docker 镜像。
- 快速反馈:优先运行单元测试、格式检查、类型检查和静态分析,让明显错误尽快返回。
- 深度验证:启动服务,运行集成测试、端到端测试、性能测试和依赖漏洞扫描。
- 制品管理:把通过验证的制品推送到仓库,并记录提交 SHA、版本号和构建日志。
- 部署决策:持续交付在生产前等待审批;持续部署自动进入生产。部署后还要检查健康状态和关键指标。
每个阶段都应该有明确的输入、输出和失败处理。例如,构建阶段输出 coupon-service:git-9f3a2c1 镜像,后面的测试和部署都使用这个不可变版本,而不是重新构建一份“看起来一样”的代码。
CI 持续集成具体做了什么?
持续集成的核心是“小步合并、自动验证、失败归属明确”。它把代码质量检查前移到合并请求阶段。

一次 CI 检查通常包含以下步骤:
- 拉取合并请求对应的代码和依赖锁文件。
- 使用与项目一致的运行时版本进行编译或打包。
- 运行单元测试,并保存测试报告和覆盖率结果。
- 执行代码格式、类型检查、静态分析和依赖安全扫描。
- 将结果回写到合并请求,阻止失败代码进入受保护的主分支。
以 GitHub Actions 为例,一个最小的 Node.js CI 可以这样写:
name: ci
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm test -- --ci
- run: npm run build
这里的重点不是 YAML 的具体写法,而是三个约束:依赖必须可锁定,检查必须在干净环境运行,失败结果必须回到提交者身边。这样“谁提交、谁修复”才有可执行的边界。
持续交付和持续部署如何把代码送上生产?
CI 通过后,CD 会把同一个制品逐级送过测试、预发布和生产环境。持续交付保留生产闸门,持续部署则把闸门也自动化。
一个可审计的 CD 流程通常如下:
- 构建一次 Docker 镜像并推送到镜像仓库。
- 在测试环境部署该镜像,执行接口、界面和性能测试。
- 通过后把同一个镜像提升到预发布环境,检查真实配置和依赖连接。
- 持续交付等待负责人确认;持续部署自动继续。
- 生产环境采用滚动更新、蓝绿发布或金丝雀发布,并持续观察错误率、延迟和资源指标。
“构建一次,到处运行”是 CD 的重要原则。环境差异应该体现在外部配置和密钥管理中,而不应该让每个环境重新编译出不同的程序包。
CI/CD 需要哪些工具?
工具可以替换,但角色不能缺失。一个完整的工具链通常包括五层:

| 工具角色 | 解决的问题 | 常见选择 |
|---|---|---|
| 版本控制 | 保存变更历史,触发合并请求和流水线 | Git、GitHub、GitLab |
| CI/CD 服务器 | 编排任务、缓存依赖、记录结果 | GitHub Actions、GitLab CI、Jenkins |
| 构建与测试 | 编译、打包、单元测试和静态检查 | Maven、Gradle、npm、JUnit、pytest |
| 制品仓库 | 保存可部署且可追溯的版本 | Docker Registry、Nexus、Artifactory |
| 部署与基础设施 | 把制品发布到目标环境 | Kubernetes、kubectl、Helm、Ansible |
小团队可以先用代码托管平台自带的流水线,减少维护 Jenkins 主机的成本;大团队则通常需要统一模板、权限、审计、缓存、构建集群和多项目复用能力。选型的标准是团队要解决的交付问题,而不是工具名称本身。
电商优惠券功能如何走完一次发布?
假设电商团队要上线优惠券功能,下面这条链路可以把 CI、CD 和发布策略串起来:

- 开发者在特性分支完成代码,创建合并请求。
- CI 拉取代码,构建服务,运行单元测试和静态代码分析。假设其中一个测试失败,合并请求显示红色状态。
- 开发者定位问题并修改代码,重新推送后再次触发 CI,直到所有检查通过。
- 同事完成 code review,代码合并到
main,CD 开始构建并推送 Docker 镜像。

- CD 用同一镜像部署测试环境,自动运行界面测试和性能测试。
- 发布负责人点击“发布到生产”,系统以滚动更新方式替换实例,并检查新旧版本的健康状态。
如果新版本的错误率超过阈值,流水线应自动停止继续发布,或者依据预先定义的策略回滚到上一个镜像版本。用户不需要知道背后执行了多少命令,但团队必须能回答“当前运行的是什么版本”和“如何在几分钟内退回上一版”。
小团队到大厂,CI/CD 应该如何逐步升级?
CI/CD 不需要一开始就建设成大厂规模。正确做法是先自动化最常失败、最容易重复的步骤,再随着发布频率和组织规模增加治理能力。
| 团队阶段 | 先解决什么 | 推荐做法 | 暂时不要做什么 |
|---|---|---|---|
| 1~5 人 | 手工构建和部署 | 一份主流水线,自动 lint、测试、构建;用托管 CI 和单一测试环境 | 一开始维护复杂的多集群平台 |
| 5~30 人 | 合并冲突和环境漂移 | 保护 main,合并请求必过 CI;制品版本化;测试环境自动部署 | 让每个项目各自发明一套发布脚本 |
| 多团队 | 权限、审计和发布并发 | 共享流水线模板、制品晋级、环境审批、密钥中心和统一观测 | 用人工表格记录发布状态 |
| 大厂或高风险业务 | 变更风险和规模化治理 | 金丝雀/蓝绿发布、自动回滚、策略即代码、供应链签名和灾备演练 | 把“全自动”当成不需要监控的理由 |
无论团队大小,都建议先定义三个指标:变更前置时间、部署频率和失败后的恢复时间。它们比“流水线有多少个阶段”更能说明交付系统是否真的变好了。
CI/CD 的常见风险和误区是什么?
自动化不会自动消除风险;它只会把团队原来的流程更快地执行。因此,以下问题必须在流水线中显式处理:
| 风险或误区 | 具体表现 | 改进方式 |
|---|---|---|
| 测试不稳定 | 同一提交偶尔通过、偶尔失败 | 隔离外部依赖,记录 flaky test,禁止长期忽略失败 |
| 只测单元测试 | 接口、数据库或配置问题上线才暴露 | 增加少量高价值集成测试和冒烟测试 |
| 制品不可追溯 | 生产包无法对应源码提交 | 用提交 SHA 或不可变版本标记制品,保留构建日志 |
| 密钥写进仓库 | Token 泄露后无法控制影响范围 | 使用 Secret Manager,最小权限,定期轮换 |
| 数据库变更不可回滚 | 应用回滚后旧版本无法读取新表结构 | 使用向后兼容的 expand/contract 迁移,并演练恢复 |
| 自动部署没有护栏 | 错误版本迅速扩散到全部实例 | 采用分批发布、健康检查、指标门禁和自动回滚 |
尤其要注意:CI 的“绿色”只说明已配置的检查通过,不等于软件在所有真实场景都正确。测试范围、数据质量、监控覆盖和回滚演练决定了自动化能把风险降低到什么程度。
CI/CD 带来的真正变化是什么?
CI/CD 的最终产出不是一张漂亮的流水线仪表盘,而是更短的反馈回路和更低的变更风险。代码质量、环境状态、发布进度和失败原因都被记录下来,团队可以基于同一份事实协作。

对开发者来说,自动化减少了重复操作,让注意力回到设计和实现;对测试和运维来说,统一的制品与日志减少了“在我机器上没问题”和“再试一次命令”的沟通;对产品团队来说,更短的交付周期让用户反馈能更快进入下一轮迭代。
常见问题
CI/CD 适合小团队吗?
适合。小团队可以从一份 GitHub Actions 或 GitLab CI 配置开始,只自动化依赖安装、测试、构建和测试环境部署,不必先搭建复杂平台。关键是让主分支始终可构建,并让失败结果立即可见。
CI 和 CD 的区别是什么?
CI 关注代码是否能安全合并,主要执行构建和自动化验证;CD 关注通过验证的制品如何进入各个环境。持续交付在生产前保留人工确认,持续部署则在自动化关卡通过后直接生产发布。
CI/CD 是否等于 DevOps?
不等于。CI/CD 是 DevOps 的重要工程实践,负责自动化集成、测试和交付;DevOps 还包括团队协作、基础设施即代码、可观测性、值班响应和持续改进等组织与技术机制。
为什么流水线通过了,线上仍然会出 bug?
因为流水线只验证它被配置来验证的内容。测试可能没有覆盖真实数据、第三方依赖、容量上限或迁移路径。补充高价值集成测试、生产监控、分批发布和可执行的回滚方案,才能覆盖测试之外的风险。
生产环境一定要持续部署吗?
不一定。需要审批、合规或业务窗口的团队可以选择持续交付,让所有准备工作自动完成,只保留最后的发布决策。持续部署适合变更可拆小、监控和回滚成熟、业务能够承受自动发布的系统。
总结:CI/CD 是现代软件工程的自动化骨架
CI/CD 把代码提交、构建、测试、制品管理和部署连接成一条可重复的流水线。持续集成让问题尽早暴露,持续交付让版本随时可发布,持续部署则把经过验证的变更直接送到生产。

从小团队到大厂,落地顺序都可以遵循同一个原则:先缩短反馈,再保证制品一致,最后用分批发布、观测和回滚控制风险。当发布从一次紧张的重大事件变成一项每天都能安全重复的普通操作,CI/CD 才真正发挥了价值。

