Skip to content

build: check binary compatibility against published releases - #465

Open
jainruchir wants to merge 1 commit into
spiffe:mainfrom
jainruchir:build/binary-compatibility-check
Open

jainruchir wants to merge 1 commit into
spiffe:mainfrom
jainruchir:build/binary-compatibility-check

Conversation

@jainruchir

Copy link
Copy Markdown

Summary

Closes #463.

Add a japicmp binary compatibility gate for java-spiffe-core and java-spiffe-provider, wired into check and therefore the existing CI builds. This catches changes that still compile from source but break previously compiled consumers, such as the builder return-type change in #377.

  • Resolve the latest stable major.minor.patch release from Maven Central automatically, with -PbaselineVersion=... for maintenance branches.
  • Use detached configurations so Gradle cannot substitute the current project for its published baseline. Compare regular module JARs only, with separate dependency classpaths for resolving referenced types.
  • Check public/protected APIs and synthetic bridge methods, matching Javadoc's exclusions for generated and internal packages. Fail on binary breaks, not compatible additions or source-only incompatibilities.
  • Produce text and HTML reports under each module's build/reports/japicmp/.
  • Document signature-level exclusions and the requirement for a breaking-change changelog entry. Missing artifacts or resolution errors fail rather than silently bypassing the gate; -PbaselineVersion=none explicitly opts out for a first-ever release.

Existing unreleased change

The check found that RetryHandler.scheduleRetry(Runnable) already changed from void to boolean on main in 8cef441. This PR records that exact method as an exclusion and documents its ABI impact in the changelog; it does not modify the retry implementation.

Please review whether to accept that existing break or restore compatibility separately. More generally, does the proposed method/field exclusion plus changelog policy match how you would like to handle intentional ABI changes?

Testing

On macOS arm64:

  • ./gradlew build passes on JDK 25, including 608 existing unit tests and nine new Gradle TestKit tests.
  • The TestKit suite and both module compatibility tasks also pass on JDK 17 and JDK 21, using the repository's Gradle 9.6.1 wrapper.
  • Fixtures exercise additions, removed public/protected methods, builder return-type changes, prerelease filtering, pinned and missing baselines, narrow exclusions, and invalidation when the current API or published baseline changes.
  • A regression test compares the actual Maven Central core JARs from 0.8.14 and 0.8.15 and verifies that the removed X509SourceOptionsBuilder and changed builder() signature fail the gate.

Local commands (no SPIRE agent required):

./gradlew :java-spiffe-core:japicmp :java-spiffe-provider:japicmp
./gradlew binaryCompatibilityTest
./gradlew binaryCompatibilityTest --tests '*detectsPublishedBuilderRegressionFrom0814To0815'

SPIRE integration tests were not run; this changes build verification only.

Compare core and provider APIs with the latest stable Maven Central release during check. Add TestKit coverage, including the published 0.8.14 to 0.8.15 builder regression, and document baseline overrides and intentional changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ruchir Jain <122954065+jainruchir@users.noreply.github.com>
@maxlambrecht

Copy link
Copy Markdown
Member

Thanks for adding this! I'll review it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a binary-compatibility check to catch unintended ABI breaks between releases

2 participants