Automatic release notes from Git commit messages

[Tweet : nvALT]

I thought I’d share the script I’m using to generate changelogs for Marked releases using git commit messages. A lot of it is tailored to my own setup, and would require some customization to make it work with a different workflow. Also, it’s messy code, for which I apologize. Ultimately it should have just been a procedural script, but I started to go somewhere else with it before I realized that wasn’t what I was getting paid for.

Anyway, when I’m working on Marked, I use keywords in my git commits to specify things I want to appear in the release notes later. For a long time I would just output a pretty-formatted log and then use one-off scripts and Sublime Text to generate my release notes. This script is my current method of automating it.

Workflow specifics

ChangeLogger uses git rev-list --tags --max-count=1 to find the commit hash for the last tag, which in my workflow (git-flow) are only created for releases. Thus the commit hash of the last tag is where the next changelog begins.

Lines in commit messages can have one of three keywords at the beginning, anything without a keyword is not included in the changelog. The keywords are “NEW”, “FIXED”, and “IMPROVED”. The script also accepts “FIX” and “IMPROVEMENT”, and these can have hyphens before (as Markdown lists) and colons after, but that’s all stripped either way.

The header for the changes gets the app name and version information. These are pulled from Xcode Info.plist files and agvtool.

It outputs formatted in the way my documentation generator needs for creating the release notes pages. That’s currently hardcoded, but probably easy to modify as needed.

Example commits

Here are a few commits from the next version of Marked

Thu Jul 6 10:53:41 2017 -0500 4a4db1bb Allow disabling code wrap, fix empty lang class  [Brett Terpstra]
   - NEW: Option to disable wrapping inside of code blocks, forcing scroll (Preferences->Style->"Allow themes to wrap text inside code blocks")
- FIXED: If a language on a code block isn't specified, Marked inserts "class=(null)"

Wed Jul 5 15:09:12 2017 -0500 68a90c57 Leanpub aside styling, fullscreen toc  [Brett Terpstra]
   - IMPROVED: {icon=[fontawesome name]} before a leanpub aside works now
- NEW: Full screen mode for table of contents, fixed to left (automatic when switching to full screen, can be manually enabled from button on TOC popup)

Tue Jul 4 15:25:06 2017 -0500 fe20f115 Fix CriticMarkup export  [Brett Terpstra]
   - FIXED: Setting criticmarkup type (markup, original, edited) in non-PDF export has no effect
- IMPROVED: {icon=[fontawesome name]} before a leanpub aside works now

When the script runs on this repository, it outputs:

Marked 2.5.11 (933)
-------------------------

#### NEW

- Option to disable wrapping inside of code blocks, forcing scroll (Preferences->Style->"Allow themes to wrap text inside code blocks")
- Full screen mode for table of contents, fixed to left (automatic when switching to full screen, can be manually enabled from button on TOC popup)

#### IMPROVED

- {icon=[fontawesome name]} before a leanpub aside works now

#### FIXED

- If a language on a code block isn't specified, Marked inserts "class=(null)"
- Setting criticmarkup type (markup, original, edited) in non-PDF export has no effect

The script has no library dependencies, so it should be self-contained. The few config options it has are commented at the top.

If this sounds intriguing, and you’re feeling forgiving about a mess of pointless class structures, feel free to grab it.