commits-to-changelog
v2.1.0
Published
Create an unopionated CHANGELOG.md from Git commit history
Maintainers
Readme
commits-to-changelog
Create an unopionated CHANGELOG.md from Git commit history (see Details)
- Rejects by default creating a Changelog if commits without associated Git tag exist, untagged commits can be allowed via setting requireTag
- Creates CHANGELOG.md on each run from scratch, i.e. an existing on will be overwritten
- Optionally writes defined number of lines from the start of CHANGELOG.md also to an existing section with heading "Changelog" (or "CHANGELOG" or any preferred case) in README.md (see linesToReadme under Settings)
- Commits that are rather not relevant for users, e.g. "bump version" / changelog" / addressing "tests" (full list see filterDefaults under settings), are filtered out by default, further commits / commit types to filter out can be defined as as setting
- I.e. no pressure to spoof commits or history to get a nice CHANGELOG
- Special handling of Merged Branches
- Does explicitly not do any magic based on things Conventional Commits to keep it compatible with less organized repos, but of course you should use commit conventions.
hh lohmann <[email protected]>
Changelog
Last 5 changes - see CHANGELOG file for full list and details
- (2.1.0) README: Clarify: Git remote must be defined for current branch to be used
- (2.1.0) Feature: Support multiple tags on the same commit
- (2.0.1) README: Clarify: Git remote must be defined for current branch to be used
- (2.0.0) Feature: Require tag (depending on setting requireTag): Reject creating a Changelog if commits without associated Git tag exist
- (1.6.2) Feature: Write newest changelog entries also to README.md: add: Write HTML comment informing that content was inserted by commits-to-changelog
Synopsis
CLI without parameters
commits-to-changelogParameters
no parameters
Settings
Default settings can be overwritten by key-value pairs in an object as value for a key "commits-to-changelog" in a package.json belonging to the repo for which a CHANGELOG.md should be created, e.g.
// package.json
{
"version": "...",
"commits-to-changelog": {
"headerDefault": "Latest",
"headerMerged": "Implement",
"linesToReadme": 5
},
"dependencies": {
"...": "..."
}
}Possible Settings
filterCommits
Array of RegExp: Filter out commits / commit types identified by a message matching one of the RegExps in the array
- Default: undefined
- Cf. filterDefaults
- May be used for types of commits identified by message patterns or exact commits to exclude from a sensible CHANGELOG
- Since JSON has no own type for them, RegExps have to be defined as strings, unlike vanilla JavaScript filterCommits does handle e.g.
^exp$exactly like/^exp$/(i,e. interprets unquoted/at start and end as RegExp delimiters, not as literal/part of the RegExp)
filterDefaults
Boolean: Filter out commit types that are rather not relevant for users by matching commit messages against RegExps /^bump version$/i, /^changelog$/i, /^dev:/i, /^[Hh]ousekeeping/i, /^planning/i, /[Rr]efactoring/i, /tests/i
- Default: true
- Own / additional RegExps via filterCommits
headerDefault
String to use as header for listing commits that do not belong to a defined Git tag
- Default: "Current"
headerMerged
String to use as header for listing Merged Branches with a commit message of the form Merge branch '<branch name>'
- Default: "Include (results of) separate branch"
linesToReadme
Write defined number of lines from the start of CHANGELOG.md also to an existing section with heading "Changelog" (or "CHANGELOG" or any preferred case) in README.md
- Existing section content is overwritten
- Short entry form with link to full CHANGELOG.md
- If "0", false or undefined: Do not touch README.md (and a possibly existing section Changelog)
- Default: "0"
- Note: The value should be a positive integer, but for convenience also strings containing (only) a positive integer are accepted
- Throws errors if greater "0" but no README.md or no section "Changelog" (case insensitive) was found in README.md
requireTag
Reject creating a Changelog if commits without associated Git tag exist
- Boolean, default: true
- Meant to improve workflows where a tag marks a release version and untagged commits would be missing when deploying via release version tag
Returns
no return
Examples
Sample CHANGELOG.md
See the CHANGELOG.md of this project
Sample for optionally writing to a section "Changelog" in README.md
See the section Changelog in this file (cf. details for optional setting linesToReadme under Settings)
Merged Branches
Branches that were merged as an explicit commit (i.e. no fast-forward) are listed as indented blocks with the message of the merge commit as a title line, e.g.
* dddb03a (HEAD -> master, origin/master) fix/unclear-error
|\
| * f6f8cd1 Update error message
|/
* 4bd8518 Update token hash to include encoded user nameas
- fix/unclear-error
- Update error message
- Update token hash to include encoded user nameIf the merge's commit message has the form Merge branch '<branch name>' it will be replaced by Include (results of) separate branch '<branch-name>', e.g.
* dddb03a (HEAD -> master, origin/master) Merge branch 'fix/unclear-error'
...as
- Include (results of) separate branch 'fix/unclear-error'
...Dependencies
none
Installation
CLIs should be installed systemwide ("global"). Strip off the -g parameter or replace it by a -D (as development dependency, -d for Bun) to explicitly restrict to a repo bounded usage.
Pick for your preferred package manager:
npm i -g commits-to-changelog pnpm i -g commits-to-changelog bun i -g commits-to-changelog # For Yarn you should double check docs for your and / or
# current Yarn version, newer versions do not treat `i package_name`
# as an alias for `add ...` and exclude global installations
yarn add commits-to-changelogDetails
The resulting CHANGELOG.md has the simple structure
# Changelog
## {groupheader} ({date})
- [{commit-subject}]({commit-link})
- [{commit-subject}]({commit-link})
## {groupheader} ({date})
- [{commit-subject}]({commit-link})
- [{commit-subject}]({commit-link})
(...)where # Changelog is the title, a Markdown atx heading (i.e. using "#") of level 1 with the text "Changelog", followed by an empty line, and lists of commits that are grouped by
- if setting requireTag is
true(default): the Git tag they are associated with - if requireTag is
false:- if given: a Git tag they are associated with
- if no Git tag associated: an existing package.json version if this is a non-labeled SemVer and is newer than an existing previous tag that is also a non-labeled SemVer
- if none of the above applies: the headerDefault (see Settings)
so that the applicable Git tag / package.json version or the headerDefault becomes the {groupheader} that together with the date of the Git tag or else the current date constitutes a Markdown heading of level 2 under which associated commits are listed as
- if a Git remote for the current branch is given: a link
[{commit-subject}]({commit-link})formed by the subject of the commit and the remote entry for the commit what is usually a page including a Git diff for the commit - if no Git remote is given: the subject of the commit only
If multiple Git tags exist on the same commit (for whatever reason), then the {groupheader} will be a sorted list of all tags separated by /, e.g. commits like
b6f8f5c (tag: fix-that, tag: feat-this) Fix: ...this...
0c6ec5e Feature: ...that...will appear in CHANGELOG.md as
## feat-this / fix-that (...date...)
- [Fix: ...that...](https://...)
- [Feature: ...this...](https://.../b6f8f5c)Git tags may be lightweight or annotated, i.e. the type of a tag has no influence on the resulting CHANGELOG.md.
Besides the existence and characteristics of Git tags, a possible package.json and Git remote defintions the actually resulting CHANGELOG.md can be shaped by Settings.
Source Code
Prior Work
The (initial) code here is forked from git-to-changelog, an already very good solution, but due to a hardwired search path '../../package.json' - mimicking npm's way of structuring a node_modules folder - not usable with pnpm, and while fixing this some other little things were changed / improved (see CHANGELOG) and made the initial little fix grow into an own project
License
- MIT (see LICENSE.txt)
References
CommonMark Spec: ATX headings
Conventional Commits
Git commmit subject
- The first line of a commit message that is separated from the body of the message by an empty line (identical to the whole message if this have empty line)
- cf. Git's example for a commit_template: https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_commit_template
Git: diff
Git: lightweight vs. annotated tags
Git: Working with Remotes: Showing Your Remotes
git-to-changelog
- npm registry: https://www.npmjs.com/package/git-to-changelog
- npmx: https://npmx.dev/package/git-to-changelog
- repo: https://github.com/Grafluxe/git-to-changelog
Non-labeled SemVer
- A semantic version (SemVer) that has no "labels for pre-release and build metadata (...) as extensions to the MAJOR.MINOR.PATCH format"
- https://semver.org/#:~#:~:text=Additional%20labels%20for%20pre%2Drelease%20and%20build%20metadata%20are%20available
