Repository navigation
Give each published module its own changelog - #125
Merged
Merged
Conversation
why: libtmux-java publishes ten Maven modules that shared one CHANGELOG.md, so a reader of libtmux-mcp or libtmux-workspace-cli had to read the other modules' history to find their own. The maintainer agreed a main changelog beside one per module is fine. what: - Move every entry verbatim into exactly one file, under its original release and section heading, with its PR and issue links; a relative link gains the ../ its new directory needs, nothing else - Add <module>/CHANGELOG.md for the ten published modules, from the release that first shipped each - Keep entries that span modules, and documentation, CI, tests, build tooling, the BOM and the release summaries, in the root file - Keep the Unreleased heading and every release heading and date in each file; a release with nothing for a module says so
why: A module that has its own changelog should carry it to the people who fetch the jar. The publication convention already puts each module's artwork in the jar under META-INF/libtmux/<module>; the changelog belongs beside it. what: - Copy the CHANGELOG.md beside each published module's build file into META-INF/libtmux/<module>/ of its jar - Link each module README to its changelog
why: Once every module has a changelog, nothing noticed a module losing it, or a jar going out without it: Gradle's from() skips a missing file without a word. The staged-release check has to refuse before anything reaches Central. what: - Make verify-staged-release.sh require each staged jar to hold its module's changelog, opening with the module's name - Add a guard to tools.ci.check that every published module keeps a CHANGELOG.md with an Unreleased section, that its README links it, and that the publication convention ships it - Test the guard on broken copies of the tree, and the script on a signed staging with a jar that lacks the file; run both in the tmux-matrix plan job
tony
force-pushed
the
docs/per-package-changelogs
branch
from
November 1, 2026 13:36
558a5a2 to
d9d98ed
Compare
why: A contributor should be told which file an entry goes in, and the guides still pointed at one changelog for everything. Neither the guides nor the root README said so once the file was split. what: - Say in WRITING.md which file an entry goes in, in CONTRIBUTING.md what is enforced, in RELEASING.md that the tag commit dates every changelog, and name the files in AGENTS.md - Say in the root README that each module keeps a changelog, and in MIGRATION.md where the full history is
tony
force-pushed
the
docs/per-package-changelogs
branch
from
November 1, 2026 13:41
d9d98ed to
e0bff1c
Compare
tony
added a commit
that referenced
this pull request
Nov 1, 2026
why: Cut 0.1.2 from master so the test-run sandbox guard (#123) and its cli await fix (#130), the per-module changelogs (#125) and the Kotlin and Scala Server capability directory (#127) ship. The install snippets and the examples' snapshot coordinates need to name the release that ships them. what: - Date the 0.1.2 section (2026-11-01) in the root changelog and in each module's, and keep an empty unreleased section above it; the modules with nothing new say so - Move the install snippets and the examples' snapshot coordinates to 0.1.2 - Set the development version to 0.1.2-SNAPSHOT; libtmuxApiBaseline stays until 0.1.2 is published
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
libtmux-java publishes ten Maven modules,
libtmux,libtmux-mcp,libtmux-workspace,libtmux-workspace-cli,libtmux-kotlin,libtmux-scala,libtmux-scala-cats,libtmux-scala-ox,libtmux-jacksonandlibtmux-junit5, but kept oneCHANGELOG.mdfor all of them, so a reader of one module had to read the others' history to find their own, and no jar carried a changelog. The maintainer asked for one per published package and said a main changelog beside a changelog for each package is fine. Once each module has a file, nothing noticed a module losing it or a jar going out without it, so the change also extends the release check.Modelled on libtmux-ts #146.
What
libtmux,libtmux-mcp,libtmux-workspace,libtmux-workspace-cli,libtmux-kotlin,libtmux-scala,libtmux-scala-cats,libtmux-scala-ox,libtmux-jackson,libtmux-junit5. The rootCHANGELOG.mdkeeps what spans modules. Each file keeps the release headings, dates and theUnreleasedheading, with an introduction naming its module.libtmux.publication.gradle.ktscopies theCHANGELOG.mdbeside a module's build file intoMETA-INF/libtmux/<module>/, next to the artwork the convention already puts there. A Maven POM has no field for release notes, so the jar is the carrier.libtmux-bomis a platform with no jar and no changelog; its entries are in the root file.tools/verify-staged-release.sh, to refuse a staged jar that does not hold its module's changelog, or holds one that does not open withNotable changes toand the module's name. A Scala artifact's id ends in_3; the check strips it to find the module.tools/ci/check.py, which the tmux-matrix plan job already runs on every pull request: every published module keeps aCHANGELOG.mdthat opens with its own name and holds a## Unreleasedheading outside a code fence, its README links it, and the publication convention still ships it with afrom(...)line that is not commented out. The published modules are read fromsettings.gradle.kts, so a module added later without a changelog is caught.WRITING.md,CONTRIBUTING.md,RELEASING.mdandAGENTS.mdwhich file an entry goes in and that the tag commit dates every changelog.Nothing lost
An entry is a top-level bullet with its nested content, or a blank-line separated paragraph. A script parsed the old file at
e227c943and the eleven new files separately and required every old entry to appear in exactly one new file, under its original release and section headings, with nothing added. The one difference it allows is the../that a relative link needs once its entry sits one directory down, which 28 entries gained.CHANGELOG.mdate227c943CHANGELOG.mdlibtmux/CHANGELOG.mdlibtmux-mcp/CHANGELOG.mdlibtmux-workspace/CHANGELOG.mdlibtmux-workspace-cli/CHANGELOG.mdlibtmux-kotlin/CHANGELOG.mdlibtmux-scala/CHANGELOG.mdlibtmux-scala-cats/CHANGELOG.mdlibtmux-scala-ox/CHANGELOG.mdlibtmux-jackson/CHANGELOG.mdlibtmux-junit5/CHANGELOG.mdDropping an entry, duplicating one into a second file, changing a single word, adding an entry, or swapping two release headings makes the script fail, so it is capable of failing. The script is not in this change: it compares against one old commit, so as a gate it would go stale at the next changelog edit.
Judgement calls
libtmuxentry. The early alphas'libtmux-mcpentries (tmux_run,tmux_whoami, the safety tiers, the toolsets) rarely name the module, and I read each one to place it; the fixturesTmuxExtension,NamedServerFixtureandFakeTmuxarelibtmux-junit5.ServerConfig.force256Colorstogether withtmux-workspace load -2, the sealed exception tree that also changeslibtmux-jackson, the Scala and OxLiveViewentry, andFilterModel.fieldNames, which is alibtmux-jacksonclass that the MCP server reads. So do documentation, CI, tests, build and release tooling,libtmux-bomand the release summaries, whichever module they concern.libtmux-jacksonandlibtmux-scala-oxhave no entry of their own in the old file. Their files keep every release heading from the module's first release and sayNo entries for `libtmux-jackson`.under each. The line says "no entries" rather than "no change" because the old file did not record every source change in the early releases.libtmux-workspace-cliat0.0.1-alpha.16, and the three Scala modules at0.0.1-alpha.13, the first release whose entries name them, although the first tag with their directories isalpha.15.WRITING.mdrequires, so the root README does not name the module changelogs in it; the paragraph below it and the Documentation section do.MIGRATION.md) would lead nowhere from the module directory, andDocumentationFactsTestfails on a link that does not resolve, so each gained../. That is the only change to entry text, and the script checks it.The check
The staged-release script is what the release rehearsal job in
ci.ymlruns on a signed staging, so the rule lives there.test_staged_release.pystages a small repository with a throwaway signing key, so every other rule of the script passes, and breaks one jar at a time: the unbroken staging passes, a Scala jar with no changelog is refused by its module name and not its artifact id, and a jar holding another module's changelog is refused. With the new block removed from the script, the two refusals fail and the unbroken staging still passes. The test skips wheregpgcannot make a key.The guard has eight tests in
test_check.py, each breaking a copy of the tree: a deleted changelog, a new published module without one, another module's changelog pasted over this one, a missing Unreleased heading and one inside a code fence, a README that does not link its changelog, and a publication convention that stops shipping it. With the guard switched off, seven of the eight fail; the eighth, that the guard finds the ten jars and not the BOM, tests discovery.test_staged_releaseis added to the plan job's unittest line intmux-matrix.yml, besidetest_check.Verification
Run on the final tree, through the host's heavy-job wrapper:
python3 -m unittest tools.ci.test_check tools.ci.test_staged_release tools.ci.test_plan tools.ci.test_tmux_ref(83 tests, andtest_staged_releasefails rather than skips whenCIis set andgpgcannot make a key) andpython3 -m tools.ci.check;./gradlew :docs:test --tests io.github.libtmux.docs.DocumentationFactsTest, which resolves every Markdown link in the repository, with the new changelogs in place; andprocessResourcesforlibtmux,libtmux-mcpandlibtmux-scala, whose built jars listMETA-INF/libtmux/<module>/CHANGELOG.md.Not run locally: a full staging with a signing key (
publishAllPublicationsToStagingRepository), which CI does in its release rehearsal, and the real-tmux suites.Not for merging yet: master stays held until the docs pin wave finishes.
Closes #122.