diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..aeba6d4d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,36 @@ +--- +name: Bug report +about: Report a defect in GraphCompose +title: "[BUG] " +labels: bug +--- + +## What I expected + + + +## What actually happened + + + +## How to reproduce + +```java +// Minimal, runnable Java code that triggers the issue. +// Prefer the canonical `GraphCompose.document(...)` API. +DocumentSession document = GraphCompose.document(Path.of("repro.pdf")) + .pageSize(DocumentPageSize.A4) + .create(); +// ... +``` + +## Environment + +- GraphCompose version: +- Java: +- OS: +- PDFBox: + +## Additional context + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..199d73cb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,36 @@ +--- +name: Feature request +about: Propose a new feature, public API addition, or template +title: "[FEATURE] " +labels: enhancement +--- + +## Use case + + + +## Proposed API + +```java +// Sketch the public-API shape you'd like to use. +// Stick to the canonical surface: GraphCompose.document(...), DocumentSession, +// document.pageFlow(...), DocumentNode + NodeDefinition, BusinessTheme. +document.pageFlow().add???(...); +``` + +## Alternatives considered + + + +## Would this be a breaking change? + +- [ ] No — additive only (new node, new builder method, new template preset). +- [ ] Possibly — affects public-record shape, deprecates an existing API, or changes default rendering behaviour. + +## Optional: ADR-worthy? + +If this is a structural change (sealed hierarchy, new sub-package, new SPI), please describe the architectural impact briefly. The maintainer may ask for a draft ADR under `docs/adr/` before implementation. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..1b65657c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,25 @@ +## Summary + + + +## Type of change + +- [ ] Bug fix (no public API change) +- [ ] New feature / public API addition +- [ ] Documentation only +- [ ] CI / build / tooling +- [ ] Refactor (no behavioural change) + +## Checklist + +- [ ] **PR targets `develop`** (the integration branch); **not `main`**. +- [ ] Branch name follows `/` (e.g. `feature/canvas-clip`, `fix/table-overflow`, `docs/recipe-themes`); issue-prefixed names like `42/fix/short-description` are also fine. +- [ ] `./mvnw -B -ntp clean verify` passes locally. +- [ ] **Java 17 compatible** — no `List.getFirst()` / `getLast()`, no `Thread.threadId()`, no switch type / deconstruction patterns, no `case null, default ->`. CI matrices Temurin 17 / 21 / 25 and will catch JDK regressions. +- [ ] **Public API change** (if any): `CHANGELOG.md` entry added under the next `## v — Planned` heading. +- [ ] **README touched** (if any): `DocumentationCoverageTest.readmeShouldUseCanonicalDslAndAvoidLegacyApis` still passes — canonical fingerprints (`GraphCompose.document(`, `DocumentSession`, `document.pageFlow(`, `BusinessTheme`) preserved, no legacy tokens (`GraphCompose.pdf(`, `PdfComposer`, `CvTemplateV1`, …). +- [ ] **Examples touched** (if any): runnable via `./mvnw -f examples/pom.xml exec:java -Dexec.mainClass=…`; if a new example, also added to `GenerateAllExamples` and the gallery row count in `examples/README.md`. + +## Linked issue + +Closes # diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..2850189c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and maintainers pledge to make participation in +the GraphCompose community a harassment-free experience for everyone, regardless +of age, body size, visible or invisible disability, ethnicity, sex +characteristics, gender identity and expression, level of experience, education, +socio-economic status, nationality, personal appearance, race, religion, or +sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behaviour that contributes to a positive environment: + +- Demonstrating empathy and kindness toward other people. +- Being respectful of differing opinions, viewpoints, and experiences. +- Giving and gracefully accepting constructive feedback. +- Accepting responsibility and apologising to those affected by our mistakes, + and learning from the experience. +- Focusing on what is best not just for us as individuals, but for the overall + community. + +Examples of unacceptable behaviour: + +- The use of sexualised language or imagery, and sexual attention or advances of + any kind. +- Trolling, insulting or derogatory comments, and personal or political attacks. +- Public or private harassment. +- Publishing others' private information, such as a physical or email address, + without their explicit permission. +- Other conduct which could reasonably be considered inappropriate in a + professional setting. + +## Enforcement Responsibilities + +The maintainer ([@DemchaAV](https://github.com/DemchaAV)) is responsible for +clarifying and enforcing standards of acceptable behaviour and will take +appropriate and fair corrective action in response to any behaviour deemed +inappropriate, threatening, offensive, or harmful. + +The maintainer has the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces (this repository's +issues, pull requests, discussions, and any related channels), and also applies +when an individual is officially representing the community in public spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behaviour may be +reported privately to the maintainer at **demchyshyn.artem@gmail.com**. +All complaints will be reviewed and investigated promptly and fairly. +The maintainer is obligated to respect the privacy and security of the reporter +of any incident. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74fa5320..3a063b56 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,19 @@ Read these files first: They explain the current public surface, the engine/template split, and the recommended extension points. +## Java 17 baseline + +GraphCompose targets **Java 17+** as of v1.6.1. CI runs the full test suite against Temurin JDK 17 / 21 / 25 in parallel matrix, so JDK-incompatibility regressions fail the PR immediately. + +When writing new code, avoid Java 21+ APIs and language constructs that don't exist in 17: + +- `List.getFirst()` / `List.getLast()` → `list.get(0)` / `list.get(list.size() - 1)` +- `Thread.threadId()` → `Thread.getId()` +- `switch` with type patterns (`case Foo f -> …`) → `instanceof` if-else chains +- `switch` with deconstruction patterns (`case Foo(Bar b) -> …`) → `instanceof Foo f` + `f.bar()` +- `case null, default ->` → explicit `if (x == null) return …;` early return +- `List.reversed()` → `Collections.reverse(new ArrayList<>(list))` + ## Build and test - The blocking validation gate for repository work is `./mvnw -B -ntp clean verify`. @@ -33,7 +46,7 @@ GraphCompose follows a fork → feature branch → pull request flow. Exte git pull --ff-only origin develop git checkout -b feature/short-description ``` - Use `feature/...` for new functionality, `fix/...` for bug fixes, and `docs/...` for documentation-only changes. + Use `feature/...` for new functionality, `fix/...` for bug fixes, and `docs/...` for documentation-only changes. Issue-prefixed names (`42/fix/short-description`) are also welcome — convenient when the branch closes a specific issue. 3. **Commit small, focused changes.** Each commit message should describe the *why*, not just the *what*. Recent commits on `develop` (`Prepare v1.5.0 release`, `Align public docs with the canonical surface`) are reasonable length and structure templates. 4. **Run the validation gate locally** before opening a PR: ```bash @@ -41,7 +54,13 @@ GraphCompose follows a fork → feature branch → pull request flow. Exte ``` This runs the architecture-and-documentation guards plus the full test suite. The same gate runs in CI on every PR. 5. **Push** your feature branch to your fork and open a pull request against `develop` on `DemchaAV/GraphCompose`. Reference any related issue and describe the user-visible change in the PR body. -6. **CI runs automatically.** The required status checks are `Architecture and Documentation Guards` and `Build and run tests`. The PR cannot merge into a protected branch until both are green. +6. **CI runs automatically.** Active jobs: + - `Architecture and Documentation Guards` — fast canonical / engine-boundary guard tests, fail-first gate + - `Build and run tests (JDK 17)`, `(JDK 21)`, `(JDK 25)` — full `mvnw verify` in parallel matrix across the supported JVMs + - `Examples Generation Smoke Test` — regenerates all 26 runnable examples and uploads the PDFs as a CI artifact + - `Performance Smoke Check` — PR-only coarse benchmark to catch performance regressions + + The PR cannot merge into a protected branch until all required checks are green. 7. **Address review comments**, then squash any fixup commits before merge. The maintainer merges through GitHub once review is complete. ### Branch protection @@ -57,12 +76,12 @@ GraphCompose follows a fork → feature branch → pull request flow. Exte ### Release flow -1. Release prep lands on `develop` — version bump in `pom.xml` + `examples/pom.xml`, fresh CHANGELOG entry, README install snippets refreshed, migration guide updated when needed. -2. The maintainer merges `develop` into `main` via pull request — this is the only path a commit takes to reach `main`. -3. The maintainer tags the release on `main` (`vX.Y.Z`) and creates the GitHub release with notes copied from the matching `CHANGELOG.md` section. -4. JitPack picks up the new tag automatically; the `Installation` block in the README is the consumer-facing source of truth. +1. **Release prep** lands on `develop` — version bumps in `pom.xml`, `examples/pom.xml`, and `benchmarks/pom.xml`; fresh CHANGELOG entry; migration guide for minor releases. **README install snippets stay pinned to the previously published tag** (e.g. `v1.6.0`) until JitPack confirms the new build, otherwise consumers copying the snippet during the publish window hit a 404. +2. **`scripts/cut-release.ps1 -Version `** automates the bump + CHANGELOG date + commit + tag + push from `develop`. The maintainer fast-forwards `main` from `develop` after the tag lands (`git push origin develop:main`). +3. **JitPack** picks up the new tag automatically. After JitPack reports `BUILD SUCCESS`, a separate post-release commit on `develop` flips the README install snippets to the new version. +4. **GitHub Release** is created with notes from the matching `CHANGELOG.md` section. -See [docs/release-process.md](./docs/release-process.md) for the full checklist. +See [docs/release-process.md](./docs/release-process.md) for the full checklist (audit gates, hotfix protocol, lessons learned). ## Repository map @@ -95,7 +114,7 @@ See [docs/release-process.md](./docs/release-process.md) for the full checklist. 2. Keep structural cleanup separate from behavior changes whenever possible. 3. If you touch public examples or screenshots, update the related docs in the same change. 4. Run the smallest relevant tests while iterating, then run `./mvnw -B -ntp clean verify` before opening a pull request. -5. For quick visual iteration on a template, you can use the experimental live preview tool in test scope by running [GraphComposeDevTool.java](./src/test/java/com/demcha/compose/devtool/GraphComposeDevTool.java) and editing [LivePreviewProvider.java](./src/test/java/com/demcha/preview/LivePreviewProvider.java). +5. For quick visual iteration on a template, run [GraphComposeDevTool.java](./src/test/java/com/demcha/compose/devtool/GraphComposeDevTool.java) in test scope — it hot-reloads the rendered PDF as you edit your template source. ## Contributor architecture rules @@ -286,9 +305,10 @@ Choose the smallest tests that match the change: [ComputedPositionTest.java](./src/test/java/com/demcha/compose/engine/components/layout/ComputedPositionTest.java) - For pagination and multi-page behavior: [PageBreakerIntegrationTest.java](./src/test/java/com/demcha/compose/engine/integration/PageBreakerIntegrationTest.java) -- For concrete templates: - [BuiltInTemplateRenderTest.java](./src/test/java/com/demcha/compose/document/templates/builtins/BuiltInTemplateRenderTest.java) - [CvTemplateV1LayoutSnapshotTest.java](./src/test/java/com/demcha/compose/document/templates/builtins/CvTemplateV1LayoutSnapshotTest.java) +- For Templates v2 CV / cover-letter presets: + [PresetVisualParityTest.java (CV)](./src/test/java/com/demcha/compose/document/templates/cv/presets/PresetVisualParityTest.java) + [PresetVisualParityTest.java (cover letter)](./src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java) + [PresetLayoutSnapshotTest.java](./src/test/java/com/demcha/compose/document/templates/cv/presets/PresetLayoutSnapshotTest.java) If a change affects public docs, examples, or screenshots, update those assets in the same PR so the repository stays internally consistent.