feat(examples): render the same document from any branch - #485
Merged
Conversation
A committed preview could not be compared against a fresh one, for two
reasons that had nothing to do with the document.
The version. Renders take it from the reactor, so develop bakes the next
patch — 2.1.1 while 2.1.0 is what anyone can depend on. Stripping the
qualifier was never enough: the number itself has moved. A display
version can now be passed in, and banner.properties keeps sourcing
@project.version@ as the default, so the reactor stays the answer when
nobody says otherwise.
The date. Two headers carried the {date} token, which resolves against
the wall clock inside the engine, so the same document differed by the
day it was rendered. The master showcase names its own quarter and the
feature catalogue drops the field; PdfChromeExample keeps the token,
because demonstrating it is what that example is for — its preview is
the one that cannot be compared, and that is a property of the example
rather than an oversight.
The number also left the places it decorated: the deck's hero kicker,
its module-graph title, a hardcoded "2.0" in the lockstep kicker, the
v1 deck's footer, and the master showcase's. It stays in the version
pill and in the Maven banner's coordinate card, which now reads the same
input as everything else instead of a string literal.
The layout snapshot moves with them: three widths shrink by 21.12 each,
which is the four characters of a version at that size, and nothing else
in the deck geometry changes.
The eight committed assets are re-rendered at 2.1.0. They disagreed with
each other before this — the hero PNG said 2.1.0 while the deck it is cut
from said 2.1.1 — so the set is internally consistent for the first time
since the release.
Both maven-banner assets were committed as modified with no content change: the version literal and the token produce the same string at 2.1.0, so the render is identical and only the time-seeded PDF /ID and the zip stamps moved. They go back to what they were. A binary diff that is not a diff hides whether the file was re-rendered at all. The override arrived undocumented and untested. The decision now sits in a pure function, because the answer is cached in a static field and a test that sets the property proves only that nothing had touched the class yet. It accepts a leading "v" — one render site prepends its own, so both spellings reaching the page as "vv2.1.0" was one typo away. The examples README carries the incantation, and the class says the reactor is the default rather than the only answer. Three leftovers: the deleted VERSION_LINE left its javadoc bound to the constructor; the master showcase still called itself deliberately undated and named a version source it no longer reads; and its currency was formatted against the default locale, so the committed preview was only reproducible on an English-locale machine. Output is unchanged there — verified by re-rendering and comparing extracted text.
…ing it Every site that prints the value runs it through withoutQualifier(), so -Dgraphcompose.examples.displayVersion=2.2.0-rc.1 would have reached the page as 2.2.0 — the final version of that line, which is not published and may never be. The release tooling does cut -rc versions, so the path was reachable rather than theoretical. The override now takes a released version and refuses anything else, naming what was passed and why. The reactor's own -SNAPSHOT is unaffected: it arrives through banner.properties, not through the override, and withoutQualifier() has always been what strips it there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First of three for #461: this one makes a fresh render comparable to the committed one. The CI gate comes next, the release-script step after that. Nothing here touches
cut-release.ps1, CI or the root README.Why
Two things made a committed preview incomparable with a fresh render, and neither was about the document.
The version. A render takes it from the reactor, so
developbakes the next patch —2.1.1while2.1.0is what anyone can depend on.withoutQualifier()already strips-SNAPSHOT; the number itself has moved, so stripping was never going to be enough.The date. Two headers carried
{date}, which the engine resolves against the wall clock. The same document differed by the day it was rendered.The assets also disagreed with each other: the README hero PNG said
v2.1.0whileengine-deck-v2.pdf— cut from the same scene — saidv2.1.1.What
A display version can be passed in.
-Dgraphcompose.examples.displayVersion=2.1.0overrides the value everything already reads.banner.propertieskeeps sourcing@project.version@, which a guard requires, so the reactor remains the default answer; the override exists for the two callers that need to reproduce a published document.The date leaves two headers. The master showcase names its own quarter — it is a Q2 fiction anyway — and the feature catalogue drops the field, including from the code sample that claims to show that document's own header.
PdfChromeExamplekeeps{date}, because demonstrating the token is what that example is for; its preview is the one that cannot be compared, which is a property of the example, not an oversight.The number leaves the places it decorated. The deck's hero kicker (
GRAPHCOMPOSE 2.1 / MODULE-FIRST→GRAPHCOMPOSE / MODULE-FIRST), its module-graph title, a hardcoded2.0in the lockstep kicker, and two footers. It stays in the version pill and in the Maven banner's coordinate card — which now reads the same input as everything else instead of the string literalv2.1.0it carried.Six assets re-rendered at 2.1.0 — four PDFs, one deck and the README hero — so no committed asset still says 2.1.1. The two
maven-bannerfiles are deliberately left at their committed bytes; see the regression note below.Tests
examples52,qa688, core guard job 37 — all green.The layout snapshot moves, and only where it should: three widths shrink by exactly 21.12 each — four characters of a version at that size — and no other geometry in the deck changes.
The override is confirmed end to end: rendered on
2.1.1-SNAPSHOT, page one of the deck extracts asv2.1.0 GRAPHCOMPOSE / MODULE-FIRST. The remaining2.0strings in the deck and catalogue are body prose — "not a shipped 2.0 claim", "Apache 2.0" — not stamps, and stay.A regression this uncovered, deliberately left for its own PR
Comparing the committed decks against a fresh render — ignoring zip timestamps, so only content counts — shows three of them losing bold today:
maven-banner.pptxtwin-output.pptxbusiness-report.pptxmaster-showcase.pptxThe cause is the defect #479 fixed in the library and never applied to the examples: a style naming
FontName.HELVETICA_BOLDwith nodecoration(BOLD).FontLibraryrewrites the alias to its family before the lookup, and the PPTX backend takes boldness from the resolved font. There are 115 such sites inexamples/src/main, none of them paired with a decoration.master-showcaseis unaffected because its styles come throughBusinessTheme.This is live on
developand predates this PR —business-reportandtwin-outputare not touched here. It matters becauseweb/showcaseis regenerated on every cut, so the next release would publish the de-bolded decks.maven-banner.pdfand.pptxare therefore left at their committed bytes rather than re-rendered: they carry the intended weights, and a fresh render today would commit the regression. Fixing the 115 sites and re-rendering is its own change, with the canonical-content comparator that found this.What this does not make byte-identical
Two renders of the same example still differ: PDFBox seeds the trailer
/IDfrom the clock, and the PPTX zip entries carry wall-clock timestamps. The engine shipsdeterministic(...)on both backends, but the convenience pathdocument.buildPdf()never reaches it, so no example opts in. The comparison the next PR builds therefore has to be raster and text, not bytes — that is a property of the output format here, not a gap in the gate.pdf-chrome.pdfstays non-reproducible in content too: it keeps{date}, because demonstrating that token is what the example is for.web/showcase/**holds a second committed copy of these documents and is regenerated by the release cut, not here — so between this PR and the next cut the two copies differ on the five documents that changed. Re-syncing by hand would rewrite all 190 files for the sake of five, since every copy picks up a fresh/ID.The committed set is consistent about the release version: no asset now says 2.1.1. Several feature previews still name 1.5 / 1.8 / 1.9.0 in their body copy — those are the subject matter of the demos, as issue #461 itself notes.
Not in this PR
The dates that survive in the previews (
2026-07-26) are literals, not clock reads — verified by rendering on 2026-08-01 and getting the same value.pdf-chrome.pdfremains non-reproducible by design and will be named as out of scope when the gate lands.