Generate a changelog from git metadata using conventional commit conventions.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive configuration system supporting presets, custom transforms, detailed output control, and integration with various commit conventions and repository structures.
type Logger = (source: string, messages: string | string[]) => void;
interface Commit {
hash?: string;
date?: string;
message?: string;
subject?: string;
body?: string;
type?: string;
scope?: string;
notes?: Array<{ title: string; text: string }>;
references?: Array<{ issue: string; action: string }>;
gitTags?: string;
committerDate?: string;
}
interface Package {
name?: string;
version?: string;
description?: string;
repository?: {
type?: string;
url?: string;
};
[key: string]: any;
}
interface HostedGitInfo {
url: string;
type: HostType;
host: string;
owner?: string;
project?: string;
}
type HostType = 'github' | 'gitlab' | 'bitbucket' | 'sourcehut' | '';
interface Context {
version?: string;
previousTag?: string;
currentTag?: string;
host?: string;
owner?: string;
repository?: string;
repoUrl?: string;
[key: string]: any;
}Core configuration options for changelog generation behavior.
interface Options {
/** Whether to reset the changelog or not (default: false) */
reset?: boolean;
/** Should the log be appended to existing data (default: false) */
append?: boolean;
/** How many releases of changelog you want to generate (default: 1, 0 = all) */
releaseCount?: number;
/** If true and context.version equals last release, context.version will be changed to 'Unreleased' */
outputUnreleased?: boolean;
/** A transform function that applies after the parser and before the writer */
transformCommit?: CommitTransformFunction;
/** Logger for warnings */
warn?: Logger;
/** Logger for debug messages */
debug?: Logger;
/** A function to format date */
formatDate?(date: string | Date): string;
}Usage Example:
import { ConventionalChangelog } from "conventional-changelog";
const changelog = new ConventionalChangelog()
.options({
releaseCount: 3, // Generate last 3 releases
append: false, // Prepend new content
outputUnreleased: true, // Include unreleased changes
reset: false, // Don't reset changelog
formatDate: (date) => {
return new Date(date).toLocaleDateString('en-US');
},
warn: (source, messages) => {
console.warn(`Warning from ${source}:`, messages);
},
debug: (source, messages) => {
console.debug(`Debug from ${source}:`, messages);
}
});Preset interface for bundling related configuration options.
interface Preset {
/** Parameters for getting semver tags */
tags?: GetSemverTagsParams;
/** Parameters for getting commits */
commits?: GetCommitsParams;
/** Parser options for parsing commit messages */
parser?: ParserStreamOptions;
/** Writer options for generating output */
writer?: WriterOptions;
}Custom transformation functions for modifying commit data and package information.
/**
* Function for transforming commit data during processing
* @param commit - The commit to transform
* @param params - Current generation parameters
* @returns Transformed commit, null to skip, or Promise of either
*/
type CommitTransformFunction = (
commit: Commit,
params: Params
) => Partial<Commit> | null | Promise<Partial<Commit> | null>;
/**
* Function for transforming package.json data
* @param pkg - Package data to transform
* @returns Transformed package data
*/
type PackageTransform = (pkg: Package) => Package;
/**
* Logger function for warnings and debug messages
* @param source - Source component generating the message
* @param messages - Message or array of messages
*/
type Logger = (source: string, messages: string | string[]) => void;Transform Examples:
// Commit transformation - filter and modify commits
const commitTransform: CommitTransformFunction = (commit, params) => {
// Skip certain commit types
if (commit.type === 'chore' || commit.type === 'test') {
return null;
}
// Transform commit subject
return {
...commit,
subject: commit.subject?.replace(/\s+/g, ' ').trim()
};
};
// Package transformation - modify package data
const packageTransform: PackageTransform = (pkg) => ({
...pkg,
// Override repository URL
repository: {
...pkg.repository,
url: 'https://github.com/my-org/my-repo.git'
}
});
const changelog = new ConventionalChangelog()
.options({ transformCommit: commitTransform })
.readPackage(packageTransform);The complete parameter set combining all configuration options.
interface Params extends Preset {
/** Commit retrieval parameters */
commits: GetCommitsParams;
/** Generation options */
options: Options;
/** Writer context data */
context?: Context;
/** Repository information */
repository?: Partial<HostedGitInfo> | null;
/** Package data */
package?: Package;
}Configuration for git operations and tag handling.
interface GetSemverTagsParams {
/** Tag prefix to match (e.g., 'v' for v1.0.0) */
prefix?: string;
/** Skip unstable tags (alpha, beta, rc) */
skipUnstable?: boolean;
}
interface GetCommitsParams {
/** Starting commit/tag reference */
from?: string;
/** Ending commit/tag reference */
to?: string;
/** Path to scope commits to specific directory */
path?: string;
/** Git log format string */
format?: string;
/** Whether to include merge commits */
merges?: boolean;
/** Reverse order of commits */
reverse?: boolean;
}Git Configuration Examples:
// Tag configuration
changelog.tags({
prefix: 'release-', // Match tags like 'release-1.0.0'
skipUnstable: true // Skip alpha/beta/rc tags
});
// Commit configuration
changelog.commits({
from: 'v1.0.0', // Start from specific tag
to: 'HEAD', // End at current commit
path: 'src/', // Only commits affecting src/ directory
merges: false // Exclude merge commits
});Options for parsing commit messages and extracting structured data.
interface ParserStreamOptions {
/** Keywords that identify breaking change notes */
noteKeywords?: string[];
/** Keywords that close issues */
referenceActions?: string[];
/** Prefixes for issue references */
issuePrefixes?: string[];
/** Warning logger function */
warn?: Logger;
}Parser Configuration Example:
changelog.commits({}, {
noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'],
referenceActions: ['close', 'closes', 'fix', 'fixes', 'resolve', 'resolves'],
issuePrefixes: ['#', 'gh-', 'jira-'],
warn: (messages) => console.warn('Parser warning:', messages)
});Options for controlling changelog output formatting and content.
interface WriterOptions {
/** Function to finalize context before rendering */
finalizeContext?: (context: any, options: any, commits: any, keyCommit: any, originalCommits: any) => any;
/** Whether to reverse order of output */
reverse?: boolean;
/** Whether to flush unreleased changes */
doFlush?: boolean;
/** Debug logger function */
debug?: Logger;
}Configuration for different git hosting platforms.
interface HostOptions {
/** URL pattern for issues (e.g., 'issues' for GitHub) */
issue: string;
/** URL pattern for commits (e.g., 'commit' for GitHub) */
commit: string;
/** Array of keywords that reference/close issues */
referenceActions: string[];
/** Array of prefixes for issue references */
issuePrefixes: string[];
}
type HostType = 'github' | 'gitlab' | 'bitbucket' | 'sourcehut' | '';Host Configuration Example:
// GitHub configuration (built-in)
const githubOptions: HostOptions = {
issue: 'issues',
commit: 'commit',
referenceActions: ['close', 'closes', 'closed', 'fix', 'fixes', 'fixed', 'resolve', 'resolves', 'resolved'],
issuePrefixes: ['#', 'gh-']
};const customPreset: Preset = {
tags: {
prefix: 'v',
skipUnstable: true
},
commits: {
format: '%B%n-hash-%n%H%n-gitTags-%n%d%n-committerDate-%n%ci',
merges: false
},
parser: {
noteKeywords: ['BREAKING CHANGE'],
referenceActions: ['close', 'fix'],
issuePrefixes: ['#']
},
writer: {
reverse: false,
doFlush: true
}
};
changelog.config(customPreset);const isProduction = process.env.NODE_ENV === 'production';
changelog.options({
releaseCount: isProduction ? 1 : 0, // All releases in dev, latest in prod
outputUnreleased: !isProduction, // Include unreleased only in dev
debug: isProduction ? undefined : console.debug,
warn: console.warn
});// Configure for specific package in monorepo
changelog
.readPackage(`packages/${packageName}/package.json`)
.tags({ prefix: `${packageName}@` }) // Package-specific tag prefix
.commits({ path: `packages/${packageName}/` }); // Scope to package directory