-
Notifications
You must be signed in to change notification settings - Fork 30
Automatic API compatibility validation #105
Description
Problem
Producers and consumers of software libraries don’t have an easy life. As a consumer of a library I don’t know if new version of the library brings API incompatibilities until I try to use it and it blows up, hopefully during compilation or testing, and not on production! As a producer of a library I can unintentionally sneak in API incompatibilities, unless I am very careful and/or great engineers review my code and spot the problems.
Let’s make the life of producers and consumers of libraries delightful!!!
Solution
What if producer gets nice report or even build failure if he changes the API without bumping major version? What if consumer gets nice report, or even early build failure if known API incompatibilities exist in the new version of a library he attempts to use? What if the incompatibilities are computable statically and it is not necessary to compile code/run tests to identify issues? What if the tools can tell you with good accuracy what version of a library you can consume safely?
First steps
While we don’t necessarily need to scope the entire solution we can to scope down an initial feature set that can help us validate if the problem is worth solving and how. Below features are suggestions and should be critically reviewed by whoever decides to own this feature.
Does my change break API compatibility?
To get started, we can create a Gradle task that compares 2 binaries, identifies API incompatibilities and reports them. Tools that identify API incompatibilities already exist and can be leveraged (mockito/mockito#738). In the project we already have code that pulls down the previously released binaries (implemented as part of #84).
Suggested implementation
Suggested implementation should be enough to get started. However, please discuss and suggest different approach as you see fit.
- Create a new plugin ApiCompatibilityPlugin that will add new Gradle task of type CheckApiCompatibilityTask (new task type). The new plugin is applied by our continuous delivery plugin, however, we don’t hook up the new task to the workflow yet.
- When the task runs, it pulls down previously released binaries reusing the code we already have
- Then, it reports binary incompatibilities. For example it produces a report file.
- Bonus: add configuration to the task to produce report AND throw exception if there are incompatibilities
- Bonus 2: add configuration to the task to specify what are public packages and what are “internal” packages. Incompatible changes to internal packages are OK and should not fail the task. In the compatibility report it is easy to discriminate changes to “internal” API VS changes to “public” API.
- Bonus 3: make bonus 2 feature configurable on a task (property on the task).
Future ideas
Below future ideas are wild brainstorming :)
- Create a service that reports API incompatibilities and attaches information to GitHub Pull Request (similar to how Travis CI reports build results, codecov reports coverage).
- Create a concept of “API snapshot” that is stored in a file and ships to binary repository along with the publications (jar, sources, javadoc). Tools can use the snapshot to compare APIs between arbitrary versions of a library.
- Create plugin for consumers so that they can check compatibility with libraries they consume. The plugin should aid consumer in bumping to new version of a desired library.