7 years ago I wrote about a script I was using to generate changelogs for Marked. Since then I’ve continued updating the script to work with just about all of my projects, from Xcode projects to Ruby gems to scripts that just have a VERSION file in the same directory. It can output a few different formats of changelog to accommodate all of my different documentation formats. So I’m posting it again.
Since it’s unlikely anyone remembers, this script uses Git tags to determine what commits have been made since the last release. This works well with git-flow, but any setup that creates tagged releases will work. It parses commit messages for lines like - FIXED: description of fix
, and it now works with a more “tag-like” syntax: @fix description of fix
. It gathers all of these lines from the commit messages and outputs a Markdown-formatted changelog, ready for release notes or website posting.
It’s simple yet highly effective. Any time I make a change I want to include in the release notes, I just make sure to include a tagged line in the commit message. It works with commit subjects as well as commit notes. Then, when it’s time to release, I just run changelog
and get my output for sharing. It can also update a CHANGELOG.md file by running changelog -u
. It detects the format of the file and adds appropriately-formatted notes to the file, recognizing if there’s already an entry for the current version number and replacing it.
Some of the customizations are specific to the formatting I use for Bunch notes, which include syntax for custom Jekyll plugins for icons and availability. These won’t be of use to anyone else, but unless your directory structure happens to exactly match the one I use for Bunch, or you use the --format bunch
flag, you’ll never see those. But if you want to edit the script to fit your specific needs, you can see how it’s done.
Eventually I’ll probably generalize this and make it work with templates and a config file with regexes for matching types and formats, but for now it’s just open to your hacking. This script has been a huge timesaver for me and has resulted in very complete release notes and changelogs I can be proud of. I hope it does the same for you.
The available tags are:
- @change, @changed
- @breaking, @deprecated
- @rem, @removed
- @fix, @fixed
- @imp, @improved, @improvement
- @add, @added, @new
All of these can be in the format - TAGNAME: description
or @tagname description
. The first letter of the description will be capitalized when the release notes are rendered.
You can also use changelog --select
to pop up an fzf
selection of all tags, allowing you to generate release notes added since any previous version. Use changelog --only TYPE
to output only changes of a type (changed, new, improved, deprecated).
You can also use this script in combination with a tool like gh
to output a changelog when creating a GitHub release. Just pass output of the changelog
command to any command that accepts input on STDIN.
Usage: changelog [options] [CHANGELOG_FILE] [APP_NAME]
Gets git log entries since last tag containing CHANGED, NEW, IMPROVED, FIXED, REMOVED
-c, --copy Copy results to clipboard
-f, --format FORMAT Output format (def_list|bunch|markdown)
-o, --only TYPES Only output changes of type (changed, new, improved, fixed, deprecated)
--file PATH File to read additional commit messages from (for commit-msg hooks)
-s, --select Choose "since" tag
-u, --update [FILE] Update changelog file
-v, --version=VER Force version (skips version detection)
-n, --no_version Skip version check (prevents header output)
-h, --help Display this screen
CHANGELOG_FILE
and APP_NAME
are optional, it will automatically detect a CHANGELOG.md
file in the current directory, and derive the app name based on the project type (works with Ruby gems and Xcode projects currently).
Have fun, and may your changelogs be informative and complete. Again, here’s the script. That Gist will be updated as I make changes to the script over time, so check the Gist comments for additional notes as this post ages. If I get around to making a package out of this (with templates and config and such), there will be a new post about it, of course. Based on a quick search there are a ton of changelog generators already out there, so this will probably remain a script that fits my personal needs perfectly, and is easily hacked around with by others.