git-history-changelog
Framework for writing changelog generation tools based on git history.
Uses nodegit.
- Split commit messages to custom categories.
- By default all stages autosaves in local config (check Store object).
- You can provide your render and formatting methods.
- Framework care and track branches.
Please contact me if you use this library in your projects or for support and proposals.
Example result
Branch: refs/heads/master, 2018-1-7 06:00:38
# 0.1.0
## example
* package-history added
## critical
* Store now handles Git.Repository instance
* openOrCreate now with repository path argument
* filterParsedCommits renamed to formatParsedCommits
## log
* custom message types now passing through mapping/formatting methods
## new
* reduceUnreleasedCommits, groupEveryKeyByKeys methods added
# 0.0.3
## log
* link fixed in readme
* repo updated
# 0.0.1
## dev
* readme added
* example with categories
## bugfix
* second parse error fixed
Simple use
-
- Pick untracked commits
-
- Format commit messages from '{messageCategory}: message;'
-
- Accept all filtered and mapped commits
-
- Render all categories with default simple markdown renderer
const store = await Store.openOrCreate('./changelog.json', './', 'autosave');
// 1. Pick untracked commits
const parsedCommits = await parseUntrackedCommits(store);
// 2. Format commit messages from '{messageCategory}: message;'
const formatted = await formatParsedCommits(store, parsedCommits, (x) => {
const messages = x.message.split(';').map(y => y.trim());
const categorized: ChangelogMessages<string[]> = {};
const defaultCategory = 'log';
for (const msg of messages) {
const [ category, text ] = msg.includes(':') ? msg.split(':') : [ defaultCategory, msg ];
if (!(category in categorized))
categorized[category] = [];
categorized[category].push(text.trim());
}
return categorized;
});
// 3. Accept all filtered and mapped commits
const changelog = await toChangelog(store, formatted);
// 4. Render all categories with default simple markdown renderer
const rendered = renderChangelog(store, {
entries: changelog,
categories: 'all',
});
fs.writeFile('./changelog.md', rendered, 'utf8', err => {
if (err) console.error(err);
else console.log('ok');
});
Result for this repo:
# example
* package-history added
# critical
* Store now handles Git.Repository instance
* openOrCreate now with repository path argument
* filterParsedCommits renamed to formatParsedCommits
# log
* custom message types now passing through mapping/formatting methods
Future plans
- git tags extraction
- more examples
- ui
Api
Store
Cache control object. Provide simple methods for saving and loading config.
Fields:
-
filename
- absolute path to config -
data
- config, typeof GitHistoryType -
autosave
- flag, if true, framework will save config after every step -
repo
- NodeGit.Repository instance
Methods:
-
static async openOrCreate(filename, repositoryPath, autoSave: false|'autosave'): Store
- open or create config and open repository -
async clearChangelog()
- clear changelog (from last step) -
async save(): true
- save config tofilename
git
This methods care about git commits, branches etc.
async function parseUntrackedCommits(store: Store, {
branchName?: string,
onlyLastCommit?: boolean
}): ParsedHistoryCommit[]
Parse untracked commits with specified options.
Returns new parsed commits.
-
branchName
- target git branch, (current by default) -
onlyLastCommit
- track only last commit, skip others (track all by default)
async function fileContentBlob(
store: Store,
commitHash: string,
filePath: string
): NodeGit.Blob
async function fileContentBuffer(
store: Store,
commitHash: string,
filePath: string
): Buffer
async function fileContentString(
store: Store,
commitHash: string,
filePath: string
): string
Read file by it's path from specified commit.
-
filePath
- relative to repository root (eg 'package.json')
commits
This methods care about commits filtering and messages extraction.
async function formatParsedCommits(
store: Store,
parsedCommits: ParsedHistoryCommit[],
format: FormatFunc,
onlyMarked?: false|'onlyMarked'
): UnreleasedChangelogCommit[]
Format & filter commit messages.
-
parsedCommits
- commits that will be formatted & filtered. -
format
- filtering and extraction method (check example). -
onlyMarked: false|'onlyMarked'
- pick commits only withcommitToUnreleasedChangelog=true
(all by default)
async function reduceUnreleasedCommits(
store: Store,
unreleasedCommits: UnreleasedChangelogCommit[]
): UnreleasedChangelogCommit[]
Pick last commit for each listed branch,
take all messages to last commit,
group all messages by categories.
For better example, check package-history example.
changelog
This methods care about changelog entries and rendering.
async function toChangelog(
store: Store,
commits: UnreleasedChangelogCommit[]
): ChangelogEntry[]
Fixes specified commits as changelog entries.
async function renderChangelog(store: Store, {
entries: ChangelogEntry[],
categories: 'all'|string[],
messageRenderer?: RenderChangelogMessageFunc,
changelogRenderer?: RenderChangelogFunc
}): string
Renders changelog entries with specified renderers.
By default it uses simple markdown renderers (check source code).
Better use custom rendering method (check package-history example).
utils
function groupByKeys<T>(items: { [keyName: string]: T }[] )
: { [keyName: string]: T[] };
Group every item's values by it's keys.
Example:
groupByKeys([ { a: 1 }, { a: 2 } ]) -> { a: [ 1, 2 ] }
function groupEveryKeyByKeys<T>(
item: { [keyA: string]: { [keyB: string]: T }<T>[] }
):
{ [keyA: string]: { [keyB: string]: T[] } }
Example:
groupEveryKeyByKeys({ x: [ { a: 1 }, { a: 2 } ] }) -> { x: { a: [ 1, 2 ] } }