Skip to content

Generated output format

GenerateFromRepo returns a markdown string. This is exactly what it contains. There is no template, no configuration, no way to change any of it short of post-processing the string yourself.

The shape of one release

# v1.2.0

### Features

* **cli:** add a --json flag
* add the greeting command

### Bug Fixes

* **http:** retry on 503
  • Release heading: # (level 1), holding the tag name exactly as it appears in the repository. A tag named 1.0.0 produces # 1.0.0; the v is not added.
  • Category heading: ### (level 3). There is no level-2 heading anywhere in the output.
  • Entries: * bullets. With a scope, * **scope:** description. Without one, * description.
  • Blank lines: one after the release heading, one after each category heading, and one between releases. The string ends with a newline after the last bullet.

Order of everything

  1. Unreleased first, if any commit is not reachable from a tag. The literal string Unreleased is used as the version.
  2. Tagged releases, newest first, ordered by semver, so v1.10.0 precedes v1.9.0, whatever order the tags were created in.
  3. Categories within a release, always in this order, with empty ones omitted: Breaking Changes → Features → Bug Fixes → Performance Improvements → Other.
  4. Entries within a category, newest commit first by committer time.

What is not in the output

No commit hashes, dates, authors, links, compare URLs, issue references or contributor lists. No document title: there is no leading # Changelog heading, so the first line of the string is the first release heading. No footnotes and no front matter.

The output is deliberately the same information a Changelog value holds, which is why it round-trips through Parse. Anything richer would be information the parser cannot read back.

The empty and near-empty cases

Situation Output
Repository with no commits "" (empty string), nil error
Repository whose every commit was dropped (all test/ci, or all unrecognised) "", nil error
Commits but no tags A single # Unreleased section
A release whose commits were all dropped The release is omitted entirely, heading and all
Two tags on the same commit The lower semver keeps the entries; the higher is emitted as a heading with no body

That last pair is worth reading twice. A tag whose commits were all test/ci disappears from the changelog without trace, while a tag that collided with another on the same commit gets an empty section. Both are deliberate; neither is configurable.

Writing the output somewhere

GenerateFromRepo returns a string and nothing else. It does not write a file, does not know the name CHANGELOG.md, and does not merge with an existing changelog. If you regenerate, you are producing the whole document again from history, and it is your program's job to decide what to do with it.