Know whether a pull request requires a major version bump before merging.
ApiBump detects semantic public API changes and recommends the correct SemVer bump. V1 is intentionally focused: a Rust CLI, a GitHub Action, and a Python backend powered by Griffe.
Real-repo dogfood report: April 27, 2026
Add this to a Python library repo:
name: API compatibility
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
apibump:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: anasm266/apibump@v1
with:
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.sha }}If the repo has one obvious Python package, ApiBump autodetects it. ApiBump writes a job summary, annotates the workflow, and updates one sticky PR comment.
Install the CLI:
cargo install apibumpInstall Griffe in the Python environment ApiBump should use:
python -m pip install "griffe>=1,<2"Run a check:
apibump check \
--base origin/main \
--head HEAD \
--format markdown \
--fail-on breakingWhen autodetect is ambiguous, pass --package and --search explicitly or add apibump.toml.
Stable JSON output is available with --format json:
{
"schema_version": "0.2",
"recommendation": "major",
"summary": {
"breaking": 1,
"additive": 0,
"internal": 0,
"unknown": 0,
"suppressed": 0
},
"packages": [
{
"package": "my_pkg",
"recommendation": "major",
"summary": {
"breaking": 1,
"additive": 0,
"internal": 0,
"unknown": 0,
"suppressed": 0
},
"changes": [
{
"package": "my_pkg",
"severity": "breaking",
"kind": "parameter_removed",
"symbol": "my_pkg.api.create_user",
"file": "src/my_pkg/api.py",
"line": 42,
"message": "Parameter was removed",
"backend": "griffe"
}
],
"suppressed_changes": []
}
],
"changes": [
{
"package": "my_pkg",
"severity": "breaking",
"kind": "parameter_removed",
"symbol": "my_pkg.api.create_user",
"file": "src/my_pkg/api.py",
"line": 42,
"message": "Parameter was removed",
"backend": "griffe"
}
],
"suppressed_changes": []
}Full workflow:
name: API compatibility
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
apibump:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: anasm266/apibump@v1
with:
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.sha }}
comment: trueThe action writes a job summary and updates one sticky PR comment. PR comments use GitHub's issue comments API because pull requests are issues in the REST API.
The fixtures/python-breaking example shows the core workflow:
base/hascreate_user(name, email).head/removes the publicemailparameter.- ApiBump reports
parameter_removedand recommendsmajor.
See docs/demo/apibump-report.json and docs/demo/apibump-report.md for the expected output shape.
Use apibump.toml when a repo contains multiple Python packages:
version = 1
[defaults]
selection = "changed"
fail_on = "breaking"
[[packages]]
package = "payments"
search = ["services/payments/src"]
roots = ["services/payments/src/payments"]
[[packages]]
package = "analytics"
search = ["services/analytics/src"]
roots = ["services/analytics/src/analytics"]See docs/configuration.md for config details and docs/why-not-griffe.md for the positioning.
Griffe is the Python API loader and breaking-change checker that powers ApiBump. ApiBump adds:
- repo-level package autodetection
- monorepo package selection
- conservative additive classification for
minorrecommendations - suppression rules through
apibump.toml - GitHub Action and PR-native reporting
If you already want a low-level Python API engine, use Griffe directly. If you want PR-level SemVer guidance for a repo, use ApiBump.
0: check completed and did not violate the configured--fail-onpolicy.1: check completed and violated--fail-on.2: CLI usage, I/O, serialization, or strict backend failure.
By default, backend failures become an unknown report and do not fail --fail-on breaking. Use --strict or --fail-on unknown for stricter CI.
ApiBump currently supports Python only. Python additive detection is intentionally conservative: clear public additions become minor, breakages become major, and ambiguous non-breaking changes become unknown. Future language adapters should normalize their findings into the same JSON schema.
