本节摘要:版本控制系统(VCS)是 CI 的起点——代码 push 或 PR 通过 Webhook 触发 CI Server。本节配置 GitHub Actions path filter、分支保护规则与 Jenkins multibranch,避免无关改动触发全量构建。
阅读完本节,你应当能够:
开发者 git push origin feature/login 后,GitHub 向 Jenkins URL 发送 POST:
{ "ref": "refs/heads/feature/login", "repository": { "full_name": "acme/webapp" }, "head_commit": { "id": "abc123", "message": "fix login timeout" } }
Jenkins Generic Webhook Trigger 或 GitHub Actions on: push 接收事件,创建一次 build。没有 Webhook,CI 就是定时任务,失去「持续」集成的意义。
on: push: branches: [main, 'release/**'] paths: - 'src/**' - 'pom.xml' - '.github/workflows/**' pull_request: branches: [main]
paths 忽略 docs/** 改动——避免改 README 触发 15 分钟 Java 全量构建。monorepo 可用 paths-filter action 输出 matrix。
GitHub Settings → Branches → main → Require status checks:
| 规则 | 目的 |
|---|---|
| Require PR before merge | 禁止直接 push main |
| Require status checks | ci/build, ci/test 必绿 |
| Require linear history | 可选,简化 bisect |
| Include administrators | 高管也遵守 |
pipeline { agent any triggers { githubPush() } stages { stage('Build') { steps { sh 'mvn -B verify' } } } }
Multibranch 自动为每个分支/PR 建 job——feature 分支 PR 跑 CI,merge 后 main 再跑一遍,防止「PR 绿、merge 后冲突」。
| 模型 | CI 触发频率 | 集成冲突 | 适用 |
|---|---|---|---|
| Trunk-based | 极高,短分支 | 少 | 互联网产品 |
| GitFlow | release 分支周期长 | 合并点集中 | 版本化软件 |
| GitHub Flow | main + feature PR | 中 | 中小型团队 |
⚠️ 常见坑:长期 feature 分支(2 周+)不 merge——CI 只在分支上绿,合 main 时爆炸。
💡 关键直觉:CI 频率与分支寿命成反比。Google 内部大量 trunk-based:小 commit、常集成。
workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == "main" - when: never build: rules: - changes: - src/**/* - package.json
MR 与 main push 才跑;其他分支 push 不消耗 runner 分钟。
| 场景 | 推荐 | 原因 |
|---|---|---|
| 开源协作 | PR only | fork 安全 |
| 内部主干 | push + PR | main 双保险 |
| 热修复 | tag push | v1.2.1 精确触发 |
parameters { choice(name: 'DEPLOY_ENV', choices: ['none', 'staging'], description: 'Deploy target') } when { expression { params.DEPLOY_ENV != 'none' } }
手动触发补跑夜间失败 build——不替代自动 Webhook,作备用。
问:Rebase 会重复触发 CI 吗?
答:会。每次 force-push 是新 commit SHA,属预期行为;可用 [skip ci] commit message 跳过(慎用)。
Webhook 交付失败是 CI「突然不跑」的头号原因。GitHub Settings → Webhooks → Recent Deliveries 看 HTTP 状态:502 多为 Jenkins 宕机,403 为 secret 不匹配,timeout 为 pipeline 未在 10s 内返回 200(应用需异步触发 build,先 200 再排队)。
services/ payment/ catalog/ gateway/
仅 payment/ 改动时,应用 dorny/paths-filter:
- uses: dorny/paths-filter@v3 id: filter with: filters: | payment: services/payment/** catalog: services/catalog/** - if: steps.filter.outputs.payment == 'true' run: cd services/payment && mvn verify
避免无关服务空跑 CI,节省 runner 成本——大型 monorepo 可省 70% 分钟数。
Google 内部大量工程师共用一个 trunk——靠极致自动化测试 + 强大基础设施支撑,中小团队可折中:main + 短 feature branch。
二进制资产(模型、视频)进 Git LFS——普通 clone 不拉 LFS 对象,CI 需 lfs: true checkout,否则构建缺文件。CI 缓存 LFS 层可显著加速。
下一节 2.2 构建阶段:Maven、npm 与 Docker 如何把源码变成制品。
触发策略的本质是「在正确的时间、用最小的成本、跑最相关的检查」。path filter 缩小范围,分支保护保证质量,PR 双跑防止 merge 意外——但这三者都要付出维护成本。实际落地时建议从简单开始:先所有 push 全量跑,再根据等待时长逐步加 filter。统计数据显示,触发过一次的构建里约有三分之一是因为依赖变更或配置文件导致的假失败,把工作流目录、构建描述文件、锁文件等关键路径加入触发白名单,能让绝大多数真实变更被正确覆盖。
另一个常被忽略的点是触发与并发的配对:Webhook 触发是「事件驱动」,而 CI 执行器是「队列驱动」,两者之间需要有明确的排队与取消策略。GitHub Actions 的 concurrency 组、Jenkins 的 disableConcurrentBuilds,都是为了防止同一分支的连续 push 排队互相覆盖结果。配置并发控制时,优先选择「取消旧构建、保留最新」,因为旧 commit 的结果对 merge 决策已经没有意义。