@bestikk/changelog
v1.0.2
Published
Manage a Keep a Changelog changelog (AsciiDoc or Markdown): roll the Unreleased section into a dated release, and extract a release as Markdown release notes.
Maintainers
Readme
bestikk-changelog
Manage a Keep a Changelog style changelog, in AsciiDoc or Markdown: roll the "Unreleased" section into a dated release, and extract a release section as Markdown release notes suitable for a GitHub release.
Changelog formats
Two formats are supported, selected with the format option (adoc or markdown, default adoc) — the CLI infers it from the --file extension (.md/.markdown -> markdown, otherwise adoc).
adoc (AsciiDoc, e.g. CHANGELOG.adoc)
Converted to Markdown via downdoc, an optional dependency (see Optional downdoc dependency).
Headings use the same style presets as the markdown format below (default title-paren), just with the AsciiDoc == marker instead of Markdown’s level 2 marker — both are a "level 2" heading in their respective syntax.
= Project Changelog
== Unreleased
== v1.0.0 (2024-01-15)
Optional summary paragraph, used as the release notes summary.
=== Added
* A new feature
=== Fixed
* A bug fix
== v0.9.0 (2023-12-01)
...markdown (native Markdown, e.g. CHANGELOG.md)
Used as-is, no conversion needed. The exact heading syntax is configurable via the style option (a preset name or a custom style object — see lib/heading-styles.js), since projects tend to spell the "Unreleased"/release headings slightly differently. Category sections (e.g. "Added", "Fixed", shown as a plain level 3 heading below) always use the same syntax, whatever the style.
keepachangelog(default)
Canonical Keep a Changelog syntax.## [Unreleased] ## [<version>] - <date>title-paren
e.g. asciidoctor-emoji.## Unreleased ## v<version> (<date>)title-paren-suffix
e.g. asciidoctor-vscode, whose release heading also allows an optional "(qualifier)" and a free-form "- suffix" (only the latter is written back, via the "suffix" option).## Unreleased ## <version> [(qualifier)] (<date>) [- suffix]
# Project Changelog
## [Unreleased]
## [1.0.0] - 2024-01-15
Optional summary paragraph, used as the release notes summary.
### Added
- A new feature
### Fixed
- A bug fix
## [0.9.0] - 2023-12-01
...A convention that doesn’t fit any preset can be passed directly as a custom style object instead of a preset name:
const style = {
unreleasedHeading: '## TBD',
releaseHeadingTemplate: (version, date) => `## Release ${version} — ${date}`,
releaseHeadingRegex: (escapedVersion) =>
new RegExp(`(?:^|\\n)## Release ${escapedVersion} — ([^\\n]+)\\n([\\s\\S]*?)(?=\\n## |$)`),
}
rollUnreleased(content, '1.0.0', '2024-01-15', { format: 'markdown', style })Install
npm install @bestikk/changelogOptional downdoc dependency
downdoc is listed as an optionalDependencies and only loaded when processing the adoc format, so a project that only uses a Markdown changelog doesn’t need it. It is installed by default by npm/npx/pnpm/yarn; if it’s missing (e.g. installed with --omit=optional) and the adoc format is used, an explicit error tells you to install it.
CLI usage
# Roll the "Unreleased" section into a dated "v1.0.0" section
npx bestikk-changelog release 1.0.0
# Print the "v1.0.0" section as Markdown release notes (for a GitHub release)
npx bestikk-changelog notes 1.0.0
# Same, for a Markdown changelog (format inferred from the .md extension)
npx bestikk-changelog release 1.0.0 --file CHANGELOG.md
npx bestikk-changelog notes 1.0.0 --file CHANGELOG.mdBoth commands accept --file <path> (default: CHANGELOG.adoc), --format <adoc|markdown> (default: inferred from --file), and --style <name> (default keepachangelog for markdown, title-paren for adoc; see the styles above).
release accepts --date <YYYY-MM-DD> (default: today) and --suffix <text> (appended to the release heading, used by the title-paren-suffix style, e.g. --suffix "- @octocat").
notes accepts --author <name> (default: $GITHUB_ACTOR or the tag’s commit author), --previous-tag <tag> (default: the tag before v<version>), and --repo-url <url> (default: inferred from the origin git remote) — used to link the full diff between releases.
Library usage
import { rollUnreleased, extractReleaseNotes } from '@bestikk/changelog'
import { readFileSync, writeFileSync } from 'node:fs'
const content = readFileSync('CHANGELOG.adoc', 'utf8')
// Roll "Unreleased" into "v1.0.0 (2024-01-15)" (format defaults to "adoc")
writeFileSync('CHANGELOG.adoc', rollUnreleased(content, '1.0.0', '2024-01-15'))
// Extract "v1.0.0" as Markdown release notes
const notes = await extractReleaseNotes(content, '1.0.0', {
author: 'octocat',
previousTag: 'v0.9.0',
repoUrl: 'https://github.com/example/example',
})Pass { format: 'markdown' } as the last argument to work with a native Markdown file instead, and { format: 'markdown', style: 'title-paren' } (or another preset, or a custom style object) to match its heading syntax.
License
MIT
