CI是强制性的协作节奏,要求每日多次向main分支提交代码并自动执行完整验证流程,任一环节失败即阻断合入。

CI不是“加个Jenkins就叫持续集成”
持续集成(CI)在DevOps中不是一套工具,而是一种强制性的协作节奏:开发人员必须每天多次把代码推到 main 分支,且每次推送后,系统自动完成 git pull → 编译 → 运行单元测试 → 静态扫描 全流程。只要其中任意一环失败(比如一个 test_login_timeout 用例报错),这次提交就不能合入主干——不是“先合并再修”,而是“不通过就不许进”。很多团队装了 GitLab CI 却仍每周合并一次大包代码,这本质上仍是手工集成,CI 形同虚设。
为什么 CI 失败常卡在“本地能跑,CI 报错”
这是环境不一致导致的典型症状,不是 CI 本身的问题,而是没把“可重现性”作为硬约束。常见原因包括:
-
node_modules或venv被提交进仓库,导致本地依赖和 CI 环境版本错位 - 测试用例依赖本地配置文件(如
.env.local),而 CI 流水线没注入等效变量 - 数据库测试用内存 SQLite,但 CI 脚本误连了宿主机 PostgreSQL 实例
- 时间相关断言(如
assert now() > yesterday)在 CI 容器时区未显式设置为UTC,偶发失败
解决方式很简单:所有环境变量、依赖安装、数据库初始化,都必须写进 .gitlab-ci.yml 或 Jenkinsfile 的 stage 步骤里,禁止任何“默认存在”的假设。
CI 流水线该跑哪些测试,按什么顺序
不是测试越多越好,而是要分层拦截、快速反馈。推荐最小可行流水线顺序如下:
-
lint:用eslint/flake8检查语法与风格,10 秒内失败即停,不进下一阶段 -
build:执行npm run build或mvn package,验证能否产出可部署产物 -
unit-test:纯内存运行,无外部依赖,覆盖率建议 ≥70%,单测失败直接阻断 -
integration-test:连接真实 DB/API,用 Docker 启postgres:15和mock-server,耗时较长,可并行或只在main分支触发
跳过 UI 测试 或 性能压测 不是偷懒——它们反馈慢、不稳定、定位难,应放在 CD 阶段或单独调度,别拖慢开发日常反馈闭环。
CI 成功率跌到 80% 以下时,团队该立刻做什么
这不是优化问题,是流程已崩溃的信号。此时必须暂停新功能开发,全员聚焦三件事:
- 把最近 3 次失败的
CI job log导出,人工比对共性错误(比如全卡在timeout: connect ECONNREFUSED 127.0.0.1:3000,说明服务启动脚本漏写了&) - 检查是否有人绕过保护机制,直接
force push到main,或关闭了require CI pass的分支保护规则 - 删掉所有“临时注释掉的测试用例”,CI 不接受“先过再说”的妥协;若某测试长期 flaky,就重写它,而不是禁用它
CI 的价值不在“能跑”,而在“敢信”——当开发人员看到绿色勾号,就知道此刻的 main 分支真能编译、真能通过核心路径测试、真能作为发布基线。这点确定性,没法靠加班补,只能靠纪律守。










