Skip to content

Commit 6e436a8

Browse files
committed
docs+ci: post-release polish for v1.6.0 (audit P0+P1)
Closes the actionable items from the post-release audit: - README — adds CI/Latest-release/JitPack badges, a Distribution status block (current: JitPack, planned: Maven Central in v1.7, tracking issue #7), an "Upgrading from v1.5?" warning under Installation that calls out the Templates v2 breaking surface explicitly (legacy CV / cover-letter classes deleted, not deprecated), and a "v1.6 primitives in 30 lines" section with one short snippet per new primitive (nested list, composed table cell, canvas layer placement). - docs/templates-v2.md — new landing page for the CV / cover-letter / invoice / proposal preset library: four-layer architecture, 14 CV preset table with palette/layout notes, 14 paired cover-letter presets, quick-start snippet, visual parity / regression coverage summary, and a pointer to the v1 -> v2 migration table. - .github/workflows/ci.yml — new examples-generation job that runs after build-and-test: installs the root artifact, recompiles the examples module, runs GenerateAllExamples, and uploads the 26 generated PDFs as a CI artifact. Examples are part of the product surface (live showcase, README install previews); a CI smoke test catches regressions in the runnable surface before they ship. DocumentationCoverageTest, CanonicalSurfaceGuardTest, and the rest of the architecture + documentation guard suite stay green (30 / 0 / 0 / 0) under the new README content.
1 parent 703f8a5 commit 6e436a8

3 files changed

Lines changed: 215 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,44 @@ jobs:
6464
- name: Generate Javadoc
6565
run: ./mvnw -B -ntp javadoc:javadoc
6666

67+
examples-generation:
68+
name: Examples Generation Smoke Test
69+
if: github.event_name != 'schedule'
70+
needs: build-and-test
71+
runs-on: ubuntu-latest
72+
env:
73+
JAVA_TOOL_OPTIONS: -Djava.awt.headless=true
74+
75+
steps:
76+
- name: Check out repository
77+
uses: actions/checkout@v4
78+
79+
- name: Set up Temurin JDK 21
80+
uses: actions/setup-java@v4
81+
with:
82+
distribution: temurin
83+
java-version: '21'
84+
cache: maven
85+
86+
- name: Install root artifact
87+
run: ./mvnw -B -ntp -DskipTests install -pl .
88+
89+
- name: Compile examples module
90+
run: ./mvnw -B -ntp -f examples/pom.xml clean compile
91+
92+
- name: Run GenerateAllExamples
93+
run: |
94+
./mvnw -B -ntp -f examples/pom.xml exec:java \
95+
"-Dexec.mainClass=com.demcha.examples.GenerateAllExamples"
96+
97+
- name: Upload generated PDFs
98+
if: always()
99+
uses: actions/upload-artifact@v4
100+
with:
101+
name: examples-pdfs-${{ github.run_id }}
102+
path: examples/target/generated-pdfs/**
103+
if-no-files-found: error
104+
67105
perf-smoke:
68106
name: Performance Smoke Check
69107
if: github.event_name == 'pull_request'

README.md

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
</p>
1111

1212
<p align="center">
13+
<a href="https://github.com/DemchaAV/GraphCompose/actions/workflows/ci.yml?query=branch%3Amain"><img src="https://img.shields.io/github/actions/workflow/status/DemchaAV/GraphCompose/ci.yml?branch=main&style=for-the-badge&label=CI" alt="CI"/></a>
14+
<a href="https://github.com/DemchaAV/GraphCompose/releases/latest"><img src="https://img.shields.io/github/v/release/DemchaAV/GraphCompose?style=for-the-badge&label=Release" alt="Latest release"/></a>
15+
<a href="https://jitpack.io/#DemchaAV/GraphCompose"><img src="https://img.shields.io/jitpack/v/github/DemchaAV/GraphCompose?style=for-the-badge&label=JitPack" alt="JitPack"/></a>
1316
<img src="https://img.shields.io/badge/Java-21-orange?style=for-the-badge&logo=openjdk" alt="Java 21"/>
14-
<img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="MIT License"/>
1517
<img src="https://img.shields.io/badge/PDFBox-3.0-red?style=for-the-badge" alt="PDFBox 3.0"/>
16-
<a href="https://jitpack.io/#DemchaAV/GraphCompose">
17-
<img src="https://img.shields.io/jitpack/v/github/DemchaAV/GraphCompose?style=for-the-badge&label=JitPack" alt="JitPack"/>
18-
</a>
18+
<img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="MIT License"/>
1919
</p>
2020

2121
<p align="center">
@@ -58,7 +58,9 @@ repositories { maven("https://jitpack.io") }
5858
dependencies { implementation("com.github.demchaav:GraphCompose:v1.6.0") }
5959
```
6060

61-
> Latest published tag: **v1.6.0** &mdash; the "expressive" release. Full notes in [`CHANGELOG.md`](./CHANGELOG.md).
61+
> **Distribution status** &mdash; currently **JitPack**. Maven Central is planned for v1.7 ([tracking issue](https://github.com/DemchaAV/GraphCompose/issues/7)).
62+
63+
> **Upgrading from v1.5?** Core document authoring stays source-compatible &mdash; engine, DSL, themes, and backend-neutral records carry v1.5 callers unchanged. **Templates v2** replaces the legacy CV / cover-letter template classes; legacy classes were **deleted**, not deprecated. Read the [migration guide](./docs/migration-v1-5-to-v1-6.md) before upgrading template-heavy code.
6264
6365
## Hello world
6466

@@ -98,15 +100,51 @@ For a Spring Boot `@RestController` streaming the PDF straight to the response,
98100

99101
## What's in v1.6 &mdash; "expressive"
100102

101-
- **Templates v2** &mdash; 14 CV and 14 paired cover-letter presets, theme-driven via `BusinessTheme`, one-liner `create(theme)` factories. Inline markdown, slot-based multi-column layouts.
103+
- **Templates v2** &mdash; 14 CV and 14 paired cover-letter presets, theme-driven via `BusinessTheme`, one-liner `create(theme)` factories. Inline markdown, slot-based multi-column layouts. See [`docs/templates-v2.md`](./docs/templates-v2.md).
102104
- **Composed primitives** &mdash; `ListBuilder.addItem(label, Consumer)` (nested lists), `DocumentTableCell.node(...)` (any node inside a cell), `CanvasLayerNode` (pixel-precise free-canvas placement).
103105
- **Architecture hardening** &mdash; `@Internal` API stability marker, public `PdfFragmentRenderHandler` SPI, `DocumentRenderingException` on the convenience render path, documented thread-safety contract.
104106

105107
Full notes in [`CHANGELOG.md`](./CHANGELOG.md). Upgrade guide: [`docs/migration-v1-5-to-v1-6.md`](./docs/migration-v1-5-to-v1-6.md).
106108

109+
## v1.6 primitives in 30 lines
110+
111+
Three snippets, one per new primitive. Full runnable versions live in the [examples gallery](./examples/README.md).
112+
113+
**Nested list** &mdash; builder-callback child scopes with a per-depth marker cascade.
114+
115+
```java
116+
document.pageFlow().addList(list -> list
117+
.addItem("Backend platform", row -> row
118+
.addItem("Java 21, Spring Boot, PostgreSQL")
119+
.addItem("REST APIs and event-driven services"))
120+
.addItem("Document generation", row -> row
121+
.addItem("PDF rendering pipeline")
122+
.addItem("Layout snapshot tests")));
123+
```
124+
125+
**Composed table cell** &mdash; any composable node inside a cell, two-pass row measurement.
126+
127+
```java
128+
DocumentTableCell richSummary = DocumentTableCell.node(
129+
new ParagraphNode("Summary",
130+
"**Q3 results** were *strong* — revenue grew 18% YoY.",
131+
bodyStyle, TextAlign.LEFT, 1.0,
132+
DocumentInsets.zero(), DocumentInsets.zero()));
133+
```
134+
135+
**Canvas layer** &mdash; pixel-precise `(x, y)` placement inside a fixed bounding box.
136+
137+
```java
138+
document.pageFlow().addCanvas(523, 360, canvas -> canvas
139+
.clipPolicy(ClipPolicy.CLIP_BOUNDS)
140+
.position(headline, 0, 60)
141+
.position(rule(503, 1.4, accent), 10, 32));
142+
```
143+
107144
## Documentation
108145

109146
- [Template authoring cheatsheet](./docs/template-authoring.md) &mdash; read this once before writing your own template
147+
- [Templates v2 landing](./docs/templates-v2.md) &mdash; CV / cover-letter / invoice / proposal preset library
110148
- [Examples gallery](./examples/README.md) &mdash; every runnable example with PDF preview
111149
- [Architecture](./docs/architecture.md) · [Lifecycle](./docs/lifecycle.md) · [Production rendering](./docs/production-rendering.md)
112150
- Recipes: [shape-as-container](./docs/recipes/shape-as-container.md) · [transforms](./docs/recipes/transforms.md) · [tables](./docs/recipes/tables.md) · [themes](./docs/recipes/themes.md) · [streaming](./docs/recipes/streaming.md) · [extending](./docs/recipes/extending.md)

docs/templates-v2.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Templates v2 &mdash; CV, cover letter, invoice, proposal
2+
3+
GraphCompose v1.6 ships a rebuilt canonical template surface for the four
4+
business document shapes: **CV, cover letter, invoice, proposal**. Every
5+
preset is one final class with one `create(BusinessTheme)` factory, and
6+
the spec / preset / theme split is the same across all four domains so a
7+
caller learns it once and reuses it everywhere.
8+
9+
This page is a landing reference. For a full conceptual walk-through
10+
(four-layer architecture, when to extend a preset vs. write your own,
11+
how rendering decisions cascade through theme tokens), read
12+
[`docs/template-authoring.md`](./template-authoring.md). For the v1 → v2
13+
upgrade table (every old class → its v2 replacement, with before/after
14+
code), read [`docs/migration-v1-5-to-v1-6.md`](./migration-v1-5-to-v1-6.md).
15+
16+
---
17+
18+
## Architecture in four layers
19+
20+
Every Templates v2 preset is composed in four layers, top-to-bottom:
21+
22+
1. **Theme tokens** &mdash; `BusinessTheme` + `Spacing` + `Typography`. Colours, type scale, gutters, accent rules.
23+
2. **Layout slots** &mdash; `SingleColumn`, `TwoColumnSidebar`, `ThreeColumnMagazine`, `LetterFormat`. The page geometry strategy.
24+
3. **Components + blocks** &mdash; `Header`, `Module`, `MarkdownText`; sealed `Block` hierarchy (`ParagraphBlock`, `BulletListBlock`, `KeyValueBlock`, `IndentedBlock`, `MultiParagraphBlock`).
25+
4. **Spec data** &mdash; `CvSpec`, `CoverLetterSpec`, `InvoiceSpec`, `ProposalSpec`. The plain-Java record carrying the document's content.
26+
27+
Presets glue 1+2+3 together; a caller hands them 4. Adjusting one visual
28+
decision is one method on one preset, never a fork of a 600-line composer.
29+
30+
---
31+
32+
## Quick start
33+
34+
```java
35+
import com.demcha.compose.document.templates.cv.presets.ModernProfessional;
36+
import com.demcha.compose.document.templates.cv.spec.CvSpec;
37+
import com.demcha.compose.document.templates.api.DocumentTemplate;
38+
import com.demcha.compose.document.theme.BusinessTheme;
39+
40+
DocumentTemplate<CvSpec> template = ModernProfessional.create(BusinessTheme.modern());
41+
template.compose(session, mySpec);
42+
```
43+
44+
Same shape for cover letters, invoices, and proposals &mdash; swap the
45+
package, the spec type, and the preset class.
46+
47+
---
48+
49+
## CV preset gallery (14)
50+
51+
Each preset is a one-class final type with `RECOMMENDED_MARGIN` and
52+
`create(BusinessTheme)`. Visual baselines are pixel-diff verified against
53+
v1 reference renders.
54+
55+
| Preset | Layout | Notes |
56+
|---|---|---|
57+
| `ModernProfessional` | Single column | Slate-blue name + royal-blue underlined links; canonical default |
58+
| `NordicClean` | Two-column sidebar | Soft-tinted profile panel on the left |
59+
| `ClassicSerif` | Two-page editorial | Serif-only typography, restrained accents |
60+
| `CompactMono` | Single column | Tight grid for technical CVs |
61+
| `Executive` | Two-column sidebar | Larger accent rule + uppercase section heads |
62+
| `EngineeringResume` | Two-column sidebar | Dense skill stack, code-friendly mono |
63+
| `TimelineMinimal` | Single column | Vertical rule + dot timeline along the left margin |
64+
| `BoxedSections` | Single column | Section headers in tinted boxes with full-width rule |
65+
| `CenteredHeadline` | Single column | Centered name + bullet & key-value sections |
66+
| `BlueBanner` | Single column | Full-width section banners in theme accent |
67+
| `EditorialBlue` | Single column | Slab subtitle + jobTitle line + uppercase rule |
68+
| `Panel` | Two-column sidebar | Soft-tinted panel for sidebar; project-leader shape |
69+
| `SidebarPortrait` | Two-column sidebar | Portrait + sidebar fill to page bottom |
70+
| `MonogramSidebar` | Two-column sidebar | Monogram badge + sidebar fill |
71+
72+
## Cover-letter preset gallery (14, paired)
73+
74+
Each cover-letter preset pairs visually with its same-named CV preset
75+
(palette, header rhythm, accent rule). Mix-and-match is supported but the
76+
default pairing produces the cleanest visual.
77+
78+
`ModernProfessional` · `NordicClean` · `ClassicSerif` · `CompactMono`
79+
· `Executive` · `EngineeringResume` · `TimelineMinimal` · `BoxedSections`
80+
· `CenteredHeadline` · `BlueBanner` · `EditorialBlue` · `Panel`
81+
· `SidebarPortrait` · `MonogramSidebar`
82+
83+
Render any preset against a sample spec to inspect the output:
84+
85+
```bash
86+
./mvnw -f examples/pom.xml exec:java \
87+
-Dexec.mainClass=com.demcha.examples.templates.cv.CvTemplateGalleryFileExample
88+
```
89+
90+
The runnable gallery writes one PDF per preset under
91+
`examples/target/generated-pdfs/templates/cv/`. The cover-letter gallery
92+
mirrors the layout under `templates/coverletter/`.
93+
94+
---
95+
96+
## Invoice + proposal (minimal v2 surface)
97+
98+
`ModernInvoice` and `ModernProposal` ship as the canonical builder seam
99+
for invoices and proposals respectively. Cinematic feature parity
100+
(rich hero blocks, accent-driven section bands) lives in
101+
`InvoiceTemplateV2` / `ProposalTemplateV2` under
102+
`templates/builtins/` &mdash; those remain the recommended path when full
103+
visual styling is required, while the v2 builders provide a smaller,
104+
copy-and-tweak entry point for callers extending their own branding.
105+
106+
---
107+
108+
## Authoring features built into every preset
109+
110+
- **Inline markdown** &mdash; body strings carrying `**bold**` and `*italic*` markers render with proper `DocumentTextDecoration` via `templates.components.MarkdownText`.
111+
- **Active hyperlinks** &mdash; header email + LinkedIn / GitHub labels become clickable `mailto:` / `https:` runs via `DocumentLinkOptions`.
112+
- **Slot-based layouts** &mdash; multi-column presets (`Panel`, `SidebarPortrait`, `MonogramSidebar`) declare named slots (`MAIN`, `SIDEBAR`); custom presets rearrange modules via `.place(slot, "Module Name", ...)`.
113+
- **Adaptive sidebar fill** &mdash; sidebar layouts size the trailing spacer dynamically from `canvas().innerHeight()` so background panels reach the page bottom on A4 / Letter / smaller fixtures without overflow.
114+
- **`CvHeader.jobTitle` subtitle** &mdash; presets that surface a subtitle (`EditorialBlue`, `Panel`, `SidebarPortrait`, `MonogramSidebar`) read it from the spec; an empty value falls back to a placeholder.
115+
116+
---
117+
118+
## Visual parity & regression coverage
119+
120+
- **28 layout-snapshot baselines** under `src/test/resources/layout-snapshots/canonical-templates/{cv-v2,coverletter-v2}/` lock the rendered tree of every preset.
121+
- **29 pixel-diff baselines** under `src/test/resources/visual-baselines/{cv-v2,coverletter-v2}/` enforce per-channel rendering parity against the v1 reference renders. The gate runs on every CI build with a calibrated `mismatchedPixelBudget` for cross-platform PDFBox font drift.
122+
- Re-bless after a deliberate visual change with `-Dgraphcompose.visual.approve=true`.
123+
124+
---
125+
126+
## Migration from v1 templates
127+
128+
Legacy CV / cover-letter classes (`CvTemplateV1`, `NordicCleanCvTemplate`,
129+
`MonogramSidebarCvTemplate`, ...) are **deleted**, not deprecated, in
130+
v1.6. Any code constructing those classes must switch to the matching v2
131+
preset's `create(BusinessTheme)` factory. The full mapping (every old
132+
class → its v2 replacement, with side-by-side code) is documented in
133+
[`docs/migration-v1-5-to-v1-6.md`](./migration-v1-5-to-v1-6.md).

0 commit comments

Comments
 (0)