Skip to content

Gradle plugin that uses Revapi to check whether you have introduced API/ABI breaks in your Java public API

License

Notifications You must be signed in to change notification settings

revapi/gradle-revapi

 
 

Repository files navigation

Autorelease

gradle-revapi

This is a fork of the well-known gradle-revapi plugin from https://github.com/palantir/gradle-revapi and has been moved under the revapi umbrella. For additional details please refer to revapi/revapi#296.

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 'org.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: 'org.revapi.revapi-gradle-plugin'
  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.

  • To accept a single break, run:

    ./gradlew revapiAcceptBreak --justification "{why this is ok}" \
            --code "{revapi check code}" \
            --old "{optional revapi description of old element}" \
            --new "{optional revapi description of new element}"
    
  • To accept all the breaks in a gradle project run:

    ./gradlew :project:revapiAcceptAllBreaks
    
  • To accept all the breaks in all gradle projects run:

    ./gradlew revapiAcceptAllBreaks
    

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

Releasing a new version of the plugin

A new version of the plugin can be released by manually triggering the Release new plugin version GH action. If necessary, a new version can also be manually released via ./gradlew publishPlugins while locally exporting the env variables RELEASE_VERSION, GRADLE_KEY, GRADLE_SECRET.

About

Gradle plugin that uses Revapi to check whether you have introduced API/ABI breaks in your Java public API

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 66.5%
  • Groovy 31.2%
  • FreeMarker 2.3%