Skip to content

build(japicmp): enforce binary compatibility against the 2.0.0 baseline#394

Merged
DemchaAV merged 3 commits into
developfrom
harden/japicmp-2.0-baseline
Jul 13, 2026
Merged

build(japicmp): enforce binary compatibility against the 2.0.0 baseline#394
DemchaAV merged 3 commits into
developfrom
harden/japicmp-2.0-baseline

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

The japicmp gate ran report-only through the 2.0 major transition, comparing against a JitPack-hosted v1.7.0. Now that 2.0.0 is published to Maven Central, the gate can protect the 2.x line — an accidental binary-incompatible change to the public API should fail CI, not just be reported. But japicmp short-circuits when the working version equals the baseline, and post-GA every module was still pinned at the release version 2.0.0, so the gate was a no-op.

What

  • Baseline → Central 2.0.0. Point the baseline at graph-compose-core:2.0.0 (resolved from Maven Central — the JitPack <repositories> block is removed, so consumers inherit nothing) and flip breakBuildOnBinaryIncompatibleModifications to true. Source-incompatible changes stay report-only. The baseline is the major's floor and holds for the whole 2.x line, advancing only at the next major, so every 2.x build must stay binary-compatible with the 2.0.0 surface.
  • Post-release bump. Every module → 2.0.1-SNAPSHOT, so the gate compares the working tree against the published 2.0.0 and actually fires on a break.
  • Guard tweak. The install snippets stay pinned to the on-Central 2.0.0, so VersionConsistencyGuardTest now also accepts the latest published release (the topmost dated CHANGELOG entry) alongside the current pom and Planned versions.
  • Cleanup. Drop the two stale 1.x removal excludes (TextMeasurementSystem, ConfigLoader) — the 2.0.0 baseline predates them. Document the gate in docs/api-stability.md §3 and add a ## v2.0.1 — Planned CHANGELOG entry.

Tests

  • VersionConsistencyGuardTest 12/12 (poms 2.0.1-SNAPSHOT, snippets 2.0.0).
  • Reactor-wide mvn validate = BUILD SUCCESS.
  • -P japicmp verify on core is BUILD SUCCESS against the 2.0.0 baseline; a controlled public→package-private change fails with METHOD_LESS_ACCESSIBLE, proving the gate fires.

DemchaAV added 3 commits July 13, 2026 10:52
The japicmp gate ran report-only through the 2.0 major transition and
compared against a JitPack-hosted v1.7.0. With 2.0.0 published to Maven
Central, point the baseline at graph-compose-core:2.0.0 (resolved from
Central, no extra repository) and fail the build on any binary-incompatible
change to the public surface, so a regression can no longer ship in a 2.x
update. Source-incompatible changes stay report-only. The baseline is the
major's floor and holds for the whole 2.x line, advancing only at the next
major.

The gate short-circuits when the working version equals the baseline, so it
only bites once development moves off the release version: bump every module
to 2.0.1-SNAPSHOT. The install snippets stay pinned to the published 2.0.0,
so VersionConsistencyGuard now also accepts the latest published release
(the topmost dated CHANGELOG entry) alongside the pom and Planned versions.
Drop the two stale 1.x removal excludes (TextMeasurementSystem, ConfigLoader)
— the 2.0.0 baseline predates them.

Tests: VersionConsistencyGuardTest 12/12 (poms 2.0.1-SNAPSHOT, snippets
2.0.0); reactor-wide `mvn validate` green; `-P japicmp verify` on core is
BUILD SUCCESS against 2.0.0, and a controlled public->package-private change
fails with METHOD_LESS_ACCESSIBLE.
…light

Align the binary-compatibility gate with docs/api-stability.md. The Internal tier
— com.demcha.compose.engine.** and com.demcha.compose.document.layout.**, plus any
element marked @internal — carries no compatibility promise, so exclude all of it;
the gate previously excluded only document.layout.payloads. Only the Stable public
surface is now enforced.

Run the gate in the publish workflow before any deploy, so a binary-incompatible
change to the public surface aborts the release even if the tag reached the publish
job by bypassing branch protection (the CI japicmp job only gates pull requests).

Tighten VersionConsistencyGuardTest: during a -SNAPSHOT development cycle the
install snippets must advertise the latest published release (the version
resolvable on Maven Central), not the in-development SNAPSHOT or a Planned version.
The release commit bumps the pom off SNAPSHOT and rewrites the snippets to the
release version, at which point they must equal it.

Verified on a 2.0.1-SNAPSHOT working tree: the gate fails a Stable break
(DocumentColor.rgba -> package-private, METHOD_LESS_ACCESSIBLE) and passes an
Internal break (LayoutCompiler.compile -> package-private, excluded); the guard
rejects a snippet pinned to an unpublished 2.0.1.
A git-revert-safe script that proves the gate enforces the Stable surface and
excludes the Internal surface: it reduces a Stable public method to
package-private and asserts the gate FAILS (METHOD_LESS_ACCESSIBLE), then does
the same to an Internal method and asserts the gate PASSES. A trap always reverts
the source. Run it after changing the japicmp <excludes> or moving a type between
tiers.
@DemchaAV DemchaAV merged commit 17d8a6d into develop Jul 13, 2026
12 checks passed
@DemchaAV DemchaAV deleted the harden/japicmp-2.0-baseline branch July 13, 2026 11:36
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.

1 participant