Skip to content

release: generated changelog section is appended at the bottom of CHANGELOG.md (convert-[Unreleased] path places correctly) #114

Description

@levifig

Summary

When loaf release has to generate the new changelog section itself (no ## [Unreleased] section present in CHANGELOG.md), the new ## [X.Y.Z] section is appended at the bottom of the file instead of the newest-first position under the header. On levifig/mvault this was manually relocated after four separate releases.

Narrowing evidence — the bug is only in the generate path

On mvault v0.11.1 (loaf 2.0.0-alpha.6) I pre-staged a curated section before running loaf release --bump patch --yes:

## [Unreleased]

### Fixed
- ...curated prose...

The release converted it correctly: ## [0.11.1] - 2026-07-17 landed in the right place (directly under the header block, above ## [0.11.0]), and a fresh ## [Unreleased] / "No unreleased changes yet." stub was reinserted above it. No manual relocation needed.

Every earlier occurrence of the bottom-append (v0.11.0 and at least three before it) ran without a pre-existing [Unreleased] section, i.e. through the generate-from-commits fallback.

So: the [Unreleased]→version conversion inserts at the correct position; the generate-from-commits fallback appends at EOF. The fix is presumably to make the fallback insert at the same anchor the conversion path uses (after the intro/header block, before the first existing ## [ heading), and ideally to also insert the fresh [Unreleased] stub in that path.

Workaround

Pre-stage a curated ## [Unreleased] section before running loaf release — which is arguably the better authoring flow anyway, but the fallback shouldn't corrupt file order when it's used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions