changelog

package
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package changelog parses, classifies, and rewrites Keep a Changelog files.

All functions in this package are pure: they accept the changelog text and configuration as input and return new text and a classification result. They never read from the process environment, the file system, or git.

Index

Constants

View Source
const (

	// SemverPattern is a regex pattern that matches a semantic version string
	// (per https://semver.org/spec/v2.0.0.html). Exposed for callers that need
	// to construct related expressions.
	SemverPattern = `(?P<major>0|[1-9]\d*)\.` +
		`(?P<minor>0|[1-9]\d*)\.` +
		`(?P<patch>0|[1-9]\d*)` +
		`(?:-` +
		`(?P<prerelease>` +
		`(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)` +
		`(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*` +
		`)` +
		`)?` +
		`(?:\+` +
		`(?P<buildmetadata>` +
		`[0-9a-zA-Z-]+` +
		`(?:\.[0-9a-zA-Z-]+)*` +
		`)` +
		`)?`
)

Variables

View Source
var ErrIncompleteBreaking = errors.New(
	"### Changed or ### Removed section found with missing or incomplete description." +
		" Per Keep a Changelog, these sections are for BREAKING CHANGES only and must include 'BREAKING CHANGE' in" +
		" the description. If this is NOT a breaking change, please use a different section type: ### Added (new features)" +
		", ### Fixed (bug fixes), ### Deprecated, or ### Security",
)

ErrIncompleteBreaking is returned when a `### Changed` or `### Removed` heading is present but no entry under it contains the literal phrase "BREAKING CHANGE".

View Source
var ErrNoChangesDetected = errors.New("no changes detected")

ErrNoChangesDetected is returned when an unreleased section is empty or absent and the module should be silently skipped.

View Source
var ErrUnrecognizedChangeType = errors.New("missing or unrecognized change type in unreleased section")

ErrUnrecognizedChangeType is returned when an unreleased section contains content that does not match any built-in or configured custom heading.

Functions

func Classify

func Classify(unreleased string, custom map[string]config.BumpType) (config.BumpType, error)

Classify inspects an unreleased section and returns the appropriate bump type, taking custom change types into account.

The decision rules are:

  • A `### Changed` or `### Removed` heading without the literal phrase "BREAKING CHANGE" anywhere in the section returns ErrIncompleteBreaking.
  • With "BREAKING CHANGE" present, those sections drive a major bump.
  • `### Added`, `### Deprecated`, `### Security` drive a minor bump.
  • `### Fixed` drives a patch bump.
  • Custom types are evaluated under the same priority order; a custom "major" mapping still requires the BREAKING CHANGE marker.
  • The highest-priority match wins.
  • An empty section returns ErrNoChangesDetected.
  • Anything else returns ErrUnrecognizedChangeType.

func ExtractCurrentVersion

func ExtractCurrentVersion(content string) string

ExtractCurrentVersion returns the most recent versioned heading in the changelog, or "0.0.0" when none is present (i.e. a first release).

func ExtractUnreleased

func ExtractUnreleased(content string) string

ExtractUnreleased returns the body of the `## [Unreleased]` section, trimmed of surrounding whitespace. It returns an empty string when no unreleased section exists or the section is empty.

func NextVersion

func NextVersion(currentVersion string, bump config.BumpType) (string, error)

NextVersion increments currentVersion by bump, returning the resulting SemVer string (without a "v" prefix).

func ReleaseName

func ReleaseName(moduleName, version string) string

ReleaseName returns the module-scoped release identifier ("vX.Y.Z" or "<module>/vX.Y.Z").

func ReleaseURL

func ReleaseURL(ownerRepo, moduleName, version string) string

ReleaseURL returns the GitHub Release URL for a given module/version.

func Rewrite

func Rewrite(content string, opts RewriteOptions) string

Rewrite returns a new changelog body that promotes the unreleased section to a versioned section. The original `## [Unreleased]` heading is preserved at the top with an empty body, and a new versioned heading is inserted directly below it.

func ValidateSection added in v1.2.0

func ValidateSection(unreleased string, custom map[string]config.BumpType) []error

ValidateSection inspects the body of a `## [Unreleased]` section and returns every problem it finds, rather than stopping at the first like Classify does. The returned errors are wrappers around the package's existing sentinels (ErrUnrecognizedChangeType, ErrIncompleteBreaking) so callers can still match with errors.Is for exit-code mapping.

An empty / whitespace-only section returns a single ErrNoChangesDetected so callers can distinguish "skip this module" from real problems. Callers that already treat empty sections as a non-error (e.g. the validate subcommand) should check for emptiness before calling.

Unlike Classify, this function never returns the computed bump because validation is not the place to make release decisions.

Types

type RewriteOptions

type RewriteOptions struct {
	ModuleName  string
	NextVersion string // bare semver, e.g. "1.2.3"
	OwnerRepo   string // "<owner>/<repo>"
	// MatchSection is the unreleased body to match in the source content
	// (i.e. the text that was originally extracted by ExtractUnreleased).
	MatchSection string
	// PromoteAs is the text to emit under the new versioned heading. It may
	// differ from MatchSection when, e.g., a manual-release footer is added.
	// When empty, MatchSection is used.
	PromoteAs string
	Now       time.Time
}

RewriteOptions controls Rewrite. The new versioned heading links back to the GitHub Release URL derived from OwnerRepo, ModuleName, and NextVersion via ReleaseURL.

type UpdateRequest

type UpdateRequest struct {
	Content       string
	ModuleName    string
	OwnerRepo     string
	CustomTypes   map[string]config.BumpType
	ManualVersion string // empty means "calculate from content"
	ManualReason  string
	Actor         string
	Now           time.Time
}

UpdateRequest describes a single changelog update.

type UpdateResult

type UpdateResult struct {
	NextVersion       string // bare semver, e.g. "1.2.3"
	UnreleasedSection string // body promoted into the new versioned section (incl. manual footer)
	NewContent        string // full rewritten changelog body
	Bump              config.BumpType
	Manual            bool
}

UpdateResult is the outcome of a successful Update.

func Update

func Update(req UpdateRequest) (UpdateResult, error)

Update performs the full pure transformation: extract -> classify -> bump -> (optional override) -> rewrite. It returns ErrNoChangesDetected when the unreleased section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL