Capabilities
Cross-Repo Impact
See which of your repositories a breaking change hits, with call sites, and get upgrade pull requests proposed when your dependencies release.
A change that is safe in one repository can break the services that depend on it; cross-repo impact shows who is affected, for teams running many connected repositories.
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it.
Bumpkit builds a service graph of your workspace: which repositories publish which packages and API contracts, and which repositories consume them. It uses the graph in two ways:
| Feature | What it does | Flag |
|---|---|---|
| Cross-repo impact | When a release breaks a public API or contract, the gate lists every consuming repository and its call sites. | cross_repo_impact |
| Dependency upgrade autopilot | When a dependency your repositories use releases a new version, Bumpkit proposes an upgrade pull request for each repository. | dependency_autopilot |
Both need the Bumpkit GitHub App installed on the repositories. See Integrations.
Multi-repo release trains use the same graph to ship across repositories in dependency order, and show it as a service map.
The service graph
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:cross_repo_impact.
For every repository the GitHub App can see, Bumpkit reads the default branch and records what the repository provides and consumes.
| File | Provides | Consumes |
|---|---|---|
go.mod |
The Go module (go). |
Each require line (go), marked direct or indirect. |
package.json |
The package (npm), unless "private": true. |
dependencies, devDependencies and peerDependencies (npm). |
pyproject.toml |
The project (pypi) from [project] or [tool.poetry]. |
[project] dependencies and [tool.poetry.dependencies] (pypi). |
requirements*.txt |
Each requirement (pypi). |
|
pom.xml, build.gradle, build.gradle.kts, *.versions.toml, *.sbt |
The artifact it builds (maven). |
Its dependencies (maven). |
*.csproj, Directory.Packages.props, Directory.Build.props, packages.config |
The NuGet package (nuget). |
Its package references (nuget). |
Gemfile, Gemfile.lock, *.gemspec |
The gem, from *.gemspec (rubygems). |
Its gems (rubygems). |
composer.json, composer.lock |
The package (composer). |
require and require-dev (composer). |
pubspec.yaml, pubspec.lock |
The package (pub). |
Its dependencies (pub). |
mix.exs, mix.lock |
The application (hex). |
Its dependencies (hex). |
Cargo.toml, Cargo.lock |
The crate (cargo). |
Its dependencies (cargo). |
CMakeLists.txt, conanfile.txt, conanfile.py, vcpkg.json |
The library it builds (cmake). |
Its packages (cmake). |
Package.swift, Package.resolved |
The package (swiftpm). |
Its packages (swiftpm). |
*.proto |
The proto package (proto). |
Each import, except google/ ones (proto_import). |
*.graphql, *.graphqls |
A GraphQL schema (graphql). |
|
OpenAPI or Swagger files (.yaml, .yml or .json with openapi or swagger in the name) |
The API, named by info.title (openapi). |
|
*.schema.json with an $id |
The JSON Schema (jsonschema). |
These are the manifests of the 15 languages Bumpkit reads; see Supported Languages. Bumpkit skips files under .git, node_modules, vendor, testdata, third_party, dist, build, fixtures, __fixtures__, examples, example and samples.
A repository consumes another when:
- It depends on a package the other publishes, matched by ecosystem and name.
- It has a copy of a contract the other publishes, matched by kind and name.
- It imports a
.protofile the other publishes, matched by path.
When the graph refreshes
- On every push to a repository's default branch.
- When the GitHub App is installed, or repositories are added to an installation.
- When an owner or admin calls
POST /v1/service-graph/refresh.
Each refresh is recorded in the workspace audit log.
Cross-repo impact in the gate
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:cross_repo_impact.
When the Release Gate runs on a repository in the graph, Bumpkit looks at its high-severity, deterministic breaking findings:
breakingfindings from theexportschecker: a removed public symbol or a changed signature.contract_breakingfindings from Contract Checks.
For each break, Bumpkit finds the repositories that consume the package or contract and looks in each one's default branch for the changed name or route.
Each affected repository becomes one consumer_break finding from the cross_repo checker:
| Result | Severity | Detail |
|---|---|---|
| Call sites found | high | How the repository depends on the change, what changed, and up to 3 call sites per file as path:line: code. |
| No call sites found | medium | How the repository depends on the change. The dependency is proven, but no use was found. |
Breaks acme/web: Removed public Client.Charge
acme/web depends on github.com/acme/payments v1.8.0 (go.mod:12).
Changed: Removed public Client.Charge.
Call sites:
services/checkout/pay.go:41: res, err := client.Charge(ctx, order.Total)If Bumpkit can't read the graph or can't search every consuming repository, it adds a cross_repo_check_unavailable finding, such as "Couldn't search for call sites in 2 of 12 consuming repositories".
On pull requests checked by the GitHub App, Bumpkit also posts a "Bumpkit cross-repo impact" comment that lists each affected repository, and updates the same comment on later runs.
Gate policy
Set what consumer breaks do under gate.cross_repo in bumpkit.yml:
gate:
cross_repo:
block_on_consumer_break: true| Key | Default | Description |
|---|---|---|
block_on_consumer_break |
false |
Fail the gate when the change breaks code in a consuming repository. |
require_approval |
true |
Ask for an approval when the change breaks code in a consuming repository. |
Only high-severity consumer_break findings, the ones with call sites, trigger these rules. When the check was incomplete (cross_repo_check_unavailable), the gate always asks for an approval, even with require_approval: false, so a gap in the search never passes silently.
The gate reasons are named cross_repo.block_on_consumer_break and cross_repo.require_approval. See cross_repo in the bumpkit.yml reference.
Dependency upgrade autopilot
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:dependency_autopilot.
The autopilot watches the Go module proxy, npm and PyPI for new versions of the dependencies in your service graph. It scans every 6 hours, and when an owner or admin calls POST /v1/autopilot/scan.
It considers direct dependencies pinned to a single version:
| Ecosystem | Pinned forms |
|---|---|
| Go | v1.2.3 in go.mod |
| npm | 1.2.3, ^1.2.3, ~1.2.3, =1.2.3 |
| PyPI | ==1.2.3, ~=1.2.3 |
Ranges such as >=1.0 are skipped. Each scan checks up to 100 distinct packages.
Breaking or routine
Bumpkit marks an upgrade as breaking when any of these hold:
- A Go module moved to a new major version module path.
- The version is a major change under semver, or a minor change below 1.0.
- The GitHub release notes for the new tag mention "breaking".
- For Go, the exported API differs between the two versions: symbols removed, renamed or changed.
Each proposal gets a priority:
| Priority | When |
|---|---|
security |
The current version has a known vulnerability in OSV. |
breaking |
The upgrade is breaking. |
routine |
Anything else. |
Proposals are listed security first, then breaking, then routine.
What a proposal contains
- Edits: mechanical line changes Bumpkit can make safely. The version in each manifest, Go import paths for a new major version module, and renamed Go symbols.
- TODOs: exact file and line locations that need a person. Removed symbols, changed signatures, and uses of a package whose new version is breaking.
Approve a proposal
Nothing is opened until an owner or admin approves a proposal. When you approve one, Bumpkit:
- Creates the branch
bumpkit/upgrade-<name>-<version>from the default branch. - Commits the edits with the message
chore(deps): bump <name> from <from> to <to>. - Opens a pull request whose body lists the reasons, any known vulnerabilities, every edit and a checklist of the TODOs.
Bumpkit never merges the pull request. Review it, finish the TODOs, refresh your lockfile and merge it yourself. If a file changed since the scan, opening fails with "line N changed since the scan; scan again".
| Status | Meaning |
|---|---|
pending |
Waiting for a decision. A new scan updates it in place. |
opening |
Approved; the pull request is being opened. |
opened |
The pull request is open. pull_request_url links to it. |
dismissed |
An owner or admin dismissed it. |
failed |
Opening failed. error says why. You can approve it again. |
Approving, dismissing and scanning are recorded in the workspace audit log.
{
"id": "0b6f3c2a-9e1d-4f7a-8c55-3a2e9d1b7f40",
"repository": "acme/web",
"ecosystem": "go",
"name": "github.com/acme/payments",
"from": "v1.8.0",
"to": "v2.0.0",
"priority": "breaking",
"breaking": true,
"reasons": ["github.com/acme/payments moved to the new major version module github.com/acme/payments/v2."],
"advisories": [],
"edits": [{"path": "go.mod", "line": 12, "old": "\tgithub.com/acme/payments v1.8.0", "new": "\tgithub.com/acme/payments/v2 v2.0.0", "why": "bump github.com/acme/payments from v1.8.0 to v2.0.0"}],
"todos": [{"path": "services/checkout/pay.go", "line": 41, "code": "res, err := client.Charge(ctx, order.Total)", "why": "payments.Charge was removed in v2.0.0."}],
"status": "pending",
"created_at": "2026-10-22T06:00:00Z"
}API endpoints
All endpoints take the x-api-key header. Endpoints return 403 FEATURE_EARLY_ACCESS when the feature isn't on for your workspace yet, and 403 FORBIDDEN when an owner-only endpoint is called by someone who isn't an owner or admin.
| Method | Path | Who | Description |
|---|---|---|---|
GET |
/v1/service-graph |
members | Every repository in the graph with what it provides, consumes, and the consumers that depend on it. |
POST |
/v1/service-graph/refresh |
owners and admins | Re-read every repository. Returns {"repositories": N}, plus error if some failed. |
GET |
/v1/autopilot/proposals |
members | Upgrade proposals. ?limit= from 1 to 200, default 50. |
POST |
/v1/autopilot/scan |
owners and admins | Scan for new versions now. Returns checked and proposed counts. |
POST |
/v1/autopilot/proposals/{id}/approve |
owners and admins | Open the pull request. Returns the proposal. |
POST |
/v1/autopilot/proposals/{id}/dismiss |
owners and admins | Dismiss the proposal. Returns 204. |
Approving or dismissing a proposal that was already decided returns 409.
curl https://bumpkit.dev/v1/service-graph \
-H "x-api-key: $BUMPKIT_API_KEY"{
"repositories": [
{
"repository": "acme/payments",
"default_branch": "main",
"head_sha": "9c1e4b2f0a7d3e6b8c5f1a2d4e7b9c0f3a6d8e1b",
"refreshed_at": "2026-10-22T09:14:03Z",
"provides": [{"kind": "go", "name": "github.com/acme/payments", "path": "go.mod", "line": 1, "direct": true}],
"consumes": [],
"consumers": ["acme/checkout", "acme/web"]
}
]
}truncated is set when GitHub returned only part of the repository's file tree.
There are no CLI commands or MCP tools for cross-repo impact or the autopilot yet. Consumer breaks show up in bumpkit gate output and in the POST /v1/gate response like any other finding. See the API Reference.