From e5e3911c3e18a4576380cbac1fb5899b0dda6232 Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Sun, 5 Jul 2026 21:44:27 +0100 Subject: [PATCH] build: split graph-compose-render-pptx out of render-docx render-docx carried both the DOCX backend (Apache POI) and the semantic PPTX backend. Split PPTX into its own graph-compose-render-pptx module so a consumer that wants only slide output does not pull POI, and each backend keeps a minimal dependency surface. The PPTX backend is a POI-free skeleton today, so the new module depends only on graph-compose-core. - New graph-compose-render-pptx module (core-only, no POI). PptxSemanticBackend moves here from render-docx; its package/FQN is unchanged. - Split the shared SessionSemanticExportTest: the docx half stays in render-docx, the pptx half becomes PptxSemanticExportTest in render-pptx. - Wire the module into the aggregator, publish (deploy after render-docx), cut-release (version bump + commit list), VersionConsistencyGuardTest (version lockstep), and the CHANGELOG. - The CI build gate now also builds and tests render-docx and render-pptx; the render-docx tests were not running in CI before (it is a reactor leaf, not an also-make upstream of the engine/testing/qa slice). --- .github/workflows/ci.yml | 12 +- .github/workflows/publish.yml | 16 +- CHANGELOG.md | 16 +- aggregator/pom.xml | 1 + render-docx/pom.xml | 7 +- .../docx/SessionSemanticExportTest.java | 32 +-- render-pptx/pom.xml | 216 ++++++++++++++++++ .../semantic/pptx/PptxSemanticBackend.java | 0 .../semantic/pptx/PptxSemanticExportTest.java | 48 ++++ scripts/cut-release.ps1 | 7 +- .../EnginePoiIsolationGuardTest.java | 7 +- .../VersionConsistencyGuardTest.java | 3 + 12 files changed, 315 insertions(+), 50 deletions(-) create mode 100644 render-pptx/pom.xml rename {render-docx => render-pptx}/src/main/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticBackend.java (100%) create mode 100644 render-pptx/src/test/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticExportTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7395539..826a6061 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,12 +71,12 @@ jobs: cache: maven - name: Build and run tests - # Reactor slice: the engine plus the extracted graph-compose-testing - # module and the graph-compose-qa cross-module suites (which need the - # testing module + the engine test-jar on the classpath and so cannot - # live in the engine's own test scope). -am pulls the fonts / emoji - # upstreams; render-docx / bundle / examples / benchmarks are excluded. - run: ./mvnw -B -ntp -f aggregator/pom.xml clean verify -pl :graph-compose-core,:graph-compose-testing,:graph-compose-qa -am + # Reactor slice: the engine, the render-docx / render-pptx semantic backends, + # the extracted graph-compose-testing module, and the graph-compose-qa + # cross-module suites (which need the testing module + the engine test-jar on + # the classpath and so cannot live in the engine's own test scope). -am pulls + # the fonts / emoji upstreams; bundle / examples / benchmarks are excluded. + run: ./mvnw -B -ntp -f aggregator/pom.xml clean verify -pl :graph-compose-core,:graph-compose-render-docx,:graph-compose-render-pptx,:graph-compose-testing,:graph-compose-qa -am - name: Generate Javadoc # Run only on the baseline JDK — Javadoc output is identical diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 293e23b5..44a63e7c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -110,15 +110,25 @@ jobs: MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} - name: Publish render-docx to Maven Central - # The semantic DOCX/PPTX backend, lockstep-versioned with the engine - # (ships on the same v* tag). graph-compose resolves from the local repo - # installed by the engine deploy above. + # The semantic DOCX backend, lockstep-versioned with the engine (ships on + # the same v* tag). graph-compose-core resolves from the local repo installed + # by the engine deploy above. run: ./mvnw -B -ntp -f render-docx/pom.xml -P release -DskipTests -Dgpg.skip=false deploy env: CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + - name: Publish render-pptx to Maven Central + # The semantic PPTX backend, lockstep-versioned with the engine (ships on + # the same v* tag). graph-compose-core resolves from the local repo installed + # by the engine deploy above. + run: ./mvnw -B -ntp -f render-pptx/pom.xml -P release -DskipTests -Dgpg.skip=false deploy + env: + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + - name: Publish testing to Maven Central # Consumer testing support (LayoutSnapshotAssertions / PdfVisualRegression), # lockstep-versioned with the engine (ships on the same v* tag). graph-compose diff --git a/CHANGELOG.md b/CHANGELOG.md index f398db6d..e0fffc68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,18 +34,20 @@ for this cycle. **`graph-compose-core`** coordinate, and the original **`graph-compose` coordinate becomes a thin drop-in aggregator** that depends on `graph-compose-core` — so an existing `graph-compose` dependency keeps compiling and rendering PDF unchanged. - Consumer-testing support (`graph-compose-testing`) and the semantic DOCX/PPTX - backend (`graph-compose-render-docx`) are already separate artifacts; the PDF + Consumer-testing support (`graph-compose-testing`) and the semantic DOCX / PPTX + backends (`graph-compose-render-docx` / `graph-compose-render-pptx`) are already + separate artifacts; the PDF render backend and the built-in templates move into their own modules over the rest of the 2.0 cycle, at which point `graph-compose` aggregates the PDF backend and `graph-compose-core` becomes the lean, bring-your-own-backend coordinate. The optional `graph-compose-fonts` / `graph-compose-emoji` artifacts are unchanged. Full install guidance ships with 2.0.0. -- `graph-compose-render-docx` is now a separate artifact: the semantic DOCX/PPTX - backend and Apache POI leave the `graph-compose` jar. `DocxSemanticBackend` moves - to `com.demcha.compose.document.backend.semantic.docx` and `PptxSemanticBackend` - to `com.demcha.compose.document.backend.semantic.pptx`; add - `graph-compose-render-docx` (it brings POI transitively) to export DOCX. The +- The semantic office backends are separate artifacts and Apache POI leaves the + engine: `DocxSemanticBackend` ships in `graph-compose-render-docx` (which brings + POI transitively — add it to export DOCX), and `PptxSemanticBackend` ships in its + own `graph-compose-render-pptx` (a POI-free skeleton for now — add it for the + slide-safe semantic manifest). Their packages — + `com.demcha.compose.document.backend.semantic.{docx,pptx}` — are unchanged. The `no-poi` build profile is retired. - `graph-compose-testing` is now a separate artifact: the consumer testing support — `LayoutSnapshotAssertions` (deterministic layout snapshots) and diff --git a/aggregator/pom.xml b/aggregator/pom.xml index 860cab11..ac1a7412 100644 --- a/aggregator/pom.xml +++ b/aggregator/pom.xml @@ -62,6 +62,7 @@ ../fonts ../emoji ../render-docx + ../render-pptx ../testing ../bundle ../examples diff --git a/render-docx/pom.xml b/render-docx/pom.xml index ddb3fedd..729825f5 100644 --- a/render-docx/pom.xml +++ b/render-docx/pom.xml @@ -5,8 +5,9 @@ 4.0.0 + io.github.demchaav + graph-compose-render-pptx + 2.0.0-SNAPSHOT + + GraphCompose Render — PPTX + Semantic PPTX export backend for GraphCompose (slide-safe semantic node validation). + https://github.com/DemchaAV/GraphCompose + + + + MIT License + https://opensource.org/licenses/MIT + repo + + + + + + DemchaAV + Artem Demchyshyn + demchishynartem@gmail.com + https://github.com/DemchaAV + + Lead Developer + Architect + + UTC 0 + + + + + scm:git:https://github.com/DemchaAV/GraphCompose.git + scm:git:ssh://git@github.com/DemchaAV/GraphCompose.git + https://github.com/DemchaAV/GraphCompose/tree/main + + + + UTF-8 + 17 + + 6.1.1 + 3.27.7 + 1.5.37 + 1.0.0 + + 3.15.0 + 3.5.0 + 3.5.6 + 3.4.0 + 3.12.0 + 3.2.8 + 0.11.0 + + + true + + + + + io.github.demchaav + graph-compose-core + ${project.version} + + + + + org.junit.jupiter + junit-jupiter + ${junit.bom.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + ch.qos.logback + logback-classic + ${logback.version} + test + + + + io.github.demchaav + graph-compose-fonts + ${graphcompose.fonts.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${maven.compiler.release} + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.plugin.version} + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + package + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + attach-javadocs + package + + jar + + + none + false + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + ${gpg.skip} + + --pinentry-mode + loopback + + + + + + + org.sonatype.central + central-publishing-maven-plugin + ${central.publishing.plugin.version} + true + + central + false + validated + + + + + + + diff --git a/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticBackend.java b/render-pptx/src/main/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticBackend.java similarity index 100% rename from render-docx/src/main/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticBackend.java rename to render-pptx/src/main/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticBackend.java diff --git a/render-pptx/src/test/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticExportTest.java b/render-pptx/src/test/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticExportTest.java new file mode 100644 index 00000000..a639dc01 --- /dev/null +++ b/render-pptx/src/test/java/com/demcha/compose/document/backend/semantic/pptx/PptxSemanticExportTest.java @@ -0,0 +1,48 @@ +package com.demcha.compose.document.backend.semantic.pptx; + +import com.demcha.compose.GraphCompose; +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.document.backend.semantic.SemanticExportManifest; +import com.demcha.compose.document.node.ContainerNode; +import com.demcha.compose.document.node.ShapeNode; +import com.demcha.compose.document.style.DocumentColor; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentStroke; +import org.junit.jupiter.api.Test; + +import java.awt.Color; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Exercises {@code DocumentSession.export(new PptxSemanticBackend())} from the + * graph-compose-render-pptx module. The semantic PPTX backend validates slide-safe + * nodes and returns a manifest describing the document graph. Split out of + * render-docx's {@code SessionSemanticExportTest} when the PPTX backend became its + * own module. + */ +class PptxSemanticExportTest { + + @Test + void pptxBackendShouldExportManifestFromDocumentGraph() throws Exception { + try (DocumentSession session = GraphCompose.document() + .pageSize(200, 200) + .margin(DocumentInsets.of(10)) + .create()) { + + session.add(new ContainerNode( + "PptxRoot", + List.of(new ShapeNode("Box", 40, 20, Color.BLUE, DocumentStroke.of(DocumentColor.BLACK, 1), DocumentInsets.zero(), DocumentInsets.zero())), + 8, + DocumentInsets.zero(), + DocumentInsets.zero(), + null, + null)); + + SemanticExportManifest pptx = session.export(new PptxSemanticBackend()); + assertThat(pptx.backendName()).isEqualTo("pptx-semantic"); + assertThat(pptx.nodeKinds()).contains("ContainerNode", "ShapeNode"); + } + } +} diff --git a/scripts/cut-release.ps1 b/scripts/cut-release.ps1 index aa1f97f7..cbab1b0a 100644 --- a/scripts/cut-release.ps1 +++ b/scripts/cut-release.ps1 @@ -496,9 +496,11 @@ try { Update-PomVersion (Join-Path $repoRoot 'aggregator/pom.xml') $Version Update-PomVersion (Join-Path $repoRoot 'examples/pom.xml') $Version Update-PomVersion (Join-Path $repoRoot 'benchmarks/pom.xml') $Version - # render-docx tracks the engine line (lockstep): its bumps here and - # its graph-compose dep is ${project.version} (follows automatically). + # render-docx / render-pptx track the engine line (lockstep): each + # bumps here and its graph-compose-core dep is ${project.version} (follows + # automatically). Update-PomVersion (Join-Path $repoRoot 'render-docx/pom.xml') $Version + Update-PomVersion (Join-Path $repoRoot 'render-pptx/pom.xml') $Version # graph-compose-testing tracks the engine line (lockstep): its # bumps here and its graph-compose dep is ${project.version} (follows # automatically). graph-compose-qa is an aggregator child (its version is @@ -576,6 +578,7 @@ try { 'aggregator/pom.xml', 'bundle/pom.xml', 'render-docx/pom.xml', + 'render-pptx/pom.xml', 'testing/pom.xml', 'wrapper/pom.xml', 'examples/pom.xml', diff --git a/src/test/java/com/demcha/documentation/EnginePoiIsolationGuardTest.java b/src/test/java/com/demcha/documentation/EnginePoiIsolationGuardTest.java index 86d00eea..b927d221 100644 --- a/src/test/java/com/demcha/documentation/EnginePoiIsolationGuardTest.java +++ b/src/test/java/com/demcha/documentation/EnginePoiIsolationGuardTest.java @@ -17,8 +17,9 @@ /** * Architectural guard that keeps Apache POI out of the lean engine module. * - *

The semantic DOCX/PPTX backend — the only code that ever touched POI — - * lives in the separate {@code graph-compose-render-docx} module. The engine + *

The semantic DOCX backend — the only code that ever touched POI — lives in + * the separate {@code graph-compose-render-docx} module (the POI-free PPTX backend + * moved to {@code graph-compose-render-pptx}). The engine * (root module) must stay free of every {@code org.apache.poi.*} import or * fully-qualified reference so it never drags {@code poi-ooxml} back onto its * classpath.

@@ -50,7 +51,7 @@ void poiShouldStayOutOfTheEngineModule() throws IOException { assertThat(violations) .describedAs("Apache POI must stay out of the lean engine module. The semantic " - + "DOCX/PPTX backend lives in graph-compose-render-docx — keep every " + + "DOCX backend (the only POI code) lives in graph-compose-render-docx — keep every " + "org.apache.poi.* import and reference there, not under com.demcha.compose.") .isEmpty(); } diff --git a/src/test/java/com/demcha/documentation/VersionConsistencyGuardTest.java b/src/test/java/com/demcha/documentation/VersionConsistencyGuardTest.java index 8cbf68e6..6ae30db8 100644 --- a/src/test/java/com/demcha/documentation/VersionConsistencyGuardTest.java +++ b/src/test/java/com/demcha/documentation/VersionConsistencyGuardTest.java @@ -64,6 +64,9 @@ void everyModuleResolvesToTheRootProjectVersion() throws Exception { assertThat(effectiveVersion(PROJECT_ROOT.resolve("render-docx/pom.xml"))) .describedAs("render-docx (graph-compose-render-docx) tracks the engine line and must equal the root version (%s)", root) .isEqualTo(root); + assertThat(effectiveVersion(PROJECT_ROOT.resolve("render-pptx/pom.xml"))) + .describedAs("render-pptx (graph-compose-render-pptx) tracks the engine line and must equal the root version (%s)", root) + .isEqualTo(root); assertThat(effectiveVersion(PROJECT_ROOT.resolve("testing/pom.xml"))) .describedAs("testing (graph-compose-testing) tracks the engine line and must equal the root version (%s)", root) .isEqualTo(root);