docs(book): teach the derived release version, and move the template onto it #8

Merged
whitlocktech merged 1 commits from docs/release-cadence into main 2026-08-19 18:06:40 +00:00
Member

What & why

The template shipped the declared-version release engine that the reference module has just abandoned: publish when a push to main leaves module.json at a version with no release yet. A kit that teaches a shape the reference module no longer runs is exactly the rot §2.11 is written against, so both flavours move together.

Both workflowstemplate/.gitea/workflows/release.yml and its GitHub twin — now run the engine link, installer and Module-uo share: feat!:/BREAKING CHANGE → major, feat: → minor, fix:/perf: → patch, nothing releasable → no release, no tag at all → what module.json declares. The tag is the number that ships, and the job writes it into the module.json inside the bundle, with an assertion that the rewrite happened.

module.json's version is kept as a floor — a version above the newest tag releases at that version — and workflow_dispatch is the backdoor for a manifest change with no releasable code behind it.

The chapter keeps the declared model in view rather than deleting it, because the reason it was abandoned is the part a reader needs: its cost is paid on every release, the drift it prevents is something review catches anyway, and a week of merged work in the reference module produced no bundle at all. A reader choosing between the two shapes should get the evidence, not just the verdict.

Two fixes carried over from the same pass:

  • a tag pushed without a release behind it is recovered instead of standing down forever (every later run would see the tag and do nothing);
  • the changelog moved into the plan step, so assemble clears $OUT rather than dist/ — which now holds it.

Deliberately kept: the # CHANGE THESE banner and its two variables, the exclusion list the acceptance run's F4 argued for (the reference module still has the include list; that is its problem, not the template's), and the GitHub twin's MODULE_SOURCE_HOSTS note in the changelog.

How it was tested

Both plan steps were extracted from the YAML and run against purpose-built git fixtures, with curl stubbed per scenario:

Case .gitea .github
feat: since tag 0.2.0 0.2.0
fix: since tag 0.1.1
nothing releasable, release exists stands down stands down
tag exists, no release behind it recovers, reuse_tag=true recovers, reuse_tag=true
first ever release (no tag) 0.1.0 from module.json
declared above the tag (the floor) 0.3.0 0.9.0
dispatch, blank version 0.1.1
dispatch, exact version 2.0.0 2.0.0

Both YAML files parse and their steps are in the expected order. The generated changelog was inspected in both, including the GitHub twin's MODULE_SOURCE_HOSTS line.

Repo checks all pass:

checkLinks: 59 link(s) across 15 markdown file(s) — OK
OK — the rename checklist matches the template (28 files).
checkChapterPaths: 35 path(s) claimed across 15 markdown file(s) — all present.
node --test scripts/checkRenameSites.test.js   → fail 0
node --test scripts/checkChapterPaths.test.js  → fail 0

No template source, dependency or pinned-core change, so coreApi and the template build are untouched by this diff.

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Opus 5). I have reviewed and understand
    every change, and take responsibility for it. AI-authored commits are
    marked with a Co-Authored-By / Assisted-By trailer.

License

  • I agree that my contribution is licensed under this project's license
    (GNU GPL v3.0 or later), and I have the right to contribute it.

Follows RunicGateway/Module-uo#17, recorded in RunicGateway/docs#171.

## What & why The template shipped the declared-version release engine that the reference module has just abandoned: publish when a push to `main` leaves `module.json` at a version with no release yet. A kit that teaches a shape the reference module no longer runs is exactly the rot §2.11 is written against, so both flavours move together. **Both workflows** — `template/.gitea/workflows/release.yml` and its GitHub twin — now run the engine `link`, `installer` and `Module-uo` share: `feat!:`/`BREAKING CHANGE` → major, `feat:` → minor, `fix:`/`perf:` → patch, nothing releasable → no release, no tag at all → what `module.json` declares. The tag is the number that ships, and the job writes it into the `module.json` inside the bundle, with an assertion that the rewrite happened. `module.json`'s version is **kept as a floor** — a version above the newest tag releases at that version — and `workflow_dispatch` is the backdoor for a manifest change with no releasable code behind it. **The chapter keeps the declared model in view rather than deleting it**, because the reason it was abandoned is the part a reader needs: its cost is paid on every release, the drift it prevents is something review catches anyway, and a week of merged work in the reference module produced no bundle at all. A reader choosing between the two shapes should get the evidence, not just the verdict. Two fixes carried over from the same pass: - a tag pushed without a release behind it is **recovered** instead of standing down forever (every later run would see the tag and do nothing); - the changelog moved into the plan step, so assemble clears `$OUT` rather than `dist/` — which now holds it. **Deliberately kept:** the `# CHANGE THESE` banner and its two variables, the **exclusion** list the acceptance run's F4 argued for (the reference module still has the include list; that is its problem, not the template's), and the GitHub twin's `MODULE_SOURCE_HOSTS` note in the changelog. ## How it was tested Both plan steps were extracted from the YAML and run against purpose-built git fixtures, with `curl` stubbed per scenario: | Case | `.gitea` | `.github` | | --- | --- | --- | | `feat:` since tag | `0.2.0` | `0.2.0` | | `fix:` since tag | `0.1.1` | — | | nothing releasable, release exists | stands down | stands down | | tag exists, no release behind it | recovers, `reuse_tag=true` | recovers, `reuse_tag=true` | | first ever release (no tag) | `0.1.0` from `module.json` | — | | declared above the tag (the floor) | `0.3.0` | `0.9.0` | | dispatch, blank version | `0.1.1` | — | | dispatch, exact version | `2.0.0` | `2.0.0` | Both YAML files parse and their steps are in the expected order. The generated changelog was inspected in both, including the GitHub twin's `MODULE_SOURCE_HOSTS` line. Repo checks all pass: ``` checkLinks: 59 link(s) across 15 markdown file(s) — OK OK — the rename checklist matches the template (28 files). checkChapterPaths: 35 path(s) claimed across 15 markdown file(s) — all present. node --test scripts/checkRenameSites.test.js → fail 0 node --test scripts/checkChapterPaths.test.js → fail 0 ``` No template source, dependency or pinned-core change, so `coreApi` and the template build are untouched by this diff. ## Checklist - [x] I have read CONTRIBUTING.md. - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Opus 5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` / `Assisted-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it. --- Follows **RunicGateway/Module-uo#17**, recorded in **RunicGateway/docs#171**.
wtclaude added 1 commit 2026-08-19 18:04:02 +00:00
docs(book): teach the derived release version, and move the template onto it
All checks were successful
PR Checks / prose (pull_request) Successful in 7s
PR Checks / template (pull_request) Successful in 33s
3979fa5abf
The template shipped the declared-version release engine the reference module
has just abandoned: publish when a push to `main` leaves `module.json` at a
version with no release yet. Both flavours of the workflow move to the engine
`link`, `installer` and now Module-uo run - feat!/BREAKING CHANGE -> major,
feat -> minor, fix|perf -> patch - with `module.json` kept as a floor and a
`workflow_dispatch` backdoor for a manifest change with no releasable code
behind it. The tag is the number that ships, and the job writes it into the
`module.json` inside the bundle.

The chapter keeps the declared model in view rather than deleting it, because
the reason it was abandoned is the part a reader needs: its cost is paid on
every release, and the drift it prevents is something review catches anyway. A
week of merged work in the reference module produced no bundle at all.

Also carried over from the same pass: a tag pushed without a release behind it
is recovered instead of standing down forever, and the changelog moved into the
plan step (so assemble clears `$OUT`, not `dist/`).

Kept: the `# CHANGE THESE` banner, the exclusion list from the acceptance run's
F4, and the GitHub twin's `MODULE_SOURCE_HOSTS` note.

checkLinks, checkRenameSites and checkChapterPaths pass.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 39736f8448 into main 2026-08-19 18:06:40 +00:00
whitlocktech deleted branch docs/release-cadence 2026-08-19 18:06:40 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Integration-kit#8
No description provided.