Configuration interfaces for controlling changelog generation behavior, including commit grouping, sorting, template customization, and repository metadata. These provide comprehensive control over the changelog generation process.
Context provides template variables and repository metadata for changelog generation. It includes version information, repository details, and linking configuration.
/**
* Context for changelog template containing metadata and repository information.
*/
interface Context<Commit extends CommitKnownProps = CommitKnownProps> {
/** Version number of the up-coming release */
version?: string;
/** Is this a patch release? */
isPatch?: boolean;
/** The title of the release */
title?: string;
/** The release date */
date?: string;
/** Should all references be linked? */
linkReferences?: boolean;
/** Commit base url path */
commit?: string;
/** Issue base url */
issue?: string;
/** Repository name (e.g., 'conventional-changelog-writer') */
repository?: string;
/** Repository host (e.g., 'https://github.com' or 'https://bitbucket.org') */
host?: string;
/** Repository owner (e.g., 'conventional-changelog') */
owner?: string;
/** Full repository url (fallback when repository doesn't exist) */
repoUrl?: string;
/** Commit groups for template rendering */
commitGroups?: CommitGroup<Commit>[];
/** Note groups for template rendering */
noteGroups?: NoteGroup[];
/** Add a link to compare changes */
linkCompare?: boolean;
}Usage Examples:
import { writeChangelogString, type Context } from "conventional-changelog-writer";
// Basic context
const basicContext: Context = {
version: "1.2.0",
date: "2023-01-15",
repository: "my-awesome-package",
host: "https://github.com",
owner: "myorg"
};
// Complete context with all options
const fullContext: Context = {
version: "2.0.0",
isPatch: false,
title: "Major Release",
date: "2023-02-01",
linkReferences: true,
commit: "commit",
issue: "issues",
repository: "my-package",
host: "https://github.com",
owner: "mycompany",
repoUrl: "https://github.com/mycompany/my-package",
linkCompare: true
};
const changelog = await writeChangelogString(commits, fullContext);
// Context with dynamic values
const dynamicContext: Context = {
version: process.env.PACKAGE_VERSION || "0.0.0",
date: new Date().toISOString().split('T')[0],
repository: process.env.GITHUB_REPOSITORY?.split('/')[1],
host: "https://github.com",
owner: process.env.GITHUB_REPOSITORY?.split('/')[0],
linkReferences: process.env.NODE_ENV === "production"
};Comprehensive configuration for changelog generation including sorting, grouping, transformation, and template customization.
/**
* Options for controlling changelog generation behavior.
*/
interface Options<Commit extends CommitKnownProps = CommitKnownProps> extends TemplatesOptions {
/** Key to group commits by (if falsy, commits are not grouped) */
groupBy?: keyof Commit;
/** Key to sort commits by or sort function (if falsy, commits are not sorted) */
commitsSort?: SortBy<Commit>;
/** Key to sort commit groups by or sort function (if falsy, commit groups are not sorted) */
commitGroupsSort?: SortBy<CommitGroup<Commit>>;
/** Key to sort notes by or sort function (if falsy, notes are not sorted) */
notesSort?: SortBy<CommitNote>;
/** Key to sort note groups by or sort function (if falsy, note groups are not sorted) */
noteGroupsSort?: SortBy<NoteGroup>;
/** If true, reverted commits will be ignored */
ignoreReverted?: boolean;
/** Reverse chronological order (true) vs chronological order (false) */
reverse?: boolean;
/** If true, the stream will flush out the last bit of commits to changelog */
doFlush?: boolean;
/** Function to transform commits - returns diff object merged with original */
transform?: CommitTransformFunction<Commit>;
/** Function or key to detect whether a changelog block should be generated */
generateOn?: GenerateOnFunction<Commit> | keyof Commit | null;
/** Last chance to modify context before generating changelog */
finalizeContext?(
context: FinalContext<Commit>,
options: FinalOptions<Commit>,
filteredCommits: Commit[],
keyCommit: Commit | null,
commits: Commit[]
): FinalContext<Commit> | Promise<FinalContext<Commit>>;
/** Function to get debug information */
debug?(message: string): void;
/** Function to format date */
formatDate?(date: string | Date): string;
/** Function to determine if a commit should be skipped */
skip?(commit: Commit): boolean;
}Usage Examples:
import {
writeChangelogString,
defaultCommitTransform,
formatDate,
type Options,
type CommitKnownProps
} from "conventional-changelog-writer";
// Basic options
const basicOptions: Options = {
groupBy: "type",
commitsSort: "header",
ignoreReverted: true
};
// Advanced sorting options
const advancedOptions: Options = {
groupBy: "type",
commitsSort: ["scope", "subject"], // Multi-field sorting
commitGroupsSort: "title",
notesSort: "text",
noteGroupsSort: "title",
reverse: false,
ignoreReverted: true,
doFlush: true
};
// Custom transformation options
const transformOptions: Options = {
groupBy: "type",
transform: (commit, context, options) => {
// Custom transformation logic
const patch: Partial<CommitKnownProps> = {
hash: commit.hash?.substring(0, 7),
header: commit.header?.replace(/\s+/g, ' ').trim()
};
// Add custom fields
if (commit.type === 'feat') {
patch.priority = 'high';
}
return patch;
},
formatDate: (date) => new Date(date).toLocaleDateString('en-US'),
skip: (commit) => commit.type === 'chore' || commit.type === 'style'
};
// Generate on specific conditions
const generateOptions: Options = {
groupBy: "type",
generateOn: (keyCommit, commitsGroup, context, options) => {
// Generate changelog block when we hit a version tag
return Boolean(keyCommit.version && semver.valid(keyCommit.version));
},
finalizeContext: async (context, options, filteredCommits, keyCommit, commits) => {
// Add custom context processing
return {
...context,
totalCommits: commits.length,
featuresCount: filteredCommits.filter(c => c.type === 'feat').length,
fixesCount: filteredCommits.filter(c => c.type === 'fix').length
};
}
};
// Debug and development options
const debugOptions: Options = {
groupBy: "type",
debug: (message) => {
if (process.env.NODE_ENV === 'development') {
console.log(`[Changelog Debug]: ${message}`);
}
},
transform: defaultCommitTransform,
formatDate: formatDate
};
const changelog = await writeChangelogString(commits, context, debugOptions);Configuration for Handlebars template customization, including main template and partial templates.
/**
* Options for customizing Handlebars templates.
*/
interface TemplatesOptions {
/** Main template for the changelog */
mainTemplate?: string;
/** Header partial template */
headerPartial?: string;
/** Commit partial template */
commitPartial?: string;
/** Footer partial template */
footerPartial?: string;
/** Additional custom partials */
partials?: Record<string, string | null>;
}Usage Examples:
import { writeChangelogString, type TemplatesOptions } from "conventional-changelog-writer";
// Custom templates
const customTemplates: TemplatesOptions = {
mainTemplate: `
{{> header}}
{{#each commitGroups}}
{{#if title}}
## {{title}}
{{/if}}
{{#each commits}}
{{> commit}}
{{/each}}
{{/each}}
{{> footer}}
`.trim(),
headerPartial: `
# Changelog
{{#if version}}
## [{{version}}]{{#if date}} - {{date}}{{/if}}
{{/if}}
`.trim(),
commitPartial: `
* {{#if scope}}**{{scope}}:** {{/if}}{{subject}}{{#if hash}} ([{{hash}}]({{commit}}/{{hash}})){{/if}}
{{#if body}}
{{body}}
{{/if}}
`.trim(),
footerPartial: `
{{#if noteGroups}}
{{#each noteGroups}}
### {{title}}
{{#each notes}}
* {{text}}
{{/each}}
{{/each}}
{{/if}}
`.trim(),
partials: {
customHeader: '<h1 class="changelog-title">{{title}}</h1>',
customFooter: '<footer>Generated on {{date}}</footer>'
}
};
const options = {
groupBy: "type" as const,
...customTemplates
};
const changelog = await writeChangelogString(commits, context, options);Type definition for commit transformation functions.
type CommitTransformFunction<Commit extends CommitKnownProps = CommitKnownProps> =
(
commit: Commit,
context: FinalContext<Commit>,
options: FinalOptions<Commit>
) => Partial<Commit> | null | Promise<Partial<Commit> | null>;Type definition for functions that determine when to generate changelog blocks.
type GenerateOnFunction<Commit extends CommitKnownProps = CommitKnownProps> =
(
keyCommit: Commit,
commitsGroup: Commit[],
context: FinalContext<Commit>,
options: FinalOptions<Commit>
) => boolean;Type definition for sorting specifications.
type SortBy<T> = PickStringsKeys<T> | PickStringsKeys<T>[] | Comparator<T>;import { Options, Context } from "conventional-changelog-writer";
// Environment-based configuration
const createOptions = (env: string): Options => {
const baseOptions: Options = {
groupBy: "type",
commitsSort: "header",
ignoreReverted: true
};
if (env === 'production') {
return {
...baseOptions,
transform: defaultCommitTransform,
debug: () => {}, // No debug in production
skip: (commit) => commit.type === 'test' || commit.type === 'chore'
};
}
return {
...baseOptions,
debug: console.log,
formatDate: (date) => `DEBUG: ${new Date(date).toISOString()}`
};
};
// Feature-flag based configuration
const createContext = (features: { linkReferences: boolean, compareLinks: boolean }): Context => ({
version: "1.0.0",
date: new Date().toISOString().split('T')[0],
repository: "my-package",
host: "https://github.com",
owner: "myorg",
linkReferences: features.linkReferences,
linkCompare: features.compareLinks
});interface RepoConfig {
name: string;
host: string;
owner: string;
customTemplates?: TemplatesOptions;
}
const repoConfigs: Record<string, RepoConfig> = {
github: {
name: "my-package",
host: "https://github.com",
owner: "myorg",
customTemplates: {
commitPartial: "* {{subject}} ([{{hash}}]({{host}}/{{owner}}/{{repository}}/commit/{{hash}}))"
}
},
gitlab: {
name: "my-package",
host: "https://gitlab.com",
owner: "myorg",
customTemplates: {
commitPartial: "* {{subject}} ([{{hash}}]({{host}}/{{owner}}/{{repository}}/-/commit/{{hash}}))"
}
}
};
function createRepoContext(repoType: keyof typeof repoConfigs): Context & Options {
const config = repoConfigs[repoType];
return {
// Context
repository: config.name,
host: config.host,
owner: config.owner,
linkReferences: true,
// Options
groupBy: "type",
...config.customTemplates
};
}