Semantic-release plugin to create or update a changelog file during the release process
npx @tessl/cli install tessl/npm-semantic-release--changelog@6.0.0@semantic-release/changelog is a semantic-release plugin that automates the creation and updating of changelog files during the release process. It integrates seamlessly with the semantic-release workflow to generate changelog entries based on commit messages and release notes.
npm install @semantic-release/changelog -Dconst { verifyConditions, prepare } = require("@semantic-release/changelog");For modern module syntax:
import { verifyConditions, prepare } from "@semantic-release/changelog";This plugin is configured as part of a semantic-release configuration file:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md",
"changelogTitle": "# Changelog"
}
],
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
]
]
}The plugin operates through semantic-release's lifecycle hooks:
Internal Architecture:
The plugin uses release notes generated by semantic-release's notes generation step and either creates a new changelog file or prepends new content to an existing one.
Validates plugin configuration options to ensure proper setup.
/**
* Validates plugin configuration during semantic-release's verify phase
* @param {PluginConfig} pluginConfig - Plugin configuration object
* @param {Context} context - Semantic-release context with options
* @returns {Promise<void>} Resolves if valid, throws AggregateError if invalid
*/
async function verifyConditions(pluginConfig, context): Promise<void>;Creates or updates changelog files with release notes.
/**
* Creates or updates changelog file during semantic-release's prepare phase
* @param {PluginConfig} pluginConfig - Plugin configuration object
* @param {PrepareContext} context - Semantic-release context with cwd, nextRelease.notes, and logger
* @returns {Promise<void>} Resolves when changelog is updated
*/
async function prepare(pluginConfig, context): Promise<void>;/**
* Plugin configuration object
*/
interface PluginConfig {
/** Path to changelog file (default: "CHANGELOG.md") */
changelogFile?: string;
/** Title to place at top of changelog file */
changelogTitle?: string;
}
/**
* Semantic-release context object for verifyConditions
*/
interface Context {
/** Release options from semantic-release configuration */
options: {
/** Prepare plugin configurations */
prepare?: Array<string | PluginConfig>;
};
}
/**
* Semantic-release context object for prepare phase
*/
interface PrepareContext {
/** Current working directory */
cwd: string;
/** Next release information */
nextRelease: {
/** Generated release notes content */
notes: string;
};
/** Semantic-release logger */
logger: {
/** Log informational messages */
log(message: string, ...args: any[]): void;
};
}
/**
* Semantic-release error type
*/
interface SemanticReleaseError extends Error {
/** Error code identifier */
code: string;
/** Additional error details */
details?: string;
}
/**
* Aggregate error containing multiple validation errors
*/
interface AggregateError extends Error {
/** Array of individual errors */
errors: SemanticReleaseError[];
}string"CHANGELOG.md"Example:
{
"changelogFile": "docs/CHANGELOG.md"
}stringundefinedExample:
{
"changelogTitle": "# Changelog\\n\\nAll notable changes to this project will be documented in this file."
}The plugin throws SemanticReleaseError instances for configuration validation failures. Multiple validation errors are collected and thrown as an AggregateError.
EINVALIDCHANGELOGFILE: When changelogFile is provided but is not a non-empty string
{
message: "Invalid `changelogFile` option.",
details: "The changelogFile option, if defined, must be a non empty String.\n\nYour configuration for the `changelogFile` option is `${changelogFile}`."
}EINVALIDCHANGELOGTITLE: When changelogTitle is provided but is not a non-empty string
{
message: "Invalid `changelogTitle` option.",
details: "The changelogTitle option, if defined, must be a non empty String.\n\nYour configuration for the `changelogTitle` option is `${changelogTitle}`."
}The plugin validates configuration using these rules:
changelogFile: Must be a non-empty string if provided (defaults to "CHANGELOG.md")changelogTitle: Must be a non-empty string if provided (optional)/**
* Configuration resolution with defaults
* @param {PluginConfig} pluginConfig - Raw plugin configuration
* @returns {ResolvedConfig} Configuration with defaults applied
*/
interface ResolvedConfig {
changelogFile: string; // defaults to "CHANGELOG.md"
changelogTitle?: string;
}
/**
* Configuration validators
*/
const VALIDATORS = {
changelogFile: (value) => isString(value) && value.trim(),
changelogTitle: (value) => isString(value) && value.trim(),
};The changelog plugin must run before @semantic-release/git to include changelog changes in commits:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\\n\\n${nextRelease.notes}"
}
]
]
}Similarly, changelog must run before npm publication:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/git"
]
}Configuration can be shared between changelog and git plugins:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "docs/CHANGELOG.md"
}
],
[
"@semantic-release/git",
{
"assets": ["docs/CHANGELOG.md"]
}
]
]
}changelogTitle is configured and the file starts with that title, the title is preserved and content is inserted after it