Skip to content

Parse existing release notes

The parsing half turns a changelog document back into a typed model, so a tool can read what was released, not just render it. Useful for showing "what changed" from a downloaded release, or inspecting a CHANGELOG.md in CI.

Parse a markdown string

func Parse(rawNotes string) *Changelog

Parse reads a markdown changelog into a Changelog:

cl := changelog.Parse(rawNotes)

fmt.Println(cl.FromVersion, "→", cl.ToVersion)
for _, rel := range cl.Releases {
    fmt.Println("##", rel.Version, "-", len(rel.Entries), "entries")
}

Parse never returns an error — malformed or empty input yields a Changelog with no releases.

Parse from a release archive

Releases often ship the changelog inside a gzip/tar bundle. ParseFromArchive extracts and parses it in one step:

func ParseFromArchive(r io.Reader) (*Changelog, error)

cl, err := changelog.ParseFromArchive(resp.Body)

It returns an error only if the archive itself cannot be read.

Query the model

Once parsed, three helpers answer the common questions:

if cl.HasBreakingChanges() {
    for _, e := range cl.BreakingChanges() {
        fmt.Printf("BREAKING %s: %s\n", e.Scope, e.Description)
    }
}

features := cl.EntriesByCategory(changelog.CategoryFeature)
fixes    := cl.EntriesByCategory(changelog.CategoryFix)

BreakingChanges and EntriesByCategory gather matching entries across every release in the changelog.

Render a summary

FormatSummary produces a concise, terminal-friendly summary — breaking changes first under a warning banner, then Features / Bug Fixes / Performance / Other:

fmt.Print(changelog.FormatSummary(cl))
WARNING: Breaking changes detected!

  BREAKING: config: renamed the timeout key

Features:
  - cli: add a --json flag
Bug Fixes:
  - http: retry on 503

A nil or empty changelog formats to the empty string.