Release notes from a curated release_notes.md (with CHANGELOG fallback + cycle reset) #749

Closed
opened 2026-07-05 22:04:36 +00:00 by jmiller · 3 comments
Owner

Let releases pull their notes from a curated release_notes.md in the repo root, instead of always auto-extracting from CHANGELOG.md.

Current behavior

Release notes are extracted from the CHANGELOG [Unreleased] section at release time:

NOTES=$(awk '/^## \[Unreleased\]/{found=1;next} /^## \[/{if(found)exit} found{print}' CHANGELOG.md)
  • .mokogitea/workflows/pre-release.yml:209
  • .mokogitea/workflows/auto-release.yml:163 and :354
    version-set.yml promotes [Unreleased][version] --- date on release; pr-check.yml:472 enforces [Unreleased] has entries.

Proposal

  1. Source with fallback (don't lose current behavior): at release time, if a root release_notes.md exists and is non-empty, use its contents as the release body; otherwise fall back to the existing CHANGELOG [Unreleased] extract. This separates curated, user-facing release notes from the exhaustive technical changelog while keeping automatic notes when nobody curates.
  2. Cycle reset (the "reset when we send to dev" part): empty release_notes.md at the start of a new cycle — when dev is recreated from main after a stable release — mirroring how [Unreleased] is promoted and re-emptied. So notes accumulate during a cycle and reset for the next.
  3. repo-health / pr-check (optional): treat release_notes.md like the changelog for readiness checks (warn if it still has stale content post-release, etc.).

Touchpoints

  • The three NOTES=$(awk … CHANGELOG.md) lines → wrap with if [ -s release_notes.md ]; then NOTES=$(cat release_notes.md); else NOTES=$(awk …); fi.
  • Dev-recreate / post-stable-release step → : > release_notes.md (reset).
  • Optionally seed a release_notes.md template in the repo + templates.

Notes

  • Not release-blocking. Implement after #733 to avoid changing the release pipeline mid-release.
  • Workflow-only change (no Go code); should sync to the Template-Generic source so all repos get it.

Related: #727 release flow, version-set/auto-release/pre-release workflows.

https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT

Let releases pull their notes from a curated **`release_notes.md`** in the repo root, instead of always auto-extracting from `CHANGELOG.md`. ## Current behavior Release notes are extracted from the CHANGELOG `[Unreleased]` section at release time: ``` NOTES=$(awk '/^## \[Unreleased\]/{found=1;next} /^## \[/{if(found)exit} found{print}' CHANGELOG.md) ``` - `.mokogitea/workflows/pre-release.yml:209` - `.mokogitea/workflows/auto-release.yml:163` and `:354` `version-set.yml` promotes `[Unreleased]` → `[version] --- date` on release; `pr-check.yml:472` enforces `[Unreleased]` has entries. ## Proposal 1. **Source with fallback (don't lose current behavior):** at release time, if a root `release_notes.md` exists and is non-empty, use its contents as the release body; **otherwise fall back** to the existing CHANGELOG `[Unreleased]` extract. This separates *curated, user-facing* release notes from the exhaustive technical changelog while keeping automatic notes when nobody curates. 2. **Cycle reset (the "reset when we send to dev" part):** empty `release_notes.md` at the **start of a new cycle** — when `dev` is recreated from `main` after a stable release — mirroring how `[Unreleased]` is promoted and re-emptied. So notes accumulate during a cycle and reset for the next. 3. **repo-health / pr-check (optional):** treat `release_notes.md` like the changelog for readiness checks (warn if it still has stale content post-release, etc.). ## Touchpoints - The three `NOTES=$(awk … CHANGELOG.md)` lines → wrap with `if [ -s release_notes.md ]; then NOTES=$(cat release_notes.md); else NOTES=$(awk …); fi`. - Dev-recreate / post-stable-release step → `: > release_notes.md` (reset). - Optionally seed a `release_notes.md` template in the repo + templates. ## Notes - Not release-blocking. **Implement after #733** to avoid changing the release pipeline mid-release. - Workflow-only change (no Go code); should sync to the Template-Generic source so all repos get it. Related: #727 release flow, version-set/auto-release/pre-release workflows. https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Author
Owner

CI integration — required (promoting §3 from "optional")

The CI must treat release_notes.md as a first-class artifact, mirroring how it already handles the CHANGELOG:

  • pr-check.yml (~line 472, where it counts [Unreleased] entries): accept either a curated release_notes.md entry or a CHANGELOG [Unreleased] entry so a PR isn't blocked when the notes live in release_notes.md; warn/fail only if both are empty. (Keeps the "notes required per release" guarantee without forcing double entry.)
  • repo-health.yml: add release_notes.md to REPO_REQUIRED_ARTIFACTS (~line 48) and add content checks (~line 360) — e.g. warn on stale content lingering after a stable release, or a missing file — parallel to the existing CHANGELOG.md checks.
  • Reset step in CI (~line 3 of the parent issue): the : > release_notes.md reset belongs in the dev-recreate / post-stable-release job (auto-release.yml or the dev-recreate workflow), so a fresh cycle starts empty.
  • Template sync: all of the above must land in Template-Generic and sync out, so every repo's CI gains it (not just this fork).

Net: pr-check validates it, repo-health requires/tracks it, auto-release extracts + resets it. Still post-#733 — but the CI changes are part of the same unit of work.

https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT

### CI integration — required (promoting §3 from "optional") The CI must treat `release_notes.md` as a first-class artifact, mirroring how it already handles the CHANGELOG: - **`pr-check.yml`** (~line 472, where it counts `[Unreleased]` entries): accept **either** a curated `release_notes.md` entry **or** a CHANGELOG `[Unreleased]` entry so a PR isn't blocked when the notes live in `release_notes.md`; warn/fail only if **both** are empty. (Keeps the "notes required per release" guarantee without forcing double entry.) - **`repo-health.yml`**: add `release_notes.md` to `REPO_REQUIRED_ARTIFACTS` (~line 48) and add content checks (~line 360) — e.g. warn on stale content lingering after a stable release, or a missing file — parallel to the existing `CHANGELOG.md` checks. - **Reset step in CI** (~line 3 of the parent issue): the `: > release_notes.md` reset belongs in the **dev-recreate / post-stable-release** job (`auto-release.yml` or the dev-recreate workflow), so a fresh cycle starts empty. - **Template sync:** all of the above must land in **Template-Generic** and sync out, so every repo's CI gains it (not just this fork). Net: pr-check validates it, repo-health requires/tracks it, auto-release extracts + resets it. Still post-#733 — but the CI changes are part of the same unit of work. https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Author
Owner

Branch created: feature/749-release-notes-from-a-curated-release-not

git fetch origin
git checkout feature/749-release-notes-from-a-curated-release-not
Branch created: [`feature/749-release-notes-from-a-curated-release-not`](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea-Fork/src/branch/feature/749-release-notes-from-a-curated-release-not) ```bash git fetch origin git checkout feature/749-release-notes-from-a-curated-release-not ```
Author
Owner

Closing as misfiled / redundant. This is a release-workflow change that belongs in the workflow source repo, not here — the release workflows are synced from Template-Generic, so editing them in this fork would be overwritten.

Tracked for implementation in MokoConsulting/Template-Generic#71 (self-contained, with exact touchpoints). It'll sync down to all repos including this one.

https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT

Closing as **misfiled / redundant**. This is a release-workflow change that belongs in the workflow *source* repo, not here — the release workflows are synced from Template-Generic, so editing them in this fork would be overwritten. Tracked for implementation in **MokoConsulting/Template-Generic#71** (self-contained, with exact touchpoints). It'll sync down to all repos including this one. https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Sign in to join this conversation.