A TypeScript-based changelog management tool that works both as a GitHub Action and CLI tool. This is inspired by the Jetpack Changelogger but implemented in TypeScript and designed to work seamlessly with GitHub Actions.
- Manage changelog entries through individual change files
- Interactive CLI for adding changelog entries
- GitHub Action support for CI/CD integration
- Configurable through package.json
- Supports semantic versioning
- Validates change files format and content
- Automatically generates well-formatted changelog entries
- Multiple writing strategies (Keep a Changelog, StellarWP formats)
- Multiple versioning strategies (SemVer, StellarWP)
npm install @stellarwp/changelogger
# Add a new changelog entry
npm run changelog add
# Validate all change files
npm run changelog validate
# Write changes to CHANGELOG.md
npm run changelog write
Adds a new changelog entry to the project. Can be used in interactive or non-interactive mode.
# Interactive mode - prompts for all required information
npm run changelog add
# Non-interactive mode - provide all options directly
npm run changelog add -- --significance minor --type feature --entry "Added new feature X"
# Non-interactive mode with auto-generated filename
npm run changelog add -- --significance minor --type feature --entry "Added new feature X" --auto-filename
Options:
--significance
: The significance of the change (patch, minor, major)--type
: The type of change (e.g., feature, fix, enhancement)--entry
: The changelog entry text--filename
: The desired filename for the changelog entry (optional)--auto-filename
: Automatically generate the filename based on branch name or timestamp (optional)
The command will:
- Create a new YAML file in the configured changes directory
- Generate a filename based on the branch name or timestamp
- Handle duplicate filenames by appending a timestamp
- Validate all inputs before creating the file
When using --auto-filename
:
- The filename will be automatically generated from the current git branch name (if available)
- If no branch name is available, a timestamp-based filename will be used
- The filename prompt will be skipped
Validates all changelog entries in the changes directory.
npm run changelog validate
This command performs the following checks:
- Validates YAML format of all change files
- Ensures required fields are present
- Verifies significance values (patch, minor, or major)
- Validates type values against configuration
- Ensures non-patch changes have an entry description
Writes changelog entries to the configured files.
# Automatic versioning
npm run changelog write
# Manual versioning
npm run changelog write -- --overwrite-version 1.2.3
# Dry run - show what would be written without making changes
npm run changelog write -- --dry-run
# Specify a custom date (supports PHP strtotime format)
npm run changelog write -- --date "2024-03-20"
npm run changelog write -- --date "yesterday"
npm run changelog write -- --date "last monday"
Options:
--overwrite-version
: Optional version number to use instead of auto-determining--dry-run
: If true, only show what would be written without making changes--date
: Custom date to use for the changelog entry (supports PHP strtotime format)
The command will:
- Read all YAML change files from the changes directory
- Determine the next version number based on change significance (if not specified)
- Write the changes to each configured file using its specific writing strategy
- Clean up processed change files
When using --dry-run
:
- Shows what would be written to each configured file
- Displays the formatted changelog entries
- No changes are actually made to any files
When using --overwrite-version
:
- Uses the specified version instead of auto-determining
- If the version exists in the changelog, new changes are appended to that version
- If the version doesn't exist, a new version entry is created
When using --date
:
- Uses the specified date for the changelog entry
- Supports PHP strtotime format for flexible date specification
- Examples:
--date "2024-03-20"
- Specific date--date "yesterday"
- Relative date--date "last monday"
- Relative date--date "next friday"
- Relative date
- If not specified, uses the current date
The command supports multiple output files with different writing strategies:
- Keep a Changelog format
- StellarWP changelog format
- StellarWP readme format
- Custom writing strategies
Each file is processed according to its configured strategy and the changes are written in the appropriate format.
import {
addCommand,
validateCommand,
writeCommand,
writingStrategies,
versioningStrategies,
loadConfig,
loadWritingStrategy,
loadVersioningStrategy,
WritingStrategy,
VersioningStrategy,
} from "@stellarwp/changelogger";
// Use built-in writing strategies
const keepachangelog = writingStrategies.keepachangelog;
const stellarwpChangelog = writingStrategies.stellarwpChangelog;
const stellarwpReadme = writingStrategies.stellarwpReadme;
// Use built-in versioning strategies
const semver = versioningStrategies.semverStrategy;
const stellarwp = versioningStrategies.stellarStrategy;
// Load custom strategies
const customWritingStrategy = await loadWritingStrategy("./path/to/custom-writing.ts");
const customVersioningStrategy = await loadVersioningStrategy("./path/to/custom-versioning.ts");
name: Verify changelog Entry.
on:
pull_request:
types: [opened, synchronize]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: stellarwp/changelogger@main
with:
command: validate
Configure the changelogger through your package.json:
{
"changelogger": {
"changelogFile": "CHANGELOG.md",
"changesDir": "changelog",
"linkTemplate": "https://github.com/owner/repo/compare/${old}...${new}",
"ordering": ["type", "content"],
"types": {
"added": "Added",
"changed": "Changed",
"deprecated": "Deprecated",
"removed": "Removed",
"fixed": "Fixed",
"security": "Security"
},
"versioning": "semver",
"files": [
{
"path": "CHANGELOG.md",
"strategy": "keepachangelog"
},
{
"path": "readme.txt",
"strategy": "stellarwp-readme"
}
]
}
}
The changelogger supports multiple versioning strategies:
-
semver (default): Standard semantic versioning (major.minor.patch)
{ "changelogger": { "versioning": "semver" } }
-
stellarwp: StellarWP versioning with hotfix support (major.minor.patch[.hotfix])
- Supports 3-part versions:
1.2.3
- Supports 4-part versions with hotfix:
1.2.3.4
- Hotfix number only appears when greater than 0
- Version handling:
major
: Increments major, resets others (1.2.3.4 → 2.0.0)minor
: Increments minor, resets patch/hotfix (1.2.3.4 → 1.3.0)patch
:- With hotfix: Increments hotfix (1.2.3.4 → 1.2.3.5)
- Without hotfix: Increments patch (1.2.3 → 1.2.4)
{ "changelogger": { "versioning": "stellarwp" } }
- Supports 3-part versions:
-
Custom Versioning: You can provide a path to a JavaScript file that implements the versioning strategy:
{ "changelogger": { "versioning": "./path/to/custom-versioning.js" } }
The custom versioning file must export these functions:
export function getNextVersion(currentVersion: string, significance: "major" | "minor" | "patch"): string; export function isValidVersion(version: string): boolean; export function compareVersions(v1: string, v2: string): number;
The changelogger supports multiple writing strategies that can be configured per file in your package.json:
{
"changelogger": {
"files": [
{
"path": "CHANGELOG.md",
"strategy": "keepachangelog"
},
{
"path": "readme.txt",
"strategy": "stellarwp-readme"
}
]
}
}
Available built-in strategies:
-
keepachangelog: Follows the Keep a Changelog format
Example output:
## [1.2.3] - 2024-03-22 ### Added - New feature description ### Fixed - Bug fix description [1.2.3]: https://github.com/owner/repo/compare/1.2.2...1.2.3
-
stellarwp-changelog: A WordPress-style changelog format
Example output:
### [1.2.3] 2024-03-22 - Feature - Added new feature - Fix - Fixed a bug
-
stellarwp-readme: Updates readme.txt in WordPress plugin format
Example output:
== Changelog == = [1.2.3] 2024-03-22 = * Feature - Added new feature * Fix - Fixed a bug
-
Custom Writing: You can provide a path to a JavaScript file that implements the writing strategy:
{ "changelogger": { "files": [ { "path": "CHANGELOG.md", "strategy": "./path/to/custom-writing.js" } ] } }
The custom writing file must implement the WritingStrategy interface:
interface WritingStrategy { /** * Format the changes into a changelog entry */ formatChanges(version: string, changes: Array<{ type: string; entry: string }>, previousVersion?: string): string; /** * Format the header for a new version */ formatVersionHeader(version: string, date: string, previousVersion?: string): string; /** * Optional: Format version comparison links */ formatVersionLink?(version: string, previousVersion: string, template?: string): string; }
Example custom writing strategy:
// custom-writing.ts import * as fs from "fs/promises"; import * as path from "path"; import { WritingStrategy } from "@stellarwp/changelogger"; const customStrategy: WritingStrategy = { formatChanges(version, changes) { return changes.map(change => `- [${change.type.toUpperCase()}] ${change.entry}`).join("\n"); }, formatVersionHeader(version, date) { return `# Version ${version} (${date})`; }, formatVersionLink(version, previousVersion, template) { if (!template) return ""; return `Compare: ${template.replace("${old}", previousVersion).replace("${new}", version)}`; }, }; export default customStrategy;
Example output:
# Version 1.2.3 (2024-03-22) - [ADDED] New feature description - [FIXED] Bug fix description Compare: https://github.com/owner/repo/compare/1.2.2...1.2.3
When adding new changelog entries:
-
Default Filename: By default, uses the current git branch name (cleaned up) or a timestamp if no branch name is available.
-
File Naming Rules:
- Converts to lowercase
- Replaces non-alphanumeric characters with hyphens
- Removes leading/trailing hyphens
- Collapses multiple hyphens into one
Example:
Feature/Add-NEW_thing!!!
→feature-add-new-thing.yaml
-
Duplicate Handling: If a file with the same name exists:
- Adds a timestamp to the filename
- Example: If
feature.yaml
exists, createsfeature-1234567890.yaml
-
Interactive Prompts:
- Significance: patch, minor, or major
- Type: added, changed, deprecated, removed, fixed, or security
- Entry: Description of the change
- Filename: Optional custom filename
-
Directory Structure:
- Creates the changes directory if it doesn't exist
- Stores all change files in the configured directory (default:
changelog/
)
Change files are YAML files containing:
significance: patch|minor|major
type: added|changed|deprecated|removed|fixed|security
entry: Description of the change
MIT