@theo.gravity/changelog-version
Version:
Creates / updates a changelog with customizable options, including version / timestamp / CI support.
374 lines (263 loc) • 11.7 kB
Markdown
# changelog-version
[](https://circleci.com/gh/theogravity/changelog-version)
[](https://badge.fury.io/js/%40theo.gravity%2Fchangelog-version)
[](https://standardjs.com)
Creates / updates a changelog with customizable options, including version / timestamp / CI support.
## What it offers
- Changelog file name
- Where to find your version data
- What your `unreleased` text for replacement should be (eg `[UNRELEASED]`, `*version*`, etc)
- What your release tag should look like (via the `{date}`, `{version}` tags)
- Date formatting via the [`dateformat`](https://www.npmjs.com/package/dateformat) library
- Use a custom config file with additional callback handlers
- Helper command included to create a changelog file + stamp it with the `unreleased` text
- Examples on how to auto-increment your logs and publish to npm in your CI
Turn this (the format can be customized):
```
# Changelog
## [UNRELEASED]
- I have a change!
```
into this:
```
# Changelog
## 1.2.3 - Wed May 04 2016 04:27:29
- I have a change!
```
## What it will not do
- Version bumping `package.json`. [`version-bump`](https://www.npmjs.com/package/@theo.gravity/version-bump) can do that job.
Your `package.json` file must have the new version you want to stamp the changelog with before running
`changelog-version release`.
- Commit changes to your VCS.
## Contents
<!-- TOC -->
- [Install](#install)
- [Quick start usage](#quick-start-usage)
- [Mark a new unreleased entry into the changelog](#mark-a-new-unreleased-entry-into-the-changelog)
- [Stamp the changelog with the current version + time from package.json](#stamp-the-changelog-with-the-current-version--time-from-packagejson)
- [CLI Usage](#cli-usage)
- [prepare](#prepare)
- [Example 1](#example-1)
- [Example 2](#example-2)
- [release](#release)
- [Example](#example)
- [verify](#verify)
- [Custom configuration file](#custom-configuration-file)
- [Additional properties](#additional-properties)
- [Release properties](#release-properties)
- [`async onBeforeRelease`](#async-onbeforerelease)
- [`async onAfterRelease({ version, date, releaseStamp })`](#async-onafterrelease-version-date-releasestamp-)
- [API](#api)
- [CI Integration](#ci-integration)
- [Auto-versioning + publishing in your CI](#auto-versioning--publishing-in-your-ci)
- [CircleCI](#circleci)
<!-- TOC END -->
## Install
`npm install -g @theo.gravity/changelog-version`
## Quick start usage
### Mark a new unreleased entry into the changelog
`changelog-version prepare`
### Stamp the changelog with the current version + time from package.json
`changelog-version release`
## CLI Usage
```
$ changelog-version
Usage: changelog-version <command> [options]
Utility for creating and updating a changelog file.
Use "<command> --help" for additional options.
Options:
-V, --version output the version number
--configFile [fileName] Name of the optional config file, relative to projectRoot.
Default is ".changelog.js".
--projectRoot [path] The project root where the package.json and changelog file is found.
Default is process.cwd().
--changelogFile [fileName] The relative path to the changelog file from projectRoot.
Default is "CHANGELOG.md".
-h, --help output usage information
Commands:
prepare [options] Stamp the changelog with an unreleased marker.
Optionally to be used prior to the "release" command.
A new file (defined by --changelogFile) will be created if one does not exist.
release [options] Stamp the changelog with the version / date info.
You do *NOT* have to use "changelog-version prepare" before using this command.
verify [options] Verifies that the changelog contains the unreleasedTag.
Returns with an error status if the changelog does not have it.
Useful to run as part of a pre-commit hook.
Examples:
$ changelog-version prepare --newUnreleasedText "## [VERSION_GOES_HERE]\n\n"
$ changelog-version release --unreleasedTag "[VERSION_GOES_HERE]" --unreleasedTagFormat "{version}"
$ changelog-version verify
```
### prepare
```
$ changelog-version prepare --help
Usage: prepare [options]
Stamp the changelog with an unreleased marker.
Optionally to be used prior to the "release" command.
A new file (defined by --changelogFile) will be created if one does not exist.
Options:
--newUnreleasedText [textToPrepend] The text to prepend to the log file.
Default is "# [UNRELEASED]\n\n".
-h, --help output usage information
```
#### Example 1
Running `changelog-version prepare` in an empty directory will create the file `CHANGELOG.md` with the following:
```
# [UNRELEASED]
```
#### Example 2
You have a `CHANGELOG.md` with the following content:
```
# 1.2.3
- New release
```
Running `changelog-version prepare` will update `CHANGELOG.md` with:
```
# [UNRELEASED]
# 1.2.3
- New release
```
### release
```
$ changelog-version release --help
Usage: release [options]
Stamp the changelog with the version / date info.
You do *NOT* have to use "changelog-version prepare" before using this command.
Options:
--requireUnreleasedEntry If present, will exit with an error code if the
unreleasedTag is not found in the changelog file.
--requireUnreleasedEntryFailMsg [failText] Message to display if requireUnreleasedEntry
is enabled and the validation check fails
--packageFile [fileName] The relative path to package.json, or a JSON file that
contains the "version" field from projectRoot.
Default is "package.json".
--unreleasedTag [textToReplace] The text to find in the changelog which would get
replaced with the version / time.
Default is "[UNRELEASED]".
--unreleasedTagFormat [format] Format to replace unreleasedTag with.
Available tags are "{version}" and "{date}".
Default is '{version} - {date}'.
--dateFormat [format] Date mask to use from the "dateformat" library when
replacing the versionTag.
Default is "default".
-h, --help output usage information
```
#### Example
- You used `changelog-version prepare` in the prior step and added in your release notes
- You have a `package.json` that contains `{"version": "1.2.3"}`
current `CHANGELOG.md`:
```
# [UNRELEASED]
* New feature!
```
Running `changelog-version release` will update `CHANGELOG.md` with:
```
# 1.2.3 - <current date>
* New feature!
```
### verify
```
$ changelog-version verify --help
Usage: verify [options]
Verifies that the changelog contains the unreleasedTag.
Returns with an error status if the changelog does not have it.
Useful to run as part of a pre-commit hook.
Options:
--unreleasedTag [textToLookFor] The text to find in the changelog.
Default is "[UNRELEASED]".
--requireUnreleasedEntryFailMsg [failText] Message to display if requireUnreleasedEntry
is enabled and the validation check fails
-h, --help output usage information
```
## Custom configuration file
To spare yourself from having to specify command line options each time, you can use a custom config file.
Place `.changelog.js` in the root of your project.
(The file name can be configured with the `--configFile` option, which is relative to `--projectRoot`.)
If detected, `changelog-version` will derive options from this file.
With the exception of `projectRoot`, options defined on the command line will take
precedence.
```js
// This is an optional configuration file
// you can use with changelog-version.
// If specified, any command line args has priority over the
// values returned in this file.
// All values are optional.
// Do not use the ES6 export default
// since the file is imported using require()
// See command line options for additional available properties
module.exports = {
/**
* This is called before doing the version stamping.
* @returns {Promise<void>}
*/
onBeforeRelease: async () => {},
/**
* This is called after the version stamping is complete.
* @param {string} version Release version that the changelog stamp used
* @param {string} date Formatted date that the changelog stamp used
* @param {string} releaseStamp Release text that the changelog was stamped with
* @returns {Promise<void>}
*/
onAfterRelease: async ({ version, date, releaseStamp } = {}) => {},
// Values can either be text
// or a (async) function that returns text
// ==== Common options ====
// If specified here, this will have priority
// over the command line option projectRoot
// once this file is read.
projectRoot: () => {
return process.cwd()
},
changelogFile: () => {
return 'CHANGELOG.md'
},
// ==== Options specific to prepare ====
newUnreleasedText: '# UNRELEASED\n\n',
// ==== Options specific to release ====
packageFile: async () => {
return 'package.json'
},
// see https://www.npmjs.com/package/dateformat
// for options
dateFormat: 'default',
unreleasedTag: () => {
return 'UNRELEASED'
},
unreleasedTagFormat: '{date} - {version}'
}
```
### Additional properties
Aside from the command line options, the config file offers additional properties:
#### Release properties
##### `async onBeforeRelease`
Called before the release. Use this to do any pre-setup that you need to do.
##### `async onAfterRelease({ version, date, releaseStamp })`
Called after the changelog has been updated.
```
* @param {string} version Release version that the changelog stamp used
* @param {string} date Formatted date that the changelog stamp used
* @param {string} releaseStamp Release text that the changelog was stamped with
```
## API
- See `src` for the API.
- See the `test` directory for API usage samples.
## CI Integration
### Auto-versioning + publishing in your CI
Make sure you have `changelog-version`.
Install:
- [version-bump](https://www.npmjs.com/package/@theo.gravity/version-bump)
- [version-bump-plugin-git](https://github.com/theogravity/version-bump-plugin-git)
`npm install @theo.gravity/version-bump @theo.gravity/changelog-version version-bump-plugin-git --dev`
#### CircleCI
This repo uses CircleCI to automatically version stamp the `CHANGELOG.md` file and
publish to npm with the new version.
See the `.circleci/` directory for auto release log stamping, version bumping and npm publishing.
The following `package.json` script is used in conjunction with the CircleCI flow:
```json
{
"scripts": {
"release-log": "changelog-version release",
"prepare-publish": "version-bump git-commit-msg && npm run release-log"
}
}
```