Skip to content
Back to skills

Protobuf Compat Checking

ASecurity

Wraps `buf breaking` to compare a Protobuf schema against a past version, classifies breaking changes by category (FILE / PACKAGE / WIRE_JSON / WIRE), configures buf.yaml rule selection plus per-path exemptions, and gates CI on the exit code. Use when reviewing `.proto` changes in a PR for gRPC services, BSR modules, or schema-versioned message bus payloads.

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 12, 2026
testinggobashgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 12, 2026

npx -y skills add testland/qa --skill protobuf-compat-checking --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Protobuf Compat Checking?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Protobuf Compat Checking
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/testland-protobuf-compat-checking/badge)](https://www.skillsdirectory.com/skills/testland-protobuf-compat-checking)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: protobuf-compat-checking
description: "Wraps `buf breaking` to compare a Protobuf schema against a past version, classifies breaking changes by category (FILE / PACKAGE / WIRE_JSON / WIRE), configures buf.yaml rule selection plus per-path exemptions, and gates CI on the exit code. Use when reviewing `.proto` changes in a PR for gRPC services, BSR modules, or schema-versioned message bus payloads."
---

# protobuf-compat-checking

## Overview

`buf breaking` is the canonical Protobuf compatibility checker from
the Buf project ([buf-breaking][breaking]). It compares the current
schema against a **past version** (BSR module, Git ref, tarball, or
buf image) and reports changes that would break clients, servers, or
generated code.

[breaking]: https://buf.build/docs/breaking
[buf-yaml]: https://buf.build/docs/configuration/v2/buf-yaml

This is the Protobuf-specific counterpart to
`openapi-contract-diff` (REST) and
`graphql-schema-regression`
(GraphQL).

## When to use

- The repo has `.proto` files (gRPC service definitions, message-bus
  schemas, internal data contracts).
- The team uses Buf Schema Registry (BSR) or git-versioned Protobuf
  modules.
- A CI gate is needed on schema regressions before pushing a new
  version of generated client / server code.
- The team needs **per-category** strictness - e.g. FILE-level checks
  during early development, downgrade to WIRE for stable v1+ APIs
  where source-level changes are acceptable but wire-format breakage
  is not.

## Breaking categories

`buf breaking` rules ship in four nested categories - **stricter
subsumes looser** ([buf-breaking][breaking]):

| Category    | Detects                                                 |
|-------------|---------------------------------------------------------|
| `FILE`      | Source-code breakage per-file. **Default**; strictest.  |
| `PACKAGE`   | Source-code breakage per-package.                       |
| `WIRE_JSON` | Wire-format **or** JSON-encoding breakage.              |
| `WIRE`      | Wire-format breakage only. Loosest.                     |

Choose `FILE` for new internal services where source compatibility
matters; choose `WIRE_JSON` for stable APIs where source rearrangement
(e.g. moving a message between files) is acceptable but JSON-mapping
breakage is not; choose `WIRE` only when JSON encoding is
out-of-scope.

## Configuration

`buf.yaml` v2 form ([buf-yaml][buf-yaml]):

```yaml
version: v2
modules:
  - path: proto
    name: buf.build/acme/foo
breaking:
  use:
    - FILE
  except:
    - FILE_NO_DELETE          # allow file deletions despite using FILE
  ignore:
    - foo/legacy/             # exclude entire path from all breaking rules
  ignore_only:
    FILE_NO_DELETE:
      - foo/bar.proto         # exclude specific path from a specific rule
  ignore_unstable_packages: true   # ignore v1alpha1 / v1beta1 / *test* packages
```

`version: v2` is required for the structure above; legacy `v1` and
`v1beta1` files use a different shape ([buf-yaml][buf-yaml]). When
migrating, run `buf migrate v1tov2` to convert.

`ignore_unstable_packages: true` is the canonical pattern - Protobuf
convention is that `v1alpha1`, `v1beta1`, and `*test*` packages are
unstable and explicitly NOT covered by compatibility guarantees.

## Running

### Against a Git reference

```bash
buf breaking --against '.git#branch=main'
buf breaking --against '.git#tag=v1.2.0'
buf breaking --against '.git#ref=HEAD~1'
```

(Per [buf-breaking][breaking].)

The `.git#...` syntax tells buf to checkout the referenced ref into a
temp directory and use it as the baseline. This is the most common CI
pattern: compare PR against `main`.

### Against a BSR module

```bash
buf breaking --against buf.build/acme/foo
buf breaking --against buf.build/acme/foo:<commit-sha>
```

Use the BSR baseline when the team treats BSR as the source of truth
and a release labeled `v1` is what production is consuming.

### Against a tarball or buf image

```bash
buf breaking --against archive.tar.gz
buf breaking --against image.bin       # buf-image-format binary
```

Useful for hermetic builds where the baseline is published as an
artifact rather than a git ref.

## Reading the report

`buf breaking` exits non-zero on detected breaking changes. The
default output prints one line per finding with the offending file,
line, column, rule ID, and message:

```
proto/orders/v1/order.proto:42:3:Field "1" with name "amount" on message
"Order" has the same number as deleted field with name "total".
[ENUM_VALUE_NO_DELETE_RESERVED]
```

For machine consumption, supply `--error-format json`:

```bash
buf breaking --against '.git#branch=main' --error-format json
```

```json
{
  "path": "proto/orders/v1/order.proto",
  "start_line": 42,
  "start_column": 3,
  "type": "ENUM_VALUE_NO_DELETE_RESERVED",
  "message": "Field 1 ..."
}
```

Pipe to `jq` for triage:

```bash
buf breaking --against '.git#branch=main' --error-format json | \
  jq -r '"\(.type) \(.path):\(.start_line) - \(.message)"'
```

## CI integration

### GitHub Actions

The Buf project ships an official Action (`bufbuild/buf-action`) that
runs lint + breaking + push against BSR in one job. For self-hosted
breaking-only:

```yaml
# .github/workflows/buf-breaking.yml
name: buf-breaking

on:
  pull_request:
    paths:
      - '**/*.proto'
      - 'buf.yaml'
      - 'buf.lock'

jobs:
  breaking:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0   # need history for `.git#branch=main` baseline

      - uses: bufbuild/buf-setup-action@v1

      - name: buf breaking
        run: buf breaking --against '.git#branch=main,subdir=.'
```

`fetch-depth: 0` is required so the `.git#branch=main` ref resolves - 
the default shallow clone doesn't have it.

For stricter pipelines, also gate on `buf lint`:

```yaml
- name: buf lint
  run: buf lint
- name: buf breaking
  run: buf breaking --against '.git#branch=main,subdir=.'
```

### Tag-based releases

For projects using git tags as release boundaries:

```bash
# Compare PR vs the latest released tag
LATEST_TAG=$(git describe --tags --abbrev=0)
buf breaking --against ".git#tag=${LATEST_TAG}"
```

This catches breaking changes vs production, not just vs the trunk
HEAD - useful when `main` itself contains in-progress un-released work.

## References

- [buf-breaking][breaking] - `buf breaking` semantics, categories,
  baseline reference formats.
- [buf-yaml][buf-yaml] - v2 `buf.yaml` configuration; `breaking.use`,
  `except`, `ignore`, `ignore_only`, `ignore_unstable_packages`.
- `openapi-contract-diff` - REST
  counterpart.
- `graphql-schema-regression` - GraphQL counterpart.
- `contract-compatibility-gate` - gate skill aggregating breaking-change verdicts across protocols.

Files in this skill

  • .tessl-plugin/plugin.json500 B
  • SKILL.md6.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.