Wraps the buf CLI for protobuf PR gating: `buf build` (compile .proto), `buf lint` (STANDARD rules: snake_case fields, Service suffix), `buf breaking --against {ref}` (detect wire/codegen breakage vs a git/BSR baseline), and `buf format`. Use as the CI proto-lint + breaking-change gate, or to debug a breaking failure by rule ID (e.g. FIELD_NO_DELETE_UNLESS_NUMBER_RESERVED) and pick the FILE/PACKAGE/WIRE_JSON/WIRE ruleset per consumer. This is the detection TOOL that enforces the rules; for the catalog of what is breaking and why use protobuf-versioning-strategy-reference, and for cross-service schema contract testing use protobuf-compat-checking - not this.
70
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Gate buf build, buf lint, and buf breaking on every PR that touches
.proto, buf.yaml, or buf.gen.yaml. All three must pass before merge.
# .github/workflows/proto-gate.yml
name: proto-gate
on:
pull_request:
paths:
- "**/*.proto"
- "buf.yaml"
- "buf.gen.yaml"
jobs:
buf:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # Required for `--against ".git#branch=main"`
- uses: bufbuild/buf-setup-action@v1
with:
buf_user: ${{ secrets.BUF_USER }}
buf_api_token: ${{ secrets.BUF_API_TOKEN }}
- run: buf build
- run: buf lint
- run: buf breaking --against ".git#branch=main"Key: fetch-depth: 0 so git has the baseline commit available. fetch-depth: 1
makes buf error because it cannot reach the baseline.
The official bufbuild/buf-setup-action and bufbuild/buf-breaking-action are
convenient but the raw CLI calls above work without them.
- if: failure()
uses: marocchino/sticky-pull-request-comment@v2
with:
header: proto-gate
message: |
❌ `buf breaking` failed. See log:
```
${{ steps.breaking.outputs.stdout }}
```
Consult
protobuf-versioning-strategy-reference
for whether this change is genuinely required and how
to do it safely (reserve, add new, deprecate old).