本节摘要:buf 把第 4 章的 protoc 流水线重新工程化——进程内编译替代插件进程、内置 lint 规则集、与远端基准比对的 breaking 检测、统一的 generate 管理。本节拆解这四大件如何组装成一条契约 CI,并把第 5 章的人脑评审规则逐步交给机器。读完你应当能为团队搭起"提交即校验"的契约治理流水线。
工程化投影。第 4 章你已经看过 protoc 的古典管道设计(stdin/stdout 插件协议)——它的开放性换来了生态繁荣,代价是调用开销与工程化管理缺位;buf 就是为补齐后者而生。
编译:buf 自带解析器,进程内完成第 4.1 节的全部前端工作,产出描述符的速度比逐文件调 protoc 快得多(免去进程创建与重复解析依赖)。它同时兼容既有插件——protoc 生态的生成器可以直接挂上,不要求迁移。
lint:内置规则集分档(BASIC、DEFAULT、加注释档),覆盖第 2 章立的多数规矩:package 命名格式、字段编号风格、枚举首值命名、导入只用于类型不引入副作用等。规则可按目录粒度覆盖——存量工程的脏文件可以豁免、新目录从严,落地成本骤降。
breaking:这是核心件。命令形如:
buf breaking --against 'https://your-schema-repo.git#branch=main,subdir=proto'
原理:拿当前描述符树与基准(远端仓库、基准 commit、或 BSR 远端模块)比对,执行第 5 章人脑评审的机器化——字段编号删除、wire type 变更、字段类型收窄、required 引入、枚举值删除等操作按 5.2 节的分级表逐条裁决,违反即非零退出。CI 里接上它,等于给每次 PR 配了一个永不疲倦的兼容性评审员。
generate:把第 4 章散落的 protoc 命令行收进配置文件——生成目标、插件、输出路径、按文件匹配的粒度控制,全部声明在版本库里。protoc 命令行"被重构弄丢参数"的 4.1 节事故,在这里结构性消失(配置进库,变更走 review)。
流水线的最小可用形态:
# 每次 PR 触发,三道门 buf lint # 门1: 风格与结构 buf breaking --against '../main-branch/proto' # 门2: 兼容性 buf generate && git diff --exit-code gen/ # 门3: 生成物同步校验
第三道门的逻辑:CI 重新生成代码后检查与提交的生成物有无差异——有差异说明提交者忘了重新生成(第 4.2 节"源与产物版本错位"事故的门禁化)。生成物是否入库是团队策略题(入库则门 3 如上;不入库则删除门 3、构建时生成),两种策略都成立,混着用才危险。

内置规则之外,团队的第 2、5、7 章纪律可以有选择地机器化。路径一:lint 的自定义规则(部分版本支持检查器扩展);路径二:第 4.3 节的自定义插件——遍历描述符做团队专属检查(比如"repeated 字段必须在热区编号"的第 7.2 节清单项、"新 string 字段必须带 log_mask 标注"的第 6.1 节脱敏纪律)。原则保持:能进描述符的纪律才机器化,语义级判断(铁律三"偷换概念")永远留给 review——第 5 章的六问清单里,前三问交给 buf breaking,后三问留给机器加人。
背景:一个演进六年的 proto 工程(第 2.1 节做过编号清算的那个),要接 buf 治理。直接开 lint 会爆出数百条违规。操作:分三步接驳。第一步建 buf 配置,lint 只开 BASIC 档,存量目录整体豁免、新增目录按 DEFAULT 档——门 1 以"增量从严"落地。第二步 breaking 以当前主干为基准快照入库,门 2 从零成本开始(只拦新增违规)。第三步把第 2.1 节清算产出的污染编号清单写进文档,配合自定义插件在 CI 里检查新 PR 是否触碰污染编号。结果:三周后存量违规被顺手清零(每次触碰文件必须顺手修 lint),新违规从进库前被拦。解读:接驳策略的关键是门禁的初始成本要压到零——任何"一次性大扫除"式的治理上线都会被业务压力冲垮;增量从严是契约治理唯一可持续的落地姿势。变式:团队若采用 BSR(远端模块仓库),基准切换为远端模块,跨仓库的契约依赖也能进 breaking 视野——多团队契约治理的完整形态。
再多说一句 buf 与既有 protoc 工程的关系:两者不是替代关系而是分工关系。buf 管治理面(lint、breaking、生成的配置化),protoc 生态的各类专用生成器(各语言的 protoc-gen-xxx、乃至第 4.3 节自写的文档插件)继续管生成面——buf 的 generate 配置可以直接调用这些既有插件,迁移不需要推倒重来。实践中分两步走最稳:第一步只上 lint 加 breaking(治理收益立现、生成路径不动),第二步再把散落的生成命令收进 generate 配置。一口气全迁移的方案在多团队环境里几乎必然被搁置,而"第一步的收益"已经足够让契约治理从口号变成日常。
工程化投影完成,最后看互操作投影:官方 JSON 映射的取舍点、网关转码、以及"对外 API 用不用 protobuf"的架构裁决。