Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,11 @@ jobs:

- name: Compare public API against baseline
# The `japicmp` profile resolves the baseline release pinned
# by the `japicmp.baseline` property in core/pom.xml (via the
# profile-local JitPack repository) and diffs it against the
# freshly-built artifact. Fails the job on any binary-
# by the `japicmp.baseline` property in core/pom.xml (the
# published graph-compose-core on Maven Central) and diffs it
# against the freshly-built artifact. Fails the job on any binary-
# incompatible modification to the public surface. Source-
# incompatible changes are reported only (phased policy).
# See CHANGELOG v1.6.6 "Build" notes for the policy rationale.
run: ./mvnw -B -ntp -DskipTests -P japicmp verify -pl :graph-compose-core

- name: Upload japicmp report
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ jobs:
# unpublished tests-jar no longer fails the deploy.
run: ./mvnw -B -ntp clean install

- name: Verify binary compatibility against the published baseline
# Defence in depth: run the japicmp gate on the tagged commit before any
# deploy, so an accidental binary-incompatible change to the public
# surface aborts the publish even when the tag reached here by bypassing
# branch protection (the CI japicmp job only gates pull requests). Compares
# the freshly built graph-compose-core against the japicmp.baseline release
# on Maven Central and fails the job on any Stable-surface break; the
# Internal packages (engine.**, document.layout.**) are excluded per
# docs/api-stability.md. Test build is skipped — the install step above
# already ran the full suite on this commit.
run: ./mvnw -B -ntp -f core/pom.xml -P japicmp -Dmaven.test.skip=true verify

- name: Publish engine to Maven Central
# Activates the release profile (sources + javadoc + gpg sign +
# central-publishing) and flips gpg.skip=false. The deploy
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
All notable changes to GraphCompose are documented here. Versions
follow semantic versioning; release dates are ISO 8601.

## v2.0.1 — Planned

### Build

- The binary-compatibility gate (japicmp) now **enforces** backward compatibility
against the published `2.0.0` baseline: an accidental binary-incompatible change to
the public API fails the build instead of only being reported. Development proceeds
on the `2.0.1-SNAPSHOT` line, so the gate compares the working tree against that
baseline and catches a regression before it can ship in a 2.x update. Source-level
incompatibilities remain report-only for now.

## v2.0.0 — 2026-07-13

The 2.0 development line. Binary-breaking by design — japicmp runs report-only
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-build</artifactId>
<version>2.0.0</version>
<version>2.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
graph-compose and graph-compose-templates dependencies below use
${project.version}, so they follow automatically.
-->
<version>2.0.0</version>
<version>2.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>GraphCompose Bundle</name>
Expand Down
103 changes: 48 additions & 55 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-core</artifactId>
<version>2.0.0</version>
<version>2.0.1-SNAPSHOT</version>

<name>GraphCompose Core</name>
<description>A declarative layout engine for programmatic document generation, implemented primarily in Java. This is the lean engine coordinate; depend on the `graph-compose` artifact for the drop-in, PDF-capable install.</description>
Expand Down Expand Up @@ -91,7 +91,14 @@

<!-- Binary compatibility baseline (japicmp profile) -->
<japicmp.version>0.26.1</japicmp.version>
<japicmp.baseline>v1.7.0</japicmp.baseline>
<!-- 2.x binary-compatibility baseline: the published graph-compose-core on
Maven Central. The 2.0 major transition is complete, so the gate now
enforces binary compatibility against 2.0.0 (see the japicmp profile).
The gate is a no-op while the working version equals the baseline
(2.0.0) and becomes active the moment the version bumps to the next
-SNAPSHOT — proven: 2.0.1-SNAPSHOT + a reduced-access public method
fails with METHOD_LESS_ACCESSIBLE. -->
<japicmp.baseline>2.0.0</japicmp.baseline>

<!--
GPG signing — opted in via -Dgpg.skip=false (the publish
Expand Down Expand Up @@ -638,23 +645,18 @@
</profile>

<!--
Binary-compatibility baseline against the last published
release. Activated with `-P japicmp`. Resolves the baseline
artifact from JitPack (kept profile-local so consumers do
NOT inherit a JitPack repository). Fails the build on any
binary-incompatible modification to the public surface;
source-incompatible changes are reported but do not fail
(yet) so the team can phase the policy in. Tracked in the
v1.6.6 stabilization (Track E1).
Binary-compatibility gate. Activated with `-P japicmp`. Resolves the
baseline artifact (the published graph-compose-core pinned by the
japicmp.baseline property) from Maven Central — no extra repository, so
consumers inherit nothing. The baseline is the current major's floor
(2.0.0 for the whole 2.x line), advancing only at the next major, so the
gate holds every 2.x build binary-compatible with the 2.0.0 public
surface. Fails the build on any binary-incompatible modification to the
public surface; source-incompatible changes are reported but do not fail
(yet) so the policy can be phased in.
-->
<profile>
<id>japicmp</id>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
Expand All @@ -673,8 +675,8 @@
<configuration>
<oldVersion>
<dependency>
<groupId>com.github.DemchaAV</groupId>
<artifactId>GraphCompose</artifactId>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-core</artifactId>
<version>${japicmp.baseline}</version>
</dependency>
</oldVersion>
Expand All @@ -686,51 +688,42 @@
<parameter>
<onlyModified>true</onlyModified>
<!--
2.0 development line: the major intentionally breaks binary
compatibility (core extraction, v2-suffix drop, Gen-2 removal).
The gate runs report-only here so the japicmp report still
documents every break for the migration guide / api-stability §3
ledger, without failing the build. Re-enable (true) once the 2.0
baseline is published and japicmp.baseline points at it.
2.x binary-compatibility gate. The 2.0 major transition is
complete and 2.0.0 is the published baseline, so binary breaks
now FAIL the build — an accidental incompatible change to the
public surface can no longer ship in a 2.x minor/patch. (Proven:
on a 2.0.1-SNAPSHOT working version, reducing a public method's
access fails with METHOD_LESS_ACCESSIBLE.) Source incompatibilities
stay report-only for now — a source break that is binary-compatible
(e.g. adding a default interface method) is documented in the report
without failing CI; tighten to true when the 2.x source-compat
policy is finalized.
-->
<breakBuildOnBinaryIncompatibleModifications>false</breakBuildOnBinaryIncompatibleModifications>
<breakBuildOnBinaryIncompatibleModifications>true</breakBuildOnBinaryIncompatibleModifications>
<breakBuildOnSourceIncompatibleModifications>false</breakBuildOnSourceIncompatibleModifications>
<includeSynthetic>false</includeSynthetic>
<reportOnlyFilename>true</reportOnlyFilename>
<skipPomModules>true</skipPomModules>
<!--
Internal layout->render handoff DTOs. These records carry
engine-internal types (TextStyle, Padding, ...) and evolve
with rendering features (e.g. ParagraphFragmentPayload gained
verticalAlign in 1.7.0). They are not part of the canonical
public API (document.api/dsl/node/style) and carry no
binary-compatibility promise, so they are excluded from the gate.
Exclude the complete Internal surface, exactly as
docs/api-stability.md defines it: the two package trees marked
@Internal at the package level — com.demcha.compose.engine.** (the
engine, incl. text/markdown/measurement helpers and the render
handoff payloads) and com.demcha.compose.document.layout.** (the
compiler, NodeDefinitionSupport, placement/measure/split contracts,
and the layout.payloads DTOs) — plus any element carrying the
per-element @Internal marker anywhere else. These carry no
binary-compatibility promise (§ 1), so the gate must not fail on
them; only the Stable public surface (document.api/dsl/node/style,
chart/svg/font, GraphCompose) is enforced. The `.**` suffix matches
the package and all sub-packages. (The former 1.x transitional
excludes — TextMeasurementSystem, ConfigLoader — are gone: those
removals predate the 2.0.0 baseline, so it no longer contains them.)
-->
<excludes>
<exclude>com.demcha.compose.document.layout.payloads</exclude>
<!--
engine.measurement.TextMeasurementSystem dropped its vestigial
SystemECS super-interface (and the no-op process(EntityManager)
default) — see CHANGELOG v1.7.1. japicmp reports this as
INTERFACE_REMOVED, but it is safe: nothing consumes a
TextMeasurementSystem as a SystemECS. The legacy ECS engine now
obtains the measurement service via
SystemRegistry.registerTextMeasurement(...) / textMeasurement()
instead of enrolling it as a process()-driven system, and the
canonical pipeline injects it directly. Drop this exclude once the
japicmp baseline advances to the release that lands the change.
-->
<exclude>com.demcha.compose.engine.measurement.TextMeasurementSystem</exclude>
<!--
com.demcha.compose.ConfigLoader removed in v1.8.0 — an
application-bootstrap YAML/JSON config helper with no
connection to document rendering; nothing in the library,
tests, or examples referenced it (see CHANGELOG v1.8.0).
japicmp reports the deliberate deletion as CLASS_REMOVED.
Drop this exclude once the japicmp baseline advances to the
release that lands the removal.
-->
<exclude>com.demcha.compose.ConfigLoader</exclude>
<exclude>com.demcha.compose.engine.**</exclude>
<exclude>com.demcha.compose.document.layout.**</exclude>
<exclude>@com.demcha.compose.document.api.Internal</exclude>
</excludes>
</parameter>
</configuration>
Expand Down
Loading
Loading