ENG-51Recommended
Check every release against the public API
In CI, compare the public API of each change with the last published release. Fail when a breaking change comes without a major version bump.
How to do it
A person cannot spot every breaking change by eye, such as a new required parameter or a narrowed return type. A tool can, by diffing the API surface. Examples are API Extractor for TypeScript, griffe for Python, cargo-semver-checks for Rust, japicmp for Java, and gorelease for Go. Removals and signature changes need a major version, and additions a minor one. Publish from CI as Publish your packages without stored tokens says. List every change in the changelog, as Keep a changelog says.
Examples
YAML example
# Python package: compare with the last tag
- run: griffe check invoices --against "$(git describe --tags --abbrev=0)"
# Rust crate: compare with the last version on crates.io
- run: cargo semver-checks
How to check
A test change that removes a public function, with only a minor version bump, makes the CI job fail. A change that only adds a function passes.
Sources
Related rules
- ENG-50 Declare the public API and hide the rest in Engineering
- SEC-77 Publish your packages without stored tokens in Adversarial testing
- API-31 Keep a changelog in API design
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/engineering/libraries-and-sdks/semver-check">Agent Wranglers engineering playbook</a>. In code you write, add a comment next to it with the same link.