必须在合并前完成自动化构建与验证,否则ci会失败、pr被阻塞、甚至污染develop分支;pre-commit不能替代ci,因其仅本地运行、环境不可控;唯一可信验证是ci,在干净容器中强制执行;通过分支保护规则(如require status checks)卡住合并;ci脚本应按目标分支决定验证粒度,优先变更模块测试,避免e2e等非必要项;环境不一致是本地与ci结果差异主因,需统一命令路径并清理缓存。

必须在合并前完成自动化构建与验证,否则 CI 会失败、PR 被阻塞、甚至污染 develop 分支。
pre-commit 钩子能否替代 CI 构建验证?
不能。pre-commit 只运行在本地,无法保证所有人启用、也无法复现 CI 环境(如 Node 版本、Python 依赖隔离、测试覆盖率阈值等)。它适合做快速 lint 或格式化,但不能替代 CI 中的 npm test、pytest 或 make build。
- pre-commit 可以拦截明显错误(比如未格式化的 Python 文件),但不会跑完整单元测试套件
- CI 是唯一可信的验证环节,因为它在干净容器中执行,且强制触发
- 如果跳过 CI 直接 merge,
git push origin develop后可能立刻触发 pipeline 失败,需回滚
如何让 PR 自动触发构建并卡住合并?
关键不是“怎么触发”,而是“怎么卡住”——靠分支保护规则(Branch Protection Rules)。
- 在 GitHub/GitLab 设置中,对
develop(或main)分支启用保护:勾选Require status checks to pass before merging - 确保 CI 工具(如 GitHub Actions、GitLab CI)的 job 名称被正确填入“Status checks”列表,例如
ci/test、build - 不要只依赖
required pull request reviews,即使有 2 人 approve,若 CI 没过,按钮仍是灰色不可点 - 推荐加一条:
Include administrators也受保护,避免维护者绕过检查
CI 构建脚本里该验证什么?
不是越全越好,而是按合并目标分支决定验证粒度。向 develop 合并时,重点验证集成可行性;向 main 合并时,才需全量回归。
- 必做项:
git diff --name-only origin/develop...HEAD找出变更文件,只对相关模块跑单元测试(节省时间) - 建议项:检查
package-lock.json或poetry.lock是否提交,避免依赖漂移 - 可选但强烈推荐:
pylint/eslint严格模式 +prettier --check,失败即 exit 1 - 避免项:不要在 CI 中运行 e2e 测试或部署到测试环境——那是合并后 pipeline 的事
本地验证不通过,但 CI 显示 success?
常见于环境不一致:比如本地用 node v18,CI 用 v20;或本地装了全局 typescript,CI 用的是 node_modules/.bin/tsc。
- 始终用
npx tsc、npx pytest而非全局命令,确保路径一致 - CI 脚本开头加
echo "Node: $(node -v), NPM: $(npm -v)",和本地输出对比 - Python 项目注意
venv是否激活、pip install -e .是否漏掉 - 最省事的排查方式:
git clean -fdx && npm ci && npm test在本地重演 CI 步骤
真正容易被忽略的,是 CI 缓存策略——比如误缓存了 node_modules 却没随 package.json 变更自动失效,导致旧依赖偷偷生效。每次修改依赖后,手动清一次缓存比猜问题快得多。











