Core changelog generation functions providing multiple output formats for different integration scenarios. These functions transform commit data into formatted changelog entries using Handlebars templates.
Creates an async generator function to generate changelog entries from commits. This is the most flexible output format, ideal for streaming scenarios or when you need to process changelog entries one by one.
/**
* Creates an async generator function to generate changelog entries from commits.
* @param context - Context for changelog template with repository and version information
* @param options - Options for changelog template including transforms and sorting
* @param includeDetails - Whether to yield details object instead of changelog entry
* @returns Function that takes commits and returns AsyncGenerator
*/
function writeChangelog<Commit extends CommitKnownProps = CommitKnownProps>(
context?: Context<Commit>,
options?: Options<Commit>,
includeDetails?: false
): (commits: Iterable<Commit> | AsyncIterable<Commit>) => AsyncGenerator<string, void>;
function writeChangelog<Commit extends CommitKnownProps = CommitKnownProps>(
context: Context<Commit>,
options: Options<Commit>,
includeDetails: true
): (commits: Iterable<Commit> | AsyncIterable<Commit>) => AsyncGenerator<Details<Commit>, void>;Usage Examples:
import { writeChangelog, type CommitKnownProps } from "conventional-changelog-writer";
const commits: CommitKnownProps[] = [
{
hash: "abc123",
header: "feat: add new feature",
type: "feat",
version: "1.0.0",
committerDate: "2023-01-15",
notes: [],
body: null,
footer: null
}
];
// Basic usage - returns string chunks
const generator = writeChangelog();
for await (const chunk of generator(commits)) {
console.log(chunk); // Formatted changelog string
}
// With context and options
const context = {
version: "1.0.0",
date: "2023-01-15",
repository: "my-repo",
host: "https://github.com"
};
const options = {
groupBy: "type" as const,
commitsSort: "header" as const
};
const generatorWithConfig = writeChangelog(context, options);
for await (const chunk of generatorWithConfig(commits)) {
console.log(chunk);
}
// Include details (returns Details objects instead of strings)
const detailsGenerator = writeChangelog(context, options, true);
for await (const details of detailsGenerator(commits)) {
console.log(details.log); // The changelog string
console.log(details.keyCommit); // The key commit for this block
}Create a changelog string from commits. This is the simplest API for generating a complete changelog as a single string.
/**
* Create a changelog string from commits.
* @param commits - Commits to generate changelog from
* @param context - Context for changelog template
* @param options - Options for changelog template
* @returns Promise resolving to complete changelog string
*/
function writeChangelogString<Commit extends CommitKnownProps = CommitKnownProps>(
commits: Iterable<Commit> | AsyncIterable<Commit>,
context?: Context<Commit>,
options?: Options<Commit>
): Promise<string>;Usage Example:
import { writeChangelogString, type CommitKnownProps } from "conventional-changelog-writer";
const commits: CommitKnownProps[] = [
{
hash: "abc123",
header: "feat: add authentication",
type: "feat",
version: "1.1.0",
committerDate: "2023-02-01",
notes: [{ title: "BREAKING CHANGE", text: "API endpoint changed" }],
body: "Added OAuth2 support",
footer: "Closes #123"
},
{
hash: "def456",
header: "fix: resolve memory leak",
type: "fix",
version: null,
committerDate: "2023-02-02",
notes: [],
body: null,
footer: null
}
];
// Generate complete changelog
const changelog = await writeChangelogString(commits);
console.log(changelog);
// With configuration
const context = {
version: "1.1.0",
date: "2023-02-02",
repository: "my-app",
host: "https://github.com",
owner: "myorg"
};
const options = {
groupBy: "type" as const,
commitsSort: ["scope", "subject"] as const,
transform: (commit) => ({
...commit,
shortHash: commit.hash?.substring(0, 7)
})
};
const formattedChangelog = await writeChangelogString(commits, context, options);
console.log(formattedChangelog);Creates a transform stream which takes commits and outputs changelog entries. Perfect for Node.js streaming scenarios and pipeline integration.
/**
* Creates a transform stream which takes commits and outputs changelog entries.
* @param context - Context for changelog template
* @param options - Options for changelog template
* @param includeDetails - Whether to emit details object instead of changelog entry
* @returns Transform stream for pipeline usage
*/
function writeChangelogStream<Commit extends CommitKnownProps = CommitKnownProps>(
context?: Context<Commit>,
options?: Options<Commit>,
includeDetails?: boolean
): Transform;Note: Transform is imported from Node.js stream module:
import { Transform } from "stream";Usage Examples:
import { writeChangelogStream } from "conventional-changelog-writer";
import { pipeline } from "stream/promises";
import { createReadStream } from "fs";
// Basic stream usage
const changelogStream = writeChangelogStream();
commitsReadableStream
.pipe(changelogStream)
.pipe(process.stdout);
// With pipeline
await pipeline(
commitsAsyncIterable,
writeChangelogStream(context, options),
process.stdout
);
// Stream commits from file and output to file
import { createReadStream, createWriteStream } from "fs";
import { Transform } from "stream";
// Parse NDJSON commits
const parseCommits = new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n').filter(Boolean);
for (const line of lines) {
try {
this.push(JSON.parse(line));
} catch (err) {
// Skip invalid JSON
}
}
callback();
}
});
await pipeline(
createReadStream('commits.ndjson'),
parseCommits,
writeChangelogStream(context, options),
createWriteStream('CHANGELOG.md')
);The package includes a CLI that uses these writer functions:
# Process commits from file
conventional-changelog-writer commits.ldjson
# Process from stdin
cat commits.ldjson | conventional-changelog-writer
# With context and options files
conventional-changelog-writer -c context.json -o options.js commits.ldjsonimport { pipeline } from "stream/promises";
import { writeChangelogStream } from "conventional-changelog-writer";
// Complex processing pipeline
await pipeline(
commitsSource,
// Filter commits
new Transform({
objectMode: true,
transform(commit, encoding, callback) {
if (commit.type === 'feat' || commit.type === 'fix') {
callback(null, commit);
} else {
callback();
}
}
}),
// Generate changelog
writeChangelogStream(context, options),
// Post-process output
new Transform({
transform(chunk, encoding, callback) {
// Add custom headers or formatting
callback(null, chunk);
}
}),
outputDestination
);import { writeChangelogString } from "conventional-changelog-writer";
try {
const changelog = await writeChangelogString(commits, context, options);
console.log(changelog);
} catch (error) {
if (error.message.includes('template')) {
console.error('Template rendering error:', error);
} else if (error.message.includes('transform')) {
console.error('Commit transformation error:', error);
} else {
console.error('Unexpected error:', error);
}
}