Create an unopionated CHANGELOG.md from Git commit history (see Details)
hh lohmann <hh.lohmann@gmail.com>
Last 5 changes - see CHANGELOG file for full list and details
CLI without parameters
commits-to-changelog
no parameters
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",
"linesToReadme": 5
},
"dependencies": {
"...": "..."
}
}
Boolean: Auto-commit CHANGELOG.md and move tag to include CHANGELOG.md in the tag’s range (see Details)
true (not existing tag cannot be moved)requireTag to be true should guarantee that only approved tags are affected.Boolean: If commits without tags are allowed (see requireTag): Use current date instead of commit date for grouping commits without tag
Array of RegExp: Filter out commits / commit types if commit message matches a RegExp in the array
^exp$ exactly like /^exp$/ (i,e. interprets pairs of unquoted / at start and end as RegExp delimiters, not as literal / part of the RegExp), and also RegExp flags are possible, e.g. ^exp$/i and /^exp$/iBoolean: 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
String to use as header for listing commits that do not belong to a defined Git tag
Number: 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
Boolean: Create CHANGELOG.md with reference-style links / link references (see Details)
Boolean: Reject creating a Changelog if commits without associated Git tag exist
Use commit date to group commits (additionally to tags)
| false | “never” |
isodate”
isodate by date, isodate = e.g. 2022-02-22isodate”
Boolean: Display also Git notes (if existing)
*Note:* )no return
See the CHANGELOG.md of this project
See the section Changelog in this file (cf. details for optional setting linesToReadme under Settings)
none
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-changelog
The resulting CHANGELOG.md has the simple structure
# Changelog
## {groupheader} ({date})
- [{commit-subject}][{commit-hash}]
- [{commit-subject}][{commit-hash}]
## {groupheader} ({date})
- [{commit-subject}][{commit-hash}]
- [{commit-subject}][{commit-hash}]
(...)
[{commit-hash}]: {commit-link}
[{commit-hash}]: {commit-link}
[{commit-hash}]: {commit-link}
[{commit-hash}]: {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
true (default): the Git tag they are associated withfalse:
so that the applicable Git tag / package.json version or the headerDefault becomes the {groupheader} that together with the date of the newest commit in the group constitutes a Markdown heading of level 2 under which associated commits are listed as
[{commit-subject}][{commit-hash}], i.e. the subject of the commit message and the commit’s hash as a label for a link reference to be listed at the end of the file with a {commit-link} to the remote entry for the commit that is usually a webpage showing the full commit message (i.e. the subject and possible further contents) and diff for the commit
(#{commit-link}) in the commit line and no link reference list at the end of the file, set false for setting referenceLinks. Note that this affects only a non-rendered view of CHANGELOG.md, for rendered Markdown this will make no difference.If your workflow allows commits without tags (see setting requireTag) then you can opt with setting defaultDateToday to use the current date for commits without tags instead the newest commit’s date.
With setting useDateGroups you can additionally group by date, distinguished from tag based grouping by groupheader in italics, e.g.
# Changelog
## {groupheader} ({date})
- [{commit-subject}][{commit-hash}]
- [{commit-subject}][{commit-hash}]
## *{date}*
- [{commit-subject}][{commit-hash}]
- [{commit-subject}][{commit-hash}]
(...)
[{commit-hash}]: {commit-link}
[{commit-hash}]: {commit-link}
[{commit-hash}]: {commit-link}
[{commit-hash}]: {commit-link}
(...)
Git tags do not need to have any special structure or orderings, they could be natural numbers as well as SemVers, ISO dates, CalVer, arbitrary names or any mixture like that used by DokuWiki, they are generally just “tags” in the most verbatim sense, giving the information you may regard as helpful to track changes - the order in the CHANGELOG.md always depends on that of the listed Git commits, not on any tagging scheme. You may choose a scheme that allows to integrate a CHANGELOG.md creation into an overall workflow like setting first a non-labeled SemVer version in package.json and derive release tags from this (see above).
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...](...hash...)
- [Feature: ...this...](...hash...)
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.
By default the freshly created CHANGELOG.md will be auto-committed and the latest tag it covers will be moved to the commit connected to the creation of CHANGELOG.md so that the CHANGELOG.md will automatically be a part of that what it describes, e.g. a relase based on the latest tag, so that you will have a history
3ab6fe2 (tag: 3.0.0) changelog
f3c32ba done everything
2bbccfe done that
9a31617 done this
instead of
3ab6fe2 changelog
f3c32ba (tag: 3.0.0) done everything
2bbccfe done that
9a31617 done this
changelog will not appear in the CHANGELOG.md by default commit filteringDepending on linesToReadme a README.md with updated section ‘Changelog’ will auto-committed together with CHANGELOG.md.
Use setting commitMoveTag to skip auto-committing / tag moving and do things manually or by other means instead.
Deprecations
- Special Handling for Explicitly Commited Merged Branches / no Fast Forward
- Up to including version 2.1.0, branches that were merged as an explicit commit (i.e. no fast-forward, e.g. explicitly by
git merge --no-ff) were listed as indented blocks with the message of the merge commit as a title line, e.g. ```sh
- dddb03a (HEAD -> master, origin/master) fix/unclear-error |
| * f6f8cd1 Update error message |/- 4bd8518 Update token hash to include encoded user name
asmarkdown- fix/unclear-error
- Update error message
- Update token hash to include encoded user name
If the merge's commit message has the form `Merge branch '<branch name>'` it will be replaced by the value of the [setting](#settings) headerMerged (see below), e.g. with value "Include (results of) separate branch" the merge commitsh- dddb03a (HEAD -> master, origin/master) Merge branch ‘fix/unclear-error’ …
would becomemarkdown- Include (results of) separate branch ‘fix/unclear-error’ … ``` This feature is deprecated in version 2.2.0 and higher since tags “inside” a merged branch will act as “normal” group markers on the parent’s level (i.e. breaking the aimed “subgrouping” of the merged commits).
- For backwards compatibility this feature can be re-enabled by setting
headerMergedwith a string value to be used as title line. Per defaultheaderMergedis not set and merged commits will be displayed as normal commits.- It is strongly advised not to settle on this feature but instead to use (specially tailored) Git tags to group commits together
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