Skip to content

Decouple lib and gui versioning and release flows - #11

Merged
perNyfelt merged 25 commits into
mainfrom
decouple-lib-gui-versioning-spec
Aug 16, 2026
Merged

Decouple lib and gui versioning and release flows#11
perNyfelt merged 25 commits into
mainfrom
decouple-lib-gui-versioning-spec

Conversation

@perNyfelt

Copy link
Copy Markdown
Member

Summary

  • gui (MarkdownToPdf) now declares its own literal <version> instead of inheriting lib's ${revision}lib and gui release independently, on independent version numbers, with gui never touching Maven Central.
  • release.sh splits into ./release.sh lib [--skip-deploy] (tags md2pdf-v<version>, deploys to Central) and ./release.sh gui (tags MarkdownToPdf-v<version>, no deploy), each with its own asset set, changelog source, and validation. A transitional guard rejects re-releasing a version already published under the old bare v<version> tag scheme.
  • gui's in-app UpdateChecker rewritten (TDD) to filter GitHub's release array by the MarkdownToPdf-v tag prefix and pick the highest matching version, since a shared releases/latest lookup could now return a lib release to a gui user.
  • ci.yml, install.sh, gui/buildAndRun.sh, CLAUDE.md, docs/release-process.md, README.md/gui/readme.md all updated to match the new mechanism and both release flows.
  • Design spec (6 external review rounds) and full implementation plan are included under docs/superpowers/.

Process

Implemented via subagent-driven development: 11 tasks, each with a fresh implementer + independent task review (one fix round on the docs rewrite), followed by a final whole-branch review that verified the version-divergence mechanism end-to-end in a scratch build and caught one real gap — the tag-scheme rename briefly disarmed the "already released" guard for the currently-released 0.2.0 — which is fixed in the final commit along with three minor polish items.

A related one-line fix in the sibling MarkdownToPdf-dist repo (a stale --tag usage-comment example) was implemented and committed locally there on branch fix-build-mas-tag-comment, but not pushed/PR'd — that's a separate repo and a separate decision.

Test plan

  • mvn verify — 112/112 tests pass, Spotless clean, SpotBugs clean, BUILD SUCCESS
  • Version-divergence mechanism verified in a scratch copy (gui bumped to 0.2.1 independent of lib's 0.2.0 revision)
  • release.sh die-paths smoke-tested (no network/tag/deploy side effects)
  • UpdateChecker's new array/prefix-filtering logic covered by new tests (mixed lib/gui tags, out-of-order highest-version selection, no-match case)

🤖 Generated with Claude Code

perNyfelt and others added 25 commits August 16, 2026 11:43
release.sh (rewritten in 375a1b9) expects a md2pdf-$VERSION-sources
artifact from lib's release CI run, but ci.yml never built or
uploaded one. It also only read a single shared "project version"
via revision, which no longer reflects gui's now-independent version.

Split the version-read step into APP_VERSION (gui's project.version)
and LIB_VERSION (lib's revision), point the javadoc jar upload at
LIB_VERSION, and add a sources-jar build/upload step modeled on the
javadoc step so release.sh's lib release flow has an artifact to
download.
- Replace single unified process with independent lib/gui flows
- Add explicit version-bump instructions for each module
- Document two-file gui lockstep requirement
- Include stranded-install documentation requirement
- Fix bare ./release.sh to specify both invocation forms (lib/gui)
…lementation plan

The design spec went through six rounds of external review after the initial
commit, fixing mechanism bugs, doc gaps, test gaps, CLI grammar, and recovery
docs. This commits the final spec text alongside the implementation plan that
the ten preceding commits on this branch execute task-by-task.
- release.sh: add a self-retiring transitional guard so releasing a version
  that was already published under the old bare "v<version>" tag scheme
  (0.1.0, 0.1.1, 0.2.0) is caught before the new md2pdf-v/MarkdownToPdf-v
  tag is created, instead of silently producing a duplicate release.
- release.sh: give the sources jar its own 5 KB floor, separate from
  javadoc's 10 KB floor, since the real sources jar (~13.5 KB) had almost
  no headroom under the shared floor.
- release.sh: mirror the lib arm's argument handling for gui so a bogus
  second argument gets an "unrecognized argument" message instead of being
  folded into the --skip-deploy message.
- gui/pom.xml: reword the version comment so it no longer embeds the
  literal token "${revision}", which flatten-maven-plugin interpolates in
  the installed POM and flips the comment's meaning.
- docs/release-process.md: note that 0.2.0 was already released under the
  legacy v0.2.0 tag, so the first release under each new tag scheme must be
  bumped past 0.2.0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sh/PR

release.sh's gui release flow already refuses to release when gui/pom.xml's
version and gui/MarkdownToPdf.xml's launcher dependency version disagree, but
nothing else checks this — the drift could sit unnoticed in the repo for a
long time before someone tries to release. Add the same check as a
lint-scripts CI step, mirroring the build job's Java setup, so it fails fast
on every push/PR instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two small fixes from code review:

1. release.sh: Initialize SKIP_DEPLOY=0 in the gui branch as well.
   Previously, SKIP_DEPLOY was only set in lib's branch. While the gui
   branch still runs under 'set -u pipefail', making an unbound variable
   safe to reference only by branch order rather than explicit init is
   fragile and would break if the deployment check order ever changed.
   Initialize it defensively in both branches for safety.

2. gui/createApp.sh: Update stale comment above app_jar(). The comment
   incorrectly framed the ambiguity check as catching 'bump ${revision}
   without a clean'; since gui now has its own independent <version>,
   that scenario no longer changes gui's jar filename. Reword to describe
   what app_jar()'s check actually catches today (stale gui jar) and note
   what it doesn't catch (lib-only revision bump, caught downstream by
   check-lib-classpath.sh).

No functional changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ray response, indeterminate outcome

Four verified post-merge review findings on the update-checker feature:

1. selectLatestGuiRelease now skips candidates flagged draft or prerelease
   (GitHubReleaseJson.extractBooleanBeforeAssets), so an unpublished release
   is never advertised as an update.

2. selectLatestGuiRelease now skips candidates whose version can't be parsed
   (VersionComparator.isParseable) before they can seed or replace bestVersion.
   Previously a single malformed tag (e.g. MarkdownToPdf-v0.4.0.RC1) would
   permanently win over every later, well-formed, genuinely newer release,
   because isNewer fails safe to false whenever either side fails to parse.

3. selectLatestGuiRelease now checks the top-level JSON shape is an array
   before scanning, logging a distinct, actionable warning instead of
   silently mis-scanning a nested array (e.g. assets[]) when fed the wrong
   response shape (relevant to the md2pdf.update.apiUrl QA override).

4. Introduced a tri-state UpdateCheckResult/UpdateCheckOutcome
   (UPDATE_AVAILABLE / UP_TO_DATE / INDETERMINATE) so "no update found"
   and "couldn't conclusively check" are no longer collapsed into the same
   Optional.empty() and the same "you're up to date" message.
   MarkdownToPdf.checkForUpdates now shows a distinct, non-misleading
   message for the INDETERMINATE case in interactive checks; background
   checks stay silent for both UP_TO_DATE and INDETERMINATE as before.

Added test coverage for all four findings following strict TDD (red then
green): GitHubReleaseJsonTest, VersionComparatorTest, UpdateCheckerTest, and
UpdateCheckerHttpTest. gui module: 124 tests passing (up from 112), spotless
and spotbugs clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The About dialog now displays which version of the md2pdf library is bundled,
helping users diagnose PDF-rendering bugs. Added Md2pdf-Version to the
MarkdownToPdf.properties file and updated the About dialog to read and display it.

Fixes review finding on decouple-lib-gui-versioning-spec branch.
The record's canonical constructor was public with no validation, so
nothing but convention stopped a future caller from constructing an
inconsistent result (e.g. UP_TO_DATE carrying an UpdateInfo). Add a
compact constructor that rejects that shape, and a couple of tests
enforcing it directly, per the final-review finding on this fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@perNyfelt
perNyfelt merged commit 688f019 into main Aug 16, 2026
6 checks passed
@perNyfelt
perNyfelt deleted the decouple-lib-gui-versioning-spec branch August 16, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant