2.1 版本控制与触发策略


2.1 版本控制与触发策略

本节摘要:版本控制系统(VCS)是 CI 的起点——代码 push 或 PR 通过 Webhook 触发 CI Server。本节配置 GitHub Actions path filter、分支保护规则与 Jenkins multibranch,避免无关改动触发全量构建。

先说结论

阅读完本节,你应当能够:

  1. 解释 Webhook 如何将 Git 事件连接到 CI
  2. 配置 PR 必须通过 CI 才能 merge 的分支保护
  3. 使用 path filter 缩小触发范围
  4. 比较 trunk-based 与 GitFlow 对 CI 的影响

一、Push 之后发生了什么

开发者 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 就是定时任务,失去「持续」集成的意义。

二、触发策略设计

GitHub Actions 分支与路径过滤

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。

分支保护 + Required Checks

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 高管也遵守

Jenkins Multibranch Pipeline

pipeline { agent any triggers { githubPush() } stages { stage('Build') { steps { sh 'mvn -B verify' } } } }

Multibranch 自动为每个分支/PR 建 job——feature 分支 PR 跑 CI,merge 后 main 再跑一遍,防止「PR 绿、merge 后冲突」

Trunk-based vs GitFlow

模型 CI 触发频率 集成冲突 适用
Trunk-based 极高,短分支 互联网产品
GitFlow release 分支周期长 合并点集中 版本化软件
GitHub Flow main + feature PR 中小型团队

⚠️ 常见坑:长期 feature 分支(2 周+)不 merge——CI 只在分支上绿,合 main 时爆炸。

💡 关键直觉:CI 频率与分支寿命成反比。Google 内部大量 trunk-based:小 commit、常集成。

三、工程实践

GitLab CI 规则表达式

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 触发 vs Push 触发

场景 推荐 原因
开源协作 PR only fork 安全
内部主干 push + PR main 双保险
热修复 tag push v1.2.1 精确触发

Jenkinsfile 参数化手动触发

parameters { choice(name: 'DEPLOY_ENV', choices: ['none', 'staging'], description: 'Deploy target') } when { expression { params.DEPLOY_ENV != 'none' } }

手动触发补跑夜间失败 build——不替代自动 Webhook,作备用。

FAQ

问:Rebase 会重复触发 CI 吗?
答:会。每次 force-push 是新 commit SHA,属预期行为;可用 [skip ci] commit message 跳过(慎用)。

四、Webhook 排错与 monorepo 策略

Webhook 交付失败是 CI「突然不跑」的头号原因。GitHub Settings → Webhooks → Recent Deliveries 看 HTTP 状态:502 多为 Jenkins 宕机,403 为 secret 不匹配,timeout 为 pipeline 未在 10s 内返回 200(应用需异步触发 build,先 200 再排队)。

Monorepo path filter 进阶

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% 分钟数。

Trunk-based 实践细节

  • 分支寿命 < 1 天
  • feature flag 隐藏未完成代码
  • main 永远 deployable
  • revert 优于 fix-forward(当 fix 需 > 30 min)

Google 内部大量工程师共用一个 trunk——靠极致自动化测试 + 强大基础设施支撑,中小团队可折中:main + 短 feature branch。

Git LFS 与大文件

二进制资产(模型、视频)进 Git LFS——普通 clone 不拉 LFS 对象,CI 需 lfs: true checkout,否则构建缺文件。CI 缓存 LFS 层可显著加速。

重点提炼

  • Webhook 连接 Git 与 CI,是 CI 的心跳
  • path filter 降低无关构建成本
  • 分支保护 让 CI 成为 merge 硬门禁
  • Multibranch 为每个 PR 独立验证
  • Trunk-based 最契合高频 CI
  • GitLab rules 精细控制 pipeline 创建
  • PR + main 双跑 防止 merge 后意外

下一节 2.2 构建阶段:Maven、npm 与 Docker 如何把源码变成制品。

触发策略的工程权衡

触发策略的本质是「在正确的时间、用最小的成本、跑最相关的检查」。path filter 缩小范围,分支保护保证质量,PR 双跑防止 merge 意外——但这三者都要付出维护成本。实际落地时建议从简单开始:先所有 push 全量跑,再根据等待时长逐步加 filter。统计数据显示,触发过一次的构建里约有三分之一是因为依赖变更或配置文件导致的假失败,把工作流目录、构建描述文件、锁文件等关键路径加入触发白名单,能让绝大多数真实变更被正确覆盖。

另一个常被忽略的点是触发与并发的配对:Webhook 触发是「事件驱动」,而 CI 执行器是「队列驱动」,两者之间需要有明确的排队与取消策略。GitHub Actions 的 concurrency 组、Jenkins 的 disableConcurrentBuilds,都是为了防止同一分支的连续 push 排队互相覆盖结果。配置并发控制时,优先选择「取消旧构建、保留最新」,因为旧 commit 的结果对 merge 决策已经没有意义。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U