palantir / gradle-revapi

Gradle plugin that uses Revapi to check whether you have introduced API/ABI breaks in your Java public API
Apache License 2.0
29 stars 17 forks source link
octo-correct-managed

Autorelease

WARNING: This repo is no longer maintained.

Use the fork established by the Revapi owners.

gradle-revapi

A gradle plugin which runs Revapi to warn you when there are breaks to your Java library's public API or ABI.

Using the plugin should be as simple as:

  1. Adding the plugin to your buildscript:

    buildscript {
        // ...
    
        dependencies {
            classpath 'com.palantir.gradle.revapi:gradle-revapi:<latest-version>'
        }
    }
  2. And then apply the plugin to all the projects you want to ensure API compatibility:

    // In my Java project's build.gradle that publishes a jar
    +apply plugin: 'com.palantir.revapi'
  3. Revapi will be run as part of ./gradlew check. Alternatively, you can call ./gradlew revapi directly.

Motivation

Accidentally releasing API or ABI breaks in java libraries has bad consequences for library consumers. In the case of API breaks, consumers have to perform some kind of manual action to upgrade to newer library versions, which may be difficult.

With ABI breaks, the situation can be even worse, as uses of the library compile but uses in jars of the old API fail at runtime. An example from Tritium is where a method was changed from a Map to a SortedMap. This compiles against direct dependencies but transitive dependencies using the older API would produce a NoSuchMethodError at runtime, which has caused a number of problems in production code. Similarly, there was a covariant return type change to docker-compose-rule (ImmutableDockerComposeRule -> DockerComposeRule) which caused ABI breaks in docker-proxy-rule, among projects.

Configuration

gradle-revapi should work out of the box for most uses cases once applied. By default it compares against the previous version of the jar from the project it is applied in by finding the last tag using git describe. However, if you need to need to override the artifact to compare against, you can do so:

revapi {
    oldGroup = '<artifact-group>'
    oldNamed = '<artifact-name>'
    oldVersion = '<artifact-version>'
}

Accepting breaks

Sometimes you may wish to break your API, or feel that the particular API break identified by revapi is acceptable to release. In these cases, there is an escape hatch you can use which should be automatically recommended to you in the error message gradle-revapi produces.

Running any of these tasks will add the breaks to the .palantir/revapi.yml file in the format"

acceptedBreaks:
  version:
    group:name:
    - code: "class"
      old: "class OldClass"
      new: null
      justification: "No one was using this"

Version overrides

Sometimes the previous release will have a successfully applied a git tag but a failed publish build. In this case gradle-revapi will fail as it cannot resolve the previous API to compare against. To resolve this, you can possible to set a version override that will use a different version instead of the last git tag. To do so, use the

./gradle revapiVersionOverride --replacement-version <last-published-version>

task to use correctly published version instead. This will creare an entry in .palantir/revapi.yml of the following format:

versionOverrides:
  group:name:version: versionOverride