Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c3bf3c7
Add design spec for decoupling lib/gui versioning
perNyfelt Aug 16, 2026
57e858c
gui: declare its own literal <version>, independent of lib's revision
perNyfelt Aug 16, 2026
26241b7
gui/MarkdownToPdf.xml: point the launcher dependency at gui's own ver…
perNyfelt Aug 16, 2026
30356d3
docs: describe gui's independent versioning in CLAUDE.md
perNyfelt Aug 16, 2026
5997e10
UpdateChecker: filter releases by MarkdownToPdf-v tag prefix instead …
perNyfelt Aug 16, 2026
375a1b9
release.sh: split lib/gui into independent release flows
perNyfelt Aug 16, 2026
9d44b54
install.sh, buildAndRun.sh: read gui's own version, not the shared re…
perNyfelt Aug 16, 2026
f081561
ci: split APP_VERSION/LIB_VERSION, upload the lib sources jar
perNyfelt Aug 16, 2026
249c709
docs: rewrite release-process.md for independent lib/gui releases
perNyfelt Aug 16, 2026
84f4575
docs: note that GitHub's repo-wide Latest badge can point at a lib-on…
perNyfelt Aug 16, 2026
ded86c6
docs: split the recovery section into lib and gui blocks
perNyfelt Aug 16, 2026
7cf2f79
docs: finalize versioning-decouple spec (6 review rounds) and add imp…
perNyfelt Aug 16, 2026
64475ef
Fix final-review findings on release tooling
perNyfelt Aug 16, 2026
1013d36
ci: catch gui/pom.xml and MarkdownToPdf.xml version drift on every pu…
perNyfelt Aug 16, 2026
7c4c169
Polish release scripts: robustify SKIP_DEPLOY, update stale comment
perNyfelt Aug 16, 2026
d8af72e
Fix update-checker review findings: drafts, poisoned versions, non-ar…
perNyfelt Aug 16, 2026
9a0bb90
Surface md2pdf library version in About dialog
perNyfelt Aug 16, 2026
c8e6aab
UpdateCheckResult: enforce the UpdateInfo-iff-UPDATE_AVAILABLE invariant
perNyfelt Aug 16, 2026
50d21b5
Fix GUI release updater compatibility
perNyfelt Aug 16, 2026
164fe0f
Harden release transition and update pagination
perNyfelt Aug 16, 2026
c780ae8
Complete release migration safeguards
perNyfelt Aug 16, 2026
9c37f88
Release GUI 0.2.1
perNyfelt Aug 16, 2026
08d2599
Bound update release pagination
perNyfelt Aug 16, 2026
0ef9f97
Harden compatibility release checks
perNyfelt Aug 16, 2026
3b725ee
Avoid migration release latest window
perNyfelt Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ jobs:
zsh -n gui/src/main/assembly/mac/markdownToPdf
zsh -n gui/src/main/assembly/mac/mkicns.zsh
# md2pdf-install.cmd has no linter; its native packaging and overlap jobs exercise it.
- run: cat .github/versions.env >> "$GITHUB_ENV"
- uses: actions/setup-java@v5
with:
java-version: ${{ env.LIBERICA_VERSION }}
distribution: liberica
java-package: jdk+fx
cache: maven
# release.sh's gui flow enforces this same lockstep at release time; checking it here
# too means drift is caught on every push/PR instead of sitting unnoticed until release.
- name: check gui/pom.xml and gui/MarkdownToPdf.xml stay in lockstep
run: |
POM_VERSION="$(mvn -q -pl gui org.apache.maven.plugins:maven-help-plugin:3.5.1:evaluate -Dexpression=project.version -DforceStdout)"
LAUNCHER_VERSION="$(sed -n -e '/<artifactId>MarkdownToPdf<\/artifactId>/,/<\/dependency>/ s/.*<version>\(.*\)<\/version>.*/\1/p' gui/MarkdownToPdf.xml)"
if [ "$POM_VERSION" != "$LAUNCHER_VERSION" ]; then
echo "gui/pom.xml's version ($POM_VERSION) does not match gui/MarkdownToPdf.xml's dependency version ($LAUNCHER_VERSION) — bump both together"
exit 1
fi

build:
strategy:
Expand Down Expand Up @@ -76,7 +93,9 @@ jobs:
run: sudo apt-get update && sudo apt-get install -y xvfb

- name: Read the project version
run: echo "APP_VERSION=$(mvn -q org.apache.maven.plugins:maven-help-plugin:3.5.1:evaluate -Dexpression=revision -DforceStdout)" >> "$GITHUB_ENV"
run: |
echo "APP_VERSION=$(mvn -q -pl gui org.apache.maven.plugins:maven-help-plugin:3.5.1:evaluate -Dexpression=project.version -DforceStdout)" >> "$GITHUB_ENV"
echo "LIB_VERSION=$(mvn -q org.apache.maven.plugins:maven-help-plugin:3.5.1:evaluate -Dexpression=revision -DforceStdout)" >> "$GITHUB_ENV"

- run: mvn install -DskipTests

Expand Down Expand Up @@ -155,8 +174,19 @@ jobs:
- uses: actions/upload-artifact@v7
if: matrix.platform == 'linux'
with:
name: md2pdf-${{ env.APP_VERSION }}-javadoc
path: lib/target/md2pdf-${{ env.APP_VERSION }}-javadoc.jar
name: md2pdf-${{ env.LIB_VERSION }}-javadoc
path: lib/target/md2pdf-${{ env.LIB_VERSION }}-javadoc.jar
if-no-files-found: error

- name: Build the sources jar
if: matrix.platform == 'linux'
run: mvn -pl lib source:jar

- uses: actions/upload-artifact@v7
if: matrix.platform == 'linux'
with:
name: md2pdf-${{ env.LIB_VERSION }}-sources
path: lib/target/md2pdf-${{ env.LIB_VERSION }}-sources.jar
if-no-files-found: error

install-failures:
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ SpotBugs runs at `verify` with `effort=Max`, `threshold=Medium`. False positives

## Module structure

This is a Maven multi-module project with `${revision}` CI-friendly versioning (resolved by flatten-maven-plugin).
This is a Maven multi-module project. `lib` uses `${revision}` CI-friendly versioning (resolved by flatten-maven-plugin); `gui` has its own independent `<version>`, see below.

### `lib` — the engine library (`se.alipsa:md2pdf`)

Expand Down Expand Up @@ -81,4 +81,4 @@ bundle their own Java 25 runtime, so end users do not need a JDK.
- **Zero new Maven dependencies** for anything in the `gui` model layer or `lib` core. The CSS round-trip parser in `StyleProfile.fromCss()` is intentionally hand-written for this reason.
- **No `--add-exports`/`--add-opens` config needed** — Spotless 3.x handles Google Java Format's module requirements automatically.
- Build-generated files such as `.flattened-pom.xml` and `dependency-reduced-pom.xml` are ignored by `.gitignore`; do not commit them.
- The `${revision}` property in the root POM controls the version for all modules. Bump it in `pom.xml` only; flatten-maven-plugin propagates it. `gui/MarkdownToPdf.xml` inherits the root parent, so its launcher dependency follows `${revision}` as well.
- The `${revision}` property in the root POM controls `lib`'s version (and the parent's). `gui` has its own independent `<version>` in `gui/pom.xml`, bumped separately at gui release time. A gui release requires bumping **two** files in lockstep: `gui/pom.xml`'s `<version>` and the dependency `<version>` in `gui/MarkdownToPdf.xml` (`release.sh gui` checks they match). `gui/MarkdownToPdf.xml`'s own `<parent>` reference still follows `${revision}` (i.e. lib's version) since that file is unchanged by gui's version override — only its dependency on the built `MarkdownToPdf` artifact needs gui's version directly.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ The installer checks for these and reports what is missing, but cannot install t
| `md2pdf-<version>-windows-x64.zip` | unzip, then double-click `md2pdf-install.cmd` | ~100 MB |
| `md2pdf-<version>-no-jdk.zip` | unzip, then `java --enable-native-access=javafx.graphics,javafx.web,javafx.media -jar MarkdownToPdf.jar` (needs a JavaFX-bundled JDK 25+) | ~15 MB |

GitHub's repo-sidebar "Latest" badge is repo-wide and can point at a `lib`-only release (which
ships no application) when one is newer than the latest `gui` release. Download the newest
release tagged `MarkdownToPdf-v*` specifically, not whatever the sidebar highlights.

Verify a download against `SHA256SUMS` from the same release:

Linux: sha256sum -c SHA256SUMS
Expand Down
75 changes: 57 additions & 18 deletions docs/release-process.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,66 @@
# MarkdownToPdf release process

Run `./release.sh` from a clean `main` checkout. It downloads the artifacts from the green CI
run for `HEAD`, publishes the library to Maven Central, creates the version tag and opens the
GitHub release. Use `./release.sh --skip-deploy` only when Maven Central already received the
release and a later release step needs recovery; see the recovery instructions in
[`gui/readme.md`](../gui/readme.md).
`lib` and `gui` release independently, on independent version numbers. `gui` releases never
touch Maven Central.

## Before releasing
```
./release.sh lib [--skip-deploy]
./release.sh gui
```

Bump `<revision>` in the root `pom.xml`, then give **all three** changelogs a
`## <version>` section — [`release.md`](../release.md), [`lib/release.md`](../lib/release.md)
and [`gui/release.md`](../gui/release.md). Each file covers only its own artifact:
`md2pdf-parent` for the shared build, CI and release tooling, `md2pdf` for the library, and
`MarkdownToPdf` for the desktop application.
Run either from a clean `main` checkout. Both download the artifacts from the green CI run for
`HEAD`, create the version tag, and open the GitHub release; `./release.sh lib` additionally
publishes the library to Maven Central. Use `./release.sh lib --skip-deploy` only when Maven
Central already received the release and a later release step needs recovery; see
[`gui/readme.md`](../gui/readme.md) for lib's and gui's recovery instructions.

`release.sh` composes the GitHub release notes from those three sections, one per artifact,
and checks them in its preconditions — before anything is downloaded and long before the
irreversible Maven Central deploy. A module whose heading still reads `-SNAPSHOT` has no
section for the version being released, and the run aborts with:
## Before releasing a lib version

Bump `<revision>` in the root `pom.xml`, then give **both** relevant changelogs a
`## <version>` section — [`release.md`](../release.md) and [`lib/release.md`](../lib/release.md).
`release.md` covers the shared build, CI and release tooling; `lib/release.md` covers the
library itself. (`0.2.0` was already released under the legacy bare `v0.2.0` tag — the first
lib release under the new `md2pdf-v<version>` scheme must be a version bumped past `0.2.0`.)

## Before releasing a gui version

Bump **two** files in lockstep:

- `gui/pom.xml`'s own `<version>`.
- The dependency `<version>` in `gui/MarkdownToPdf.xml` — `release.sh gui` checks these match
and refuses to proceed otherwise, but the values still have to be written by hand in both
places.

Then give [`gui/release.md`](../gui/release.md) a `## <version>` section. On the first gui release
under the new `MarkdownToPdf-v<version>` tag scheme, `release.sh` also creates a bare
`v<version>` compatibility release with the same assets. This lets installed 0.2.0-and-earlier
clients, which only understand the old tag scheme, update into the prefix-aware checker. (`0.2.0`
was already released under the legacy bare `v0.2.0` tag — the first gui release under the new
scheme must be a version bumped past `0.2.0`.)

The legacy updater only looks at the repository-wide `releases/latest` endpoint, so this migration
window closes as soon as either module publishes another release. `release.sh` verifies that the
compatibility release initially wins GitHub's latest-release selection; after that, leave both lib
and gui releases quiet for at least seven days to give normally active legacy installs time to run
their daily update check. Run the first new-style gui release in an exclusive release window: a
concurrent release can displace the compatibility release before the script verifies it, leaving
both tags and releases to clean up manually. This one-time compatibility flow requires a GitHub
CLI version that supports `gh release create --latest`; `release.sh` checks that capability before
publishing anything.

## What `release.sh` checks

`release.sh` composes the GitHub release notes from the relevant changelog section(s) above and
checks them in its preconditions — before anything is downloaded and long before the irreversible
Maven Central deploy (lib only). A module whose heading still reads `-SNAPSHOT` has no section for
the version being released, and the run aborts with:

ERROR: gui/release.md has no section for 0.1.1 — bump its heading from -SNAPSHOT before releasing

Push the release commit and wait for its CI run to go green before running `./release.sh`;
the script releases the artifacts built by the run for `HEAD`, so a later commit means a
later CI run and a re-check.
For a gui release, it also checks that `gui/MarkdownToPdf.xml`'s dependency version matches
`gui/pom.xml`'s version, and dies with a clear message before doing anything else if they've
drifted.

Push the release commit and wait for its CI run to go green before running `./release.sh lib [--skip-deploy]`
or `./release.sh gui`, as appropriate; the script releases the artifacts built by the run for
`HEAD`, so a later commit means a later CI run and a re-check.
Loading
Loading