Semantic-release plugin to generate changelog content with conventional-changelog
npx @tessl/cli install tessl/npm-semantic-release--release-notes-generator@14.0.0A semantic-release plugin that generates changelog content using conventional-changelog. This plugin analyzes commit messages following conventional commit standards and produces formatted release notes for software releases.
npm install @semantic-release/release-notes-generatorimport { generateNotes } from "@semantic-release/release-notes-generator";
import loadChangelogConfig from "@semantic-release/release-notes-generator/lib/load-changelog-config.js";
import HOSTS_CONFIG from "@semantic-release/release-notes-generator/lib/hosts-config.js";For CommonJS:
const { generateNotes } = require("@semantic-release/release-notes-generator");
const loadChangelogConfig = require("@semantic-release/release-notes-generator/lib/load-changelog-config.js").default;
const HOSTS_CONFIG = require("@semantic-release/release-notes-generator/lib/hosts-config.js").default;This plugin is designed to be used within the semantic-release ecosystem:
{
"plugins": [
"@semantic-release/commit-analyzer",
[
"@semantic-release/release-notes-generator",
{
"preset": "angular",
"parserOpts": {
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"]
},
"writerOpts": {
"commitsSort": ["subject", "scope"]
}
}
]
]
}Direct programmatic usage:
import { generateNotes } from "@semantic-release/release-notes-generator";
const pluginConfig = {
preset: "angular",
parserOpts: {},
writerOpts: {}
};
const context = {
commits: [
{ hash: "abc123", message: "feat(auth): add login functionality" },
{ hash: "def456", message: "fix(ui): correct button alignment" }
],
lastRelease: { gitTag: "v1.0.0" },
nextRelease: { gitTag: "v2.0.0", version: "2.0.0" },
options: { repositoryUrl: "https://github.com/owner/repo" },
cwd: process.cwd()
};
const changelog = await generateNotes(pluginConfig, context);
console.log(changelog);The plugin operates through several key components:
generateNotes processes commits and generates changelog contentThe primary functionality for generating changelog content from commits.
/**
* Generate the changelog for all the commits in context.commits
* @param {Object} pluginConfig - The plugin configuration
* @param {String} [pluginConfig.preset] - conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint')
* @param {String} [pluginConfig.config] - Requireable npm package with a custom conventional-changelog preset
* @param {Object} [pluginConfig.parserOpts] - Additional conventional-changelog-parser options that will overwrite ones loaded by preset or config
* @param {Object} [pluginConfig.writerOpts] - Additional conventional-changelog-writer options that will overwrite ones loaded by preset or config
* @param {Object} [pluginConfig.presetConfig] - Configuration for the preset
* @param {Object} [pluginConfig.host] - Host configuration overrides
* @param {Boolean} [pluginConfig.linkCompare] - Enable/disable compare links
* @param {Boolean} [pluginConfig.linkReferences] - Enable/disable reference links
* @param {Object} [pluginConfig.commit] - Commit configuration overrides
* @param {Object} [pluginConfig.issue] - Issue configuration overrides
* @param {Object} context - The semantic-release context
* @param {Array<Object>} context.commits - The commits to analyze
* @param {Object} context.lastRelease - The last release with gitHead and gitTag
* @param {Object} context.nextRelease - The next release with gitHead, version, and gitTag
* @param {Object} context.options - Contains repositoryUrl and other options
* @param {String} context.cwd - Current working directory
* @returns {Promise<String>} The changelog content as HTML/markdown string
*/
async function generateNotes(pluginConfig, context);Internal function for loading conventional-changelog configuration from presets or custom packages.
/**
* Load conventional-changelog-parser options. Handle presets that return either a Promise<Array> or a Promise<Function>
* @param {Object} pluginConfig - The plugin configuration
* @param {String} [pluginConfig.preset] - conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint')
* @param {String} [pluginConfig.config] - Requireable npm package with a custom conventional-changelog preset
* @param {Object} [pluginConfig.parserOpts] - Additional conventional-changelog-parser options that will overwrite ones loaded by preset or config
* @param {Object} [pluginConfig.writerOpts] - Additional conventional-changelog-writer options that will overwrite ones loaded by preset or config
* @param {Object} [pluginConfig.presetConfig] - Configuration for the preset
* @param {Object} context - The semantic-release context
* @param {Array<Object>} context.commits - The commits to analyze
* @param {String} context.cwd - The current working directory
* @returns {Promise<Object>} A Promise that resolves to the conventional-changelog-core config with parserOpts and writerOpts
*/
async function loadChangelogConfig(pluginConfig, context);Pre-defined host configurations for popular Git hosting platforms.
/**
* Host configurations for different Git hosting platforms
*/
const HOSTS_CONFIG = {
github: {
hostname: "github.com",
issue: "issues",
commit: "commit",
referenceActions: ["close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"],
issuePrefixes: ["#", "gh-"]
},
bitbucket: {
hostname: "bitbucket.org",
issue: "issue",
commit: "commits",
referenceActions: ["close", "closes", "closed", "closing", "fix", "fixes", "fixed", "fixing", "resolve", "resolves", "resolved", "resolving"],
issuePrefixes: ["#"]
},
gitlab: {
hostname: "gitlab.com",
issue: "issues",
commit: "commit",
referenceActions: ["close", "closes", "closed", "closing", "fix", "fixes", "fixed", "fixing"],
issuePrefixes: ["#"]
},
default: {
issue: "issues",
commit: "commit",
referenceActions: ["close", "closes", "closed", "closing", "fix", "fixes", "fixed", "fixing", "resolve", "resolves", "resolved", "resolving"],
issuePrefixes: ["#", "gh-"]
}
};Configuration structures used by the plugin.
interface PluginConfig {
/** Conventional-changelog preset name */
preset?: "angular" | "atom" | "codemirror" | "ember" | "eslint" | "express" | "jquery" | "jscs" | "jshint";
/** Custom conventional-changelog preset package name */
config?: string;
/** Additional parser options */
parserOpts?: {
/** Keywords that indicate breaking changes */
noteKeywords?: string[];
/** Other parser configuration options */
[key: string]: any;
};
/** Additional writer options */
writerOpts?: {
/** Sort order for commits */
commitsSort?: string[];
/** Other writer configuration options */
[key: string]: any;
};
/** Configuration for the preset */
presetConfig?: Record<string, any>;
/** Host configuration overrides */
host?: Record<string, any>;
/** Enable/disable compare links */
linkCompare?: boolean;
/** Enable/disable reference links */
linkReferences?: boolean;
/** Commit configuration overrides */
commit?: Record<string, any>;
/** Issue configuration overrides */
issue?: Record<string, any>;
}
interface SemanticReleaseContext {
/** Array of commit objects to analyze */
commits: Array<{
/** Commit hash */
hash: string;
/** Commit message */
message: string;
/** Author information with name, email, and date */
author?: {
name?: string;
email?: string;
date?: string;
};
/** Committer information with name, email, and date */
committer?: {
name?: string;
email?: string;
date?: string;
};
/** Parsed commit type (feat, fix, etc.) - added by conventional-commits-parser */
type?: string;
/** Parsed commit scope - added by conventional-commits-parser */
scope?: string;
/** Parsed commit subject - added by conventional-commits-parser */
subject?: string;
/** Parsed commit body - added by conventional-commits-parser */
body?: string;
/** Parsed commit footer - added by conventional-commits-parser */
footer?: string;
/** Breaking change notes - added by conventional-commits-parser */
notes?: Array<{
title: string;
text: string;
}>;
/** Issue references - added by conventional-commits-parser */
references?: Array<{
action?: string;
owner?: string;
repository?: string;
issue: string;
raw: string;
prefix: string;
}>;
/** Whether this is a revert commit - added by conventional-commits-parser */
revert?: Record<string, any> | null;
/** Other commit properties */
[key: string]: any;
}>;
/** Last release information */
lastRelease: {
/** Git commit hash of last release */
gitHead?: string;
/** Git tag of last release */
gitTag?: string;
/** Version of last release */
version?: string;
};
/** Next release information */
nextRelease: {
/** Git commit hash of next release */
gitHead?: string;
/** Git tag of next release */
gitTag?: string;
/** Version of next release */
version: string;
};
/** Semantic-release options */
options: {
/** Repository URL */
repositoryUrl: string;
/** Other semantic-release options */
[key: string]: any;
};
/** Current working directory */
cwd: string;
}Platform-specific configuration for different Git hosting services.
interface HostConfig {
/** Platform hostname */
hostname: string;
/** Issue path segment for URLs */
issue: string;
/** Commit path segment for URLs */
commit: string;
/** Keywords that reference/close issues */
referenceActions: string[];
/** Prefixes that indicate issue references */
issuePrefixes: string[];
}
interface HostsConfiguration {
github: HostConfig;
bitbucket: HostConfig;
gitlab: HostConfig;
default: HostConfig;
}Internal wrapper modules that provide compatibility with conventional-changelog packages.
/**
* Wrapper for conventional-changelog-writer that exports the writeChangelogStream function
* Located at: wrappers/conventional-changelog-writer.js
*/
import { writeChangelogStream as writer } from 'conventional-changelog-writer';
export default writer;{
"preset": "angular",
"parserOpts": {
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"]
},
"writerOpts": {
"commitsSort": ["subject", "scope"]
}
}{
"config": "conventional-changelog-eslint",
"parserOpts": {
"headerPattern": "/^(\\w*)(?:\\(([\\w\\$\\.\\-\\* ]*)\\))?: (.*)$/",
"headerCorrespondence": ["type", "scope", "subject"]
}
}{
"preset": "angular",
"host": "https://custom-git-host.com",
"linkCompare": true,
"linkReferences": true,
"commit": {
"linkPath": "commits"
},
"issue": {
"linkPath": "issues"
}
}The plugin handles various error scenarios:
Common issues:
repositoryUrl is properly formattedhash and message propertieslastRelease and nextRelease objects have appropriate properties