Build Status Software License Release Last Release Github commits (since latest release) Last Commit Code Size Repo Size Contributors WolfSoftware

Caretaker

Caretaker is an automated changelog generator. It works by reading the commit history for the repository and generates the changelog based on that. It requires no human intervention, and will work happily with existing repositories and their existing git histories.

Caretaker also has an advanced category mode, which allows it to parse specially crafted commit messages and split the CHANGELOG into categories (per release).

Additional features

  • Converting a GitHub username tag into a link to the GitHub user (appended to the commit message).
  • Automatically linking each commit message to the hash of that commit.
  • Automatically linking each pull request to the pull request number.
  • Can run automatically as a post-commit hook.
  • Ignore commits that are shorter than a specified number of words.
  • Bump verions and tag releases automatically.

For a full list of featues see the section on command line usage.

Table of contents

Installation

Installing caretaker is very simple, just execute the following command.

gem install caretaker

Command line usage

Caretaker has a number of command line options:

Usage: caretaker [-h] [-a author] [-c] [-e] [-i] [-o filename] [-r] [-s] [-u] [-w number]
Option Purpose Default Value
-h or --help Show the help message N/A
-a or --author [Github username] Specify the author name
-b or --bump [part] Bump the VERSION.txt to next version.
-c or --config Generate a .caretaker.cfg config file. false
-e or --enable-categories Enable the splitting of commit messages into categories false
-i or --init Initialise the repo to use caretaker
-o or --output [filename] Set the name of the output file CHANGELOG.md
-r or --remove-categories Remove categories from commit messages. --enable-categories sets this to true false
-s or --silent Turn off all output from Caretaker, aka Silent Mode false
-u or --url-verification Verify each url to ensure that the links are valid, skip any links that are not false
-w or --words number Minimum number of words needed to include a commit. 1

Basic usage

Initialise the repository

This step isn't required but running the following command configures your repository to use caretaker automatically on every commit to ensure that your changelog is as up-to-date as possible.

caretaker -i

What is actually does is create a post-commit hook in your git repo which execute caretaker and adds the updated CHANGELOG.md to the commit ready for you to push.

The post-commit hook

#!/usr/bin/env bash

OUTPUT_FILE="CHANGELOG.md"

caretaker

res=$(git status --porcelain | grep "${OUTPUT_FILE}" | wc -l)
if [[ "${res}" -gt 0 ]]; then
    git add "${OUTPUT_FILE}"
    git commit --amend --no-edit
end

Customisation

There are a number of ways in which you can customise the way caretaker works, you can enable category mode, or change the output file from CHANGELOG.md to some other name. If you do this as part of the initialisation then the settings are retained.

Example of customised usage

caretaker -i -e -o HISTORY.md

Resulting post-commit hook

#!/usr/bin/env bash

OUTPUT_FILE="CHANGELOG.md"

caretaker -i -e -o HISTORY.md

res=$(git status --porcelain | grep "${OUTPUT_FILE}" | wc -l)
if [[ "${res}" -gt 0 ]]; then
    git add "${OUTPUT_FILE}"
    git commit --amend --no-edit
end

It is worth noting the final git commit command the --amend tells git to amend the last commit and add in the output file and the --no-edit tells git that we do not want to edit the commit message and to retain the previous one.

Once the initialisation is complete, you should never need to do anything else as caretaker will run automatically and keep your changelog up-to-date. You can re-run the init command at anytime if you wish to change the configuration that you are using.

If you do not want to run caretaker automatically, maybe you are just evaluating it and are not yet ready to fully automate the process, then you can run caretaker manually from the command line.

Advanced usage

Amongst other things Caretaker has a category mode (-e or --enable-categories) which allows for the grouping of changes by category. This is done by using special tags as a prefix to your commit messaged. It will parse these prefixes and group like commits together, within a specific release.

git commit -m "<category>: <message>"

Category example

git commit -m "docs: Updated the README.md to include an example."

Category list

The categories are used for splitting the changelog into logical sections. In the following table the category is what is displayed in the CHANGELOG.md (as the section header), and the patterns are the strings that it will match on when parsing the commit messages.

The matching is case-insensitive.

Category Patterns Purpose
New Features new features, new feature, new, feature Any new features that have been added
Improvements improvements, improvement Any improvement or enhancement of an existing feature
Bug Fixes bug fixes, bug fix, bug, bugs Any bug fixes to existing features
Security Fixes security fixes, security Any security fixes to existing features
Refactor refactor A code change that neither fixes a bug or adds a feature
Style style A change that does not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
Deprecated deprecated Any existing feature that is being deprecated
Removed removed Any existing feature that is being removed
Tests tests, test, testing Any changes to the existing tests
Documentation documentation, docs Changes to documentation only
Chores chores, chore Changes to the build process or auxiliary tools and libraries such as documentation generation
Experiments experiments, experiment Any experiments that you are carrying out, these are things that might get added and then removed again
Miscellaneous miscellaneous, misc Anything else (this shouldn't really be required)
Initial Commit initial commit, initial A special tag for the initial commit to the repo
Skip skip, ignore A special tag to ignore adding the commit to the CHANGELOG

Any commit without a matching category will be added to an 'Uncategorised' group.

Example category output

# Changelog

All notable changes to this project will be documented in this file.

### [Unreleased](https://github.com/WolfSoftware/caretaker/compare/v1.0.0...HEAD)

###### Documentation:

- Updated the README.md to include an example.

###### Uncategorised:

- Created an example without a prefix.

Tagging release versions

Due to the way that post-commit hooks work, if you were tag a release that tag would either be ignored or worse lost, because the commit ID changes when a 'commit amend' is carried out. In order to get around this problem Caretaker can now tag releases for you as part of its push process.

The current version is stored in 'VERSION.txt', and it is semantic version string (however it can include an optional v prefix eg v1.0.0). This version is used to 'tag' a release as part of the process. It works be comparing the current tag to the one in the file and if they are different it will tag the release with the new version.

Release handler snippet

The following code is a snippet of how the release mechanism works:

if [[ -n $RELEASE_VERSION ]]; then
    git tag "${TAG_VERSION}"
fi

#{cmd}

res=$(git status --porcelain | grep "${OUTPUT_FILE}" | wc -l)
if [[ "${res}" -gt 0 ]]; then
    git add "${OUTPUT_FILE}" >> /dev/null 2>&1
    git commit --amend --no-edit >> /dev/null 2>&1

    if [[ -n "${RELEASE_VERSION"} ]]; then
        git tag -f "${TAG_VERSION}"
    fi
fi

As you can see, it will tag the release, run caretaker and re-tag the release after the commit amend, ensuring that the tag persists. This is not a perfect solution, but it does work :)

The created tag is NOT pushed to the remote end, this is to allow manual pushing once the release is correct.

Bumping release versions

In order to make life as simple as possible the new version of Caretaker comes with a --bump option, this takes 1 argument of either major, minor or patch and will update the version file accordingly.

Note if the version file doesn't exist, it will be created with a default version of v0.1.0

Caretaker config file

Caretaker allows you to generate a config file (-c or --config-file) which it will read automatically, so that you do not need to provide command line flags each time you run Caretaker, this file is also read when you run Caretaker via the post-commit hook.

It will look in the base of the current git repository for the config file, if it is not found it will then check your home directory, if still not found it will check the current directory and every parent directory until it either finds a config file or runs out of directories to check. Placing the config file, for example, in your home directory will have the effect of making it global for ALL your git repositories.

The config file is called .caretaker.yml.

You can run Caretaker with command line options and if you add the -c option it will generate the config (in the base of your git repository) with the settings you specificy.

Example config file

enable-categories: false
min-words: 1
remove-categories: false
silent: false
verify-urls: false

Github usernames

Caretaker is also able to parse commit messages for special tags which specify a GitHub username and converts those tags into a link to the user. This link appended to the commit messages.

Github username example

git commit -m "docs: This is a GitHub username example. {TGWolf}"

In addition you can set a username using the -a option:

Github username command line example

git commit -m "docs: This is a GitHub username example." -a TGWolf

You can also use the -a option along with the -i (init) option to set the username as your default for all commits.

If there is already a author tag within the commit then the -a option is ignored for that commit, it is only appended to commits with no author. This stops double entries if you enable -a after you have already tagged commits with an author.

Result

- This is a GitHub username example. [`[Author: TGWolf]`](https://github.com/TGWolf)

Pull requests and commits

Caretaker is also able to identify the difference between pull requests and commits and automatically creates a link to either the pull request number or the commit it.

Pull request linking example

- This is a normal commit. [`[17df108]`](https://github.com/WolfSoftware/caretaker/commit/17df1080a501ed1bb780aa946190d64966dc30df)
- This is a pull request. [`[#7]`](https://github.com/WolfSoftware/caretaker/pull/7)

Issues

It is also possible to specify a tag within the commit to tell caretaker that the commit relates to an issue and caretaker will create a link to that issues.

git commit -m "Bug: This fixes a bug in the code and resolves issue (issue-7).

##### Bug Fixes:

This fixes a bug in the code and resolves issue [`[#7]`](https://github.com/WolfSoftware/caretaker/issues/7)

Using caretaker in your own code

Installation

Add this line to your application's Gemfile:

gem 'caretaker'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install caretaker

Usage

Load the gem

require 'caretaker'

Initialise

caretaker = Caretaker.new(output: 'HISTORY.md')

output is optional and will default to CHANGELOG.md

Generate a changelog

Caretaker.generate_changelog

Initialise the git repo

Caretaker.init_repo

Contributing to caretaker

Setup

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Testing

For local testing make sure that you run bundle exec rspec spec and then rake install to install the gem locally.

For further information please refer to the contributing documentation.

To-Do List

  • [ ] CLI option to enable/disable linking to commit hashes
  • [ ] CLI option to enable/disable linking to pull requests
  • [ ] CLI option to enable/disable linking to github users
  • [ ] Option to allow auto-pushing of the tag to the remote origin