diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c631504e8..b268dafca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,7 +166,8 @@ jobs: cache: maven - name: Compare public API against baseline - # The `japicmp` profile pulls the v1.6.5 jar from JitPack and + # The `japicmp` profile resolves the prior published jar (currently + # v1.6.5 from JitPack; v1.6.6 and later from 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). diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8027c1cac..4d3c4580f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,8 +9,8 @@ name: Publish to Maven Central # workflow alone via workflow_dispatch if Central had a transient # validator hiccup without re-cutting the tag. # -# Hyphenated tags (rc / alpha / beta / SNAPSHOT) are skipped: those go -# only to JitPack and the GitHub Release pre-release, never to Central +# Hyphenated tags (rc / alpha / beta / SNAPSHOT) are skipped: those +# ship only to the GitHub Release pre-release surface, never to Central # (Central's validator rejects SNAPSHOT-style coordinates anyway). # # Human prerequisites (one-time per repo): @@ -46,8 +46,7 @@ jobs: name: Publish ${{ github.ref_name }} to Maven Central runs-on: ubuntu-latest # Only ship plain semver tags (vX.Y.Z) to Central. Pre-release tags - # like v1.7.0-rc.1 ship to JitPack + the GitHub Release pre-release - # surface only. + # like v1.7.0-rc.1 ship to the GitHub Release pre-release surface only. if: | github.event_name == 'workflow_dispatch' || (!contains(github.ref, '-rc') && !contains(github.ref, '-alpha') && !contains(github.ref, '-beta') && !contains(github.ref, '-snapshot')) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 98203607d..90468f170 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,9 +76,9 @@ GraphCompose follows a fork → feature branch → pull request flow. Exte ### Release flow -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. +1. **Release prep** lands on `develop` — version bumps propagate via `aggregator/pom.xml` to all modules in one pass; fresh CHANGELOG entry; migration guide for minor releases. **README install snippet stays pinned to the previously published version** until Maven Central confirms the new artifact, 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. +3. **Maven Central** picks up the new tag automatically via [`.github/workflows/publish.yml`](./.github/workflows/publish.yml) — the workflow re-runs `mvnw verify` at the tagged commit, signs the four artefacts (main / sources / javadoc / pom) with the repo's GPG key, and uploads via the `central-publishing-maven-plugin`. Hyphenated tags (`-rc`, `-alpha`, `-beta`) are skipped on Central; they ship only to the GitHub Release pre-release surface. Javadocs auto-publish to [javadoc.io/doc/io.github.demchaav/graphcompose](https://javadoc.io/doc/io.github.demchaav/graphcompose) shortly after each Central release. 4. **GitHub Release** is created with notes from the matching `CHANGELOG.md` section. See [docs/contributing/release-process.md](./docs/contributing/release-process.md) for the full checklist (audit gates, hotfix protocol, lessons learned). diff --git a/ROADMAP.md b/ROADMAP.md index 8ef2b59d9..efa105edb 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,12 +8,12 @@ In flight on `main` / `develop`. - v1.6 polish — documentation, examples, visual baselines, fixes. - Open-source hygiene — security policy, support guidance, dependency automation, security scanning. +- **Maven Central distribution** — debut shipping in v1.6.6 under `io.github.demchaav:graphcompose`. Replaces JitPack as the primary install channel; the JitPack URL stays alive for existing pinned consumers but is no longer documented as a primary option. Tracked in [#7](https://github.com/DemchaAV/GraphCompose/issues/7). ## Next (v1.7) Committed direction. Tracked in CHANGELOG (Phase E) and issues. -- **Maven Central distribution** — replace JitPack as the primary install channel. Tracked in [#7](https://github.com/DemchaAV/GraphCompose/issues/7). - **JMH benchmark migration** — replace the current custom benchmark harness with `org.openjdk.jmh` so the published numbers are credible and machine-comparable. - **Templates v2 component refactor** — 13 of the 14 v2 CV presets are currently hand-coded `DocumentTemplate` subclasses. Route more visual decisions through `CvBuilder` and equivalent component recipes so each preset becomes a thin composition rather than a 400–700-line class. diff --git a/SECURITY.md b/SECURITY.md index 586441554..b1625ec56 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -47,7 +47,7 @@ In scope: - DOCX / PPTX semantic backends (`com.demcha.compose.document.backend.semantic`). - Templates shipped in `com.demcha.compose.document.templates`. - Public authoring API (`GraphCompose`, `DocumentSession`, DSL). -- Build and release artifacts on JitPack (and Maven Central once published). +- Build and release artifacts on Maven Central (`io.github.demchaav:graphcompose`). The legacy JitPack URL remains available for consumers pinned to v1.6.5 and earlier but is no longer the documented install channel. Out of scope: diff --git a/docs/README.md b/docs/README.md index 304c39843..e4dab1880 100644 --- a/docs/README.md +++ b/docs/README.md @@ -49,7 +49,7 @@ back here. ### Contributing - **[contributing/extension-guide.md](contributing/extension-guide.md)** — add a new node type, backend handler, or theme primitive. - **[contributing/implementation-guide.md](contributing/implementation-guide.md)** — internal engine notes for contributors hacking on layout / measurement / pagination. -- **[contributing/release-process.md](contributing/release-process.md)** — versioning, tag procedure, JitPack publication. +- **[contributing/release-process.md](contributing/release-process.md)** — versioning, tag procedure, Maven Central publication. ### Roadmaps & migrations - **[roadmaps/v1.6-roadmap.md](roadmaps/v1.6-roadmap.md)** — current development roadmap. diff --git a/docs/SHOWCASE.md b/docs/SHOWCASE.md index 5e2a30ef9..08ee201dc 100644 --- a/docs/SHOWCASE.md +++ b/docs/SHOWCASE.md @@ -51,8 +51,8 @@ The gallery is driven by code, not by hand-editing JSON. Source of truth: ## Version and source links - The displayed version lives **only** in `index.html` (JSON-LD - `softwareVersion`, the JitPack download URL, the hero badge, and the Maven + - Gradle install snippets). It does not inherit from the pom. + `softwareVersion`, the Maven Central artefact URL, the hero badge, and the + Maven + Gradle install snippets). It does not inherit from the pom. - `scripts/cut-release.ps1` flips all of those — plus the README and poms — to the release tag in the release commit, and `VersionConsistencyGuardTest` fails the `verify` gate if any of them drift out of sync with the library diff --git a/docs/contributing/release-process.md b/docs/contributing/release-process.md index 903371439..d3201de0b 100644 --- a/docs/contributing/release-process.md +++ b/docs/contributing/release-process.md @@ -2,8 +2,8 @@ This is the canonical release runbook for GraphCompose 1.x. -- JitPack — `com.github.DemchaAV:GraphCompose:v` (current) -- Maven Central — `io.github.demchaav:graphcompose:` (planned, v1.7+) +- Maven Central — `io.github.demchaav:graphcompose:` (canonical, from v1.6.6) +- JitPack — `com.github.DemchaAV:GraphCompose:v` (legacy; resolves for callers pinned to v1.6.5 and earlier, no longer the documented install channel) The release workflow is automated by [`scripts/cut-release.ps1`](../scripts/cut-release.ps1). The script must run from the `develop` branch with a clean working tree. The agent (Claude / Codex) **must complete every audit gate below before a release tag is cut**, and **must wait for explicit human approval** ("yes, cut the tag" / "делаем тег") before invoking the script. @@ -36,7 +36,7 @@ The shell setup and exact PowerShell commands live in the `graphcompose-release- - [ ] `CHANGELOG.md` has a `## v — Planned` header at the top. The script flips `Planned` → today's date during release execution; if the header is missing or already dated, the script silently skips and the release ships with the wrong header. - [ ] CHANGELOG `v` section: every linked file resolves on disk. Common offenders: new `docs/adr/00XX-*.md`, `docs/migration-v1-N-to-v1-M.md`, recipe pages. - [ ] `README.md` test-count claim matches the actual surefire total (`grep -E '[0-9]+ green tests' README.md` vs the surefire aggregate). -- [ ] `README.md` install snippets match the **current** `pom.xml` version (on `develop` between releases that is the last published tag). `VersionConsistencyGuardTest` enforces README == pom, so the two move together: `cut-release.ps1` rewrites the README Maven + Gradle JitPack snippets to `v` in the *same* release commit it bumps the POMs (section 1, Step 2/6). The README therefore flips to `v` at release-execution time, never on `develop` ahead of the tag — a snippet pointing at a tag that does not exist yet would break JitPack for any user who copies it. Do **not** hand-flip the README ahead of the script: that desyncs README from the still-unbumped pom and fails the guard at the verify gate. +- [ ] `README.md` install snippets match the **current** `pom.xml` version (on `develop` between releases that is the last published version). `VersionConsistencyGuardTest` enforces README == pom, so the two move together: `cut-release.ps1` rewrites the README Maven + Gradle install snippets to the new version in the *same* release commit it bumps the POMs (section 1, Step 2/6). The README therefore flips to the new version at release-execution time, never on `develop` ahead of the tag — a snippet pointing at a version that has not been published yet would 404 for any user who copies it. Do **not** hand-flip the README ahead of the script: that desyncs README from the still-unbumped pom and fails the guard at the verify gate. - [ ] `README.md` and `examples/README.md` link audits resolve: every `(./...)` and `(../...)` link must exist on disk. Use `grep -oE '\(\.?\.?/[^)]+\.(md|java|png|pdf|jpg)\)' README.md examples/README.md | sed 's/^(//;s/)$//' | sort -u | xargs -I{} test -e {} || echo MISSING: {}`. - [ ] `examples/README.md` gallery row count matches the file count: `find examples/src/main/java -name '*Example.java' | wc -l` equals `grep -c '^| \[' examples/README.md`. - [ ] For minor releases (`vX.Y.0`): `docs/migration-v1--to-v1-.md` exists. Patch releases skip this. @@ -59,7 +59,7 @@ The script's Step 1–4 mutates these. The agent only confirms the *current stat Running `pwsh ./scripts/cut-release.ps1 -Version ` performs: 1. **Pre-flight** — re-checks all of A above (branch, clean tree, in-sync, no existing tag). -2. **Bump versions** to `` across the library `pom.xml`, the `aggregator/pom.xml`, the inherited `` refs in `examples/pom.xml` and `benchmarks/pom.xml`, **and** the README Maven + Gradle JitPack install snippets — all in one pass, so `VersionConsistencyGuardTest` stays green at Step 5. +2. **Bump versions** to `` across the library `pom.xml`, the `aggregator/pom.xml`, the inherited `` refs in `examples/pom.xml` and `benchmarks/pom.xml`, **and** the README Maven + Gradle install snippets — all in one pass, so `VersionConsistencyGuardTest` stays green at Step 5. 3. **Date the CHANGELOG** — flips `## v — Planned` to `## v`. 4. **Switch ShowcaseMetadata GH_BASE** from `/blob/develop` to `/blob/v` and regenerate `docs/examples.json`. 5. **`mvnw verify -pl .`** — full sanity build (skip with `-SkipVerify` only if you just ran it). @@ -86,15 +86,15 @@ The script does **not** handle these. They are either pre-release or post-releas Run within 1 hour of the tag push. Independent steps can run in parallel. -1. **Wait for JitPack `BUILD SUCCESS`** — `https://jitpack.io/com/github/DemchaAV/GraphCompose/v/build.log` ends in `BUILD SUCCESS`. Then: -2. **README install snippets** — already flipped to `v` by `cut-release.ps1` in the release commit (section 1, Step 2/6) and enforced by `VersionConsistencyGuardTest`. No separate post-release commit is needed; just confirm the JitPack `BUILD SUCCESS` above means the version the README now advertises actually resolves. +1. **Wait for Maven Central artefact** — once `.github/workflows/publish.yml` turns green (see step 9 below), poll `mvn dependency:get -DgroupId=io.github.demchaav -DartifactId=graphcompose -Dversion=` until it resolves (usually 5–15 minutes after the workflow finishes). Then: +2. **README install snippets** — already flipped to `` by `cut-release.ps1` in the release commit (section 1, Step 2/6) and enforced by `VersionConsistencyGuardTest`. No separate post-release commit is needed; just confirm the Central artefact resolves (step 1 above) means the version the README now advertises actually exists. 3. **Merge `develop` → `main`** on GitHub so GitHub Pages picks up the new docs. Fast-forward only — never force-push `main`. If the push is rejected with `non-fast-forward`, a hotfix landed on `main` after the audit and the merge has to be redone after merging `origin/main` back into `develop`. 4. **Verify CI green on main** — `gh run list --branch main --limit 1` shows `success` for the tag commit. -5. **Smoke-test the JitPack snippet** — minimal POM in `$env:TEMP`, `mvn dependency:resolve` against the snippet copy-pasted from README, expect 0 exit. +5. **Smoke-test the install snippet** — minimal POM in `$env:TEMP`, `mvn dependency:resolve` against the snippet copy-pasted from README, expect 0 exit. 6. **Re-run all examples against the published artifact** — `./mvnw -f examples/pom.xml clean package` followed by `exec:java -Dexec.mainClass=com.demcha.examples.GenerateAllExamples`. Expect 26+ `Generated:` lines. 7. **Flip ShowcaseMetadata back to develop** — `pwsh ./scripts/cut-release.ps1 -PostReleaseOnly`. This restores linkable "View Code" buttons for ongoing v1.x.y dev work. 8. **GitHub Release — automated.** Pushing the `v` tag triggers [`.github/workflows/release.yml`](../../.github/workflows/release.yml): it re-runs `./mvnw clean verify -pl .` against the tagged commit, then creates the Release with that version's CHANGELOG section as the body (hyphenated tags like `v1.7.0-rc.1` ship as pre-releases; the step is idempotent — it edits the notes if the Release already exists). The workflow titles it `GraphCompose v`; for a **minor** release, edit the title to add the codename (`v1.4`=cinematic, `v1.5`=intuitive, `v1.6`=expressive; patches drop it). Create the Release by hand (`gh release create v --notes-file `) only if the workflow is unavailable. -9. **Maven Central publish — automated (from v1.6.6).** The same `v` tag push triggers [`.github/workflows/publish.yml`](../../.github/workflows/publish.yml): it re-runs `mvnw verify` at the tagged commit, signs the four artefacts (main / sources / javadoc / pom) with the repo's GPG key, and uploads to Maven Central via the `central-publishing-maven-plugin`. Hyphenated tags (`-rc`, `-alpha`, `-beta`, `-snapshot`) are skipped — those go only to JitPack + the GitHub Release pre-release surface. `autoPublish=false` in the plugin config means the artefact lands in the Central validation queue; the maintainer flips the switch on [central.sonatype.com](https://central.sonatype.com) for the first publish, then can opt into auto-release in a follow-up. Verify via `mvn dependency:get -DgroupId=io.github.demchaav -DartifactId=graphcompose -Dversion=` once the artifact appears (usually 5–15 minutes after the workflow turns green). +9. **Maven Central publish — automated (from v1.6.6).** The same `v` tag push triggers [`.github/workflows/publish.yml`](../../.github/workflows/publish.yml): it re-runs `mvnw verify` at the tagged commit, signs the four artefacts (main / sources / javadoc / pom) with the repo's GPG key, and uploads to Maven Central via the `central-publishing-maven-plugin`. Hyphenated tags (`-rc`, `-alpha`, `-beta`, `-snapshot`) are skipped — those go only to the GitHub Release pre-release surface. `autoPublish=false` in the plugin config means the artefact lands in the Central validation queue; the maintainer flips the switch on [central.sonatype.com](https://central.sonatype.com) for the first publish, then can opt into auto-release in a follow-up. Verify via `mvn dependency:get -DgroupId=io.github.demchaav -DartifactId=graphcompose -Dversion=` once the artifact appears (usually 5–15 minutes after the workflow turns green). 10. **Optional**: GitHub Discussions announcement (mirror the prior release's style; close with *"author intent, not coordinates"*), LinkedIn post, r/java post. The release is **done** only when steps 1–7 are all green; step 9 adds Maven Central availability once the D-track of v1.6.6 has shipped. @@ -126,13 +126,13 @@ These steps are done **once per repo** before the publish workflow can succeed; - `CENTRAL_TOKEN` — token password from step 4. 6. **Test the wiring on a release-candidate tag** *before* the first real release. `v1.6.6-rc.1` (hyphenated) skips Central per `publish.yml`'s `if:` guard, so it's safe — alternatively, cut `v1.6.6` for real and observe the workflow; `autoPublish=false` means a failed validation does not pollute Central, the artefact just sits in the validation queue until manually released or deleted. -If any of these stop working between releases (key expired, token rotated), the publish workflow surfaces the failure inside the workflow run — the GitHub Release and the JitPack artefact are still cut by the other workflows. +If any of these stop working between releases (key expired, token rotated), the publish workflow surfaces the failure inside the workflow run — the GitHub Release is still cut by the other workflow, and the legacy JitPack URL keeps resolving for callers pinned to earlier versions. --- -## 3. Hotfix protocol (CI red after tag, or JitPack didn't pick up) +## 3. Hotfix protocol (CI red after tag, or Central didn't pick up) -The published jar is final. **Never force-move a tag** that JitPack has already built — JitPack caches by tag SHA and won't rebuild. Always fix forward with a `vX.Y.Z+1` patch tag. +The published jar is final. **Never force-move a tag** that Maven Central has already validated — Central rejects re-uploading the same coordinates, and JitPack (still building legacy v1.6.5 and earlier) caches by tag SHA and won't rebuild either. Always fix forward with a `vX.Y.Z+1` patch tag. - Diagnose: `gh run view --log-failed`. The `Tests run: , Failures: ` line is the source of truth, not the trace excerpt in the Actions UI annotation. - Fix the test or doc, not the published artifact. @@ -172,7 +172,7 @@ Each learning maps to a check above. ## 5. Never do (during release) -- Force-move a tag JitPack has already built — publish a new patch tag instead. +- Force-move a tag that Maven Central has already validated or that JitPack has already built — Central rejects re-upload of the same coordinates, JitPack caches by tag SHA. Publish a new patch tag instead. - Skip the `origin/main → develop` merge before tagging. - Use `git add .` or `git add -A` — the develop tree often has accidental untracked junk. Stage by exact filename. - Skip the full `GenerateAllExamples` regen — `mvn test` does not catch runtime layout exceptions in fixed-column tables. @@ -189,9 +189,10 @@ The release is **done** when all of these are true: - [ ] Tag visible at `https://github.com/DemchaAV/GraphCompose/releases/tag/v` - [ ] GitHub Release created with the CHANGELOG `v` body - [ ] CI green on `main` for the tag commit -- [ ] JitPack `build.log` ends in `BUILD SUCCESS` -- [ ] `mvn dependency:resolve` succeeds against the README JitPack snippet -- [ ] README install snippets read `v` (flipped by the release commit; `VersionConsistencyGuardTest` green) +- [ ] `.github/workflows/publish.yml` succeeded for the tag +- [ ] Maven Central artefact resolves: `mvn dependency:get -DgroupId=io.github.demchaav -DartifactId=graphcompose -Dversion=` exit 0 +- [ ] `mvn dependency:resolve` succeeds against the README install snippet +- [ ] README install snippets read `` (flipped by the release commit; `VersionConsistencyGuardTest` green) - [ ] `develop` and `main` synced at the same SHA - [ ] Working tree clean on develop (`git status --short` empty) - [ ] `ShowcaseMetadata.GH_BASE` flipped back to `/blob/develop` (run `cut-release.ps1 -PostReleaseOnly`) diff --git a/docs/roadmaps/v1.6-roadmap.md b/docs/roadmaps/v1.6-roadmap.md index 8477ba48d..198565a71 100644 --- a/docs/roadmaps/v1.6-roadmap.md +++ b/docs/roadmaps/v1.6-roadmap.md @@ -176,19 +176,19 @@ builds it out into a working semantic exporter against Apache POI. ### Phase E — Maven Central distribution -JitPack stays as a fallback, but Maven Central is the standard for -Java open-source libraries. +Maven Central becomes the canonical install channel from v1.6.6 +onwards. The legacy JitPack URL keeps resolving for callers pinned to +v1.6.5 and earlier but is no longer the documented install option. **Scope** -- Sonatype OSSRH account +- Sonatype Central namespace verification (`io.github.demchaav`) - GPG signing of release artifacts -- `maven-deploy-plugin` configuration in `pom.xml` -- README install snippets switch from - `com.github.demchaav:GraphCompose:v1.6.0` to - `io.github.demchaav:graphcompose:1.6.0` as the primary form - (JitPack stays documented as a fallback) +- `central-publishing-maven-plugin` configuration in `pom.xml` +- README install snippet switches to + `io.github.demchaav:graphcompose:` as the only documented form - automated deployment via GitHub Actions on tag push + (`.github/workflows/publish.yml`) ### Phase F — Benchmark infrastructure modernisation @@ -326,9 +326,8 @@ roadmap: ## Release identity -- Maven coordinates `io.github.demchaav:graphcompose:1.6.0` -- JitPack coordinates `com.github.demchaav:GraphCompose:v1.6.0` -- Tag `v1.6.0` on `main` after develop merge +- Maven Central coordinates `io.github.demchaav:graphcompose:` (canonical; debut at 1.6.6) +- Tag `vX.Y.Z` on `main` after develop merge - Migration guide at `docs/roadmaps/migration-v1-5-to-v1-6.md` ## References diff --git a/docs/templates/which-template-system.md b/docs/templates/which-template-system.md index 1a88bf9c4..a55335d3d 100644 --- a/docs/templates/which-template-system.md +++ b/docs/templates/which-template-system.md @@ -207,10 +207,11 @@ private taskboard. ### Maven coordinates do **not** change in 2.0 -The library `pom.xml` artifact id stays `graphcompose`; JitPack -coordinates (`com.github.DemchaAV:GraphCompose:v`) and the Maven -Central coordinates being introduced in 1.6.6 (`io.github.demchaav:graphcompose:`) -both carry through to 2.0. +The library `pom.xml` artifact id stays `graphcompose`. The Maven Central +coordinates introduced in 1.6.6 (`io.github.demchaav:graphcompose:`) +carry through to 2.0 unchanged. The legacy JitPack URL +(`com.github.DemchaAV:GraphCompose:v`) remains resolvable for callers +pinned to v1.6.5 and earlier but is not the documented install channel. ---