Docs

Capabilities

Contract Checks ​

Breaking-change checks for OpenAPI, GraphQL, protobuf and JSON Schema contracts, with the file and line on both sides of every break.

A renamed field in an API spec breaks every client that reads it; contract checks catch those breaks before release, for teams that publish APIs or schemas.

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: contract_checks.

Contract checks compare the API contracts a release changes, old against new, and report every change that breaks a client. They cover OpenAPI and Swagger specs, GraphQL schemas, protobuf files and JSON Schema payloads. Each finding gives the file and line on both sides, so you can see exactly what was and what is.

Contract checks run as part of every release check once the flag is on. There is nothing to configure.

Which files are checked ​

Format Detected when
protobuf The file ends in .proto
GraphQL The file ends in .graphql, .graphqls or .gql
OpenAPI / Swagger A .yaml, .yml or .json file with a top-level openapi or swagger key
JSON Schema A .yaml, .yml or .json file whose name ends in .schema.json, or whose $schema names a JSON Schema

Files under testdata/, fixtures/, __fixtures__/, examples/, example/ or samples/, and generated files, are skipped. Both versions of a file must be the same format to be compared.

The CLI (bumpkit check, bumpkit gate) sends the old and new text of each changed contract with the check, up to 20 files of at most 1 MB each. The GitHub App fetches them from the repository instead. Each file reports at most 50 changes, breaking ones first.

A contract file that is deleted is a break ("Removed the OpenAPI contract …"), unless a file with the same name and format was added elsewhere in the same release; then the two are compared as a move.

Findings ​

Kind Severity Meaning
contract_breaking high The change breaks existing clients
contract info A compatible change, such as a new operation, field or enum value, or a deprecation

Findings come from the contracts checker, with deterministic evidence and high confidence. A contract_breaking finding makes the release a major version bump. The detail reads "Was: … (file:line). Now: … (file:line)."

What counts as breaking ​

OpenAPI ​

  • Removing an operation, or a parameter
  • Making a parameter or the request body required, adding a required parameter, or requiring a request body where there was none
  • Changing the security scheme or the authentication an operation requires
  • No longer accepting a request media type, or no longer returning a response media type
  • Removing a success response
  • Changing a property's type or format in a way the other side can't handle (narrowing what a request accepts, or widening what a response returns)
  • Closing an object to properties it doesn't list (additionalProperties)
  • Restricting a value to a fixed set (enum), or removing an enum value that requests use
  • Removing a response property, making a property required, or making a response property no longer always present
  • Adding a required property to a request

GraphQL ​

  • Removing a type, field, argument, enum value or union member
  • Changing a type's kind, such as an object to an interface
  • Changing a field's type, or an argument's type, unsafely
  • Adding a required argument or required input field
  • A type no longer implementing an interface

protobuf ​

  • Changing the package
  • Removing a message, enum, service or RPC
  • Changing an RPC's request or response type or streaming
  • Removing a field or enum value without reserving its number
  • Renaming a field (the binary encoding is unchanged, but JSON clients and generated code break)
  • Changing a field's number, type or cardinality, or moving it into or out of a oneof
  • Reusing a reserved number or name, or no longer reserving one

Removing a field and reserving it is reported as a compatible change.

JSON Schema ​

A JSON Schema payload is compared in both directions, as data that is both sent and received. Type and format changes, closing an object, restricting or removing enum values, removing properties and making properties required are all breaking.

Use them in the gate ​

contract_breaking findings work with the usual policy keys:

YAML
gate:
  block_on: [secret, data_loss, contract_breaking]
  require_approval:
    - contract_breaking
  hotfix:
    block_on: [breaking, contract_breaking, data_loss, migration]
  • block_on accepts contract_breaking to fail on any high-severity break.
  • require_approval accepts a contract_breaking rule. The breaking rule also asks for approval on contract breaks.
  • hotfix.block_on accepts contract_breaking, and includes it by default.

Without a policy entry, a contract break gives the check a review verdict and needs approval under the default breaking rule.

Compatibility matrix ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: compatibility_matrix.

The compatibility matrix is an explicit table of the version pairs you support: client vX with server vY, SDK with API, schema with app. Each pair gets one verdict, read from your recorded release checks:

Verdict What it means
compatible Every recorded release of the provider inside the range was checked in full, and none has a proven break.
breaking A recorded release inside the range has a proven break. The pair names it, with its file and version. Later versions in the range carry it.
not_checked The evidence isn't complete, and the pair says why. Not checked never means compatible.

There are no AI verdicts and no percentages. Bumpkit doesn't run your client against your server: a verdict states what the provider's recorded checks prove.

Set it up ​

  1. Get access to compatibility_matrix, contract_checks and version_consistency. A check run without contract checks or version consistency counts as not checked.
  2. Declare your components and the ranges you support in bumpkit.yml:
YAML
compatibility:
  components:
    - name: web
      role: client
      repository: acme/web
    - name: api
      role: server
      paths: ["openapi/**", "proto/**"]
    - name: db
      role: schema
      paths: ["db/migrations/**"]
  supported:
    - consumer: web
      consumer_versions: ">=1.4.0 <2.0.0"
      provider: api
      provider_versions: ">=2.0.0"
    - consumer: api
      consumer_versions: ">=2.0.0"
      provider: db
      provider_versions: ">=2.0.0"
  1. Run the gate, which reads the section every time, or read it now:
Terminal
bumpkit compatibility sync --repository acme/api
  1. Open Release decisions, or run bumpkit compatibility. Each row leads with a status lamp. Open a row to see the pair version by version. See compatibility in bumpkit.yml for every key.

Where a verdict comes from ​

Bumpkit looks at the provider's repository and the recorded releases inside provider_versions. A version counts as released once Bumpkit published it or a check ran with that version's tag as its head. A check counts when both its previous version and its new version are inside the range.

Provider role What counts as a break
client, server, sdk, api, app contract_breaking findings from these contract checks, and breaking findings such as a removed export or route
schema data_loss findings from migration safety checks, such as a dropped table or column

A break counts when it is high severity, deterministic, not marked as a false positive, and inside the component's paths. With no paths, the whole repository counts.

A pair is not checked when a release in the range has no recorded check, the diff was too large to check in full, contract checks or version consistency weren't on, a contract file couldn't be read on both sides, version consistency disputes the version number, or data retention deleted the check's findings. Checks recorded before you turned on compatibility_matrix don't count either.

Block a release that breaks a pair ​

The rule is opt-in. Without it, the gate only reports the break:

YAML
gate:
  block_on: [secret, data_loss, compatibility_break]

The gate reads the pairs in the bumpkit.yml of the repository it runs on, and applies each pair whose provider is that repository. A release breaks a pair when its previous and new versions are both inside provider_versions. A proven break makes a release a major version, so a closed range such as >=2.0.0 <3.0.0 doesn't cover the release that leaves it: 3.0.0 isn't a version you declared as supported. To block that release, leave the range open, such as >=2.0.0.

A pair the gate can't prove adds a compatibility_not_checked finding, which never blocks.

Export it for a procurement review ​

Use Export CSV or Export JSON on the Release decisions page, or the CLI:

Terminal
bumpkit compatibility export --format csv > compatibility.csv

The CSV has one row for each pair, with provider_version set to all in range, then one row per version and per break, with the file, line and check it came from.

Internal contract alerts ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: contract_alerts.

Contract checks cover the contracts you publish. For code shared between branches, bumpkit contracts alerts other open branches when a Go function, method or type they call changes signature:

Terminal
bumpkit contracts sync
bumpkit contracts alerts --branch feature/export
bumpkit contracts ack ALERT_ID
bumpkit contracts close --branch feature/export

Run sync on every push, in CI or from an agent. It records this push's Go signature changes and the symbols the branch calls; branches calling an old signature are alerted by pull request comment, webhook and MCP. See Agent Swarms.

↑↓ to move, Enter to open