
Security News
OWASP 2025 Top 10 Adds Software Supply Chain Failures, Ranked Top Community Concern
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.
@stellarwp/changelogger
Advanced tools
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.
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
add CommandAdds 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:
When using --auto-filename:
validate CommandValidates all changelog entries in the changes directory.
npm run changelog validate
This command performs the following checks:
write CommandWrites 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:
When using --dry-run:
When using --overwrite-version:
When using --date:
--date "2024-03-20" - Specific date--date "yesterday" - Relative date--date "last monday" - Relative date--date "next friday" - Relative dateThe command supports multiple output files with different 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])
1.2.31.2.3.4major: 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:
{
"changelogger": {
"versioning": "stellarwp"
}
}
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 an object with these methods:
// custom-versioning.js
module.exports = {
/**
* Calculate the next version based on current version and significance
* @param {string} currentVersion - Current version string
* @param {"major" | "minor" | "patch"} significance - Type of change
* @returns {string} The next version
*/
getNextVersion(currentVersion, significance) {
// Your custom logic here
const parts = currentVersion.split(".");
const major = parseInt(parts[0] || "0");
const minor = parseInt(parts[1] || "0");
const patch = parseInt(parts[2] || "0");
switch (significance) {
case "major":
return `${major + 1}.0.0`;
case "minor":
return `${major}.${minor + 1}.0`;
case "patch":
return `${major}.${minor}.${patch + 1}`;
default:
throw new Error(`Unknown significance: ${significance}`);
}
},
/**
* Check if a version string is valid
* @param {string} version - Version string to validate
* @returns {boolean} True if valid
*/
isValidVersion(version) {
return /^\d+\.\d+\.\d+$/.test(version);
},
/**
* Compare two versions
* @param {string} v1 - First version
* @param {string} v2 - Second version
* @returns {number} -1 if v1 < v2, 0 if equal, 1 if v1 > v2
*/
compareVersions(v1, v2) {
const parts1 = v1.split(".").map(Number);
const parts2 = v2.split(".").map(Number);
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const part1 = parts1[i] || 0;
const part2 = parts2[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
},
};
See examples/custom-versioning.js for a complete example.
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 export an object with these methods:
// custom-writing.js
// You can import utilities from the main package to help with formatting
// Note: These are only available when using the writing strategy through changelogger
const { getTypeLabel, defaultConfig } = require("@stellarwp/changelogger");
module.exports = {
/**
* Format the changes into a changelog entry
* @param {string} version - Version being released
* @param {Array<{type: string, entry: string, significance: string}>} changes - List of changes
* @param {string} [previousVersion] - Previous version for comparison
* @returns {string} Formatted changelog content
*/
formatChanges(version, changes, previousVersion) {
// Group changes by type
const grouped = {};
for (const change of changes) {
if (!grouped[change.type]) {
grouped[change.type] = [];
}
grouped[change.type].push(change.entry);
}
// Format each group
let output = "";
for (const [type, entries] of Object.entries(grouped)) {
// Use getTypeLabel for consistent type formatting
// Falls back to capitalized type if not in config
const label = getTypeLabel ? getTypeLabel(type) : type.charAt(0).toUpperCase() + type.slice(1);
output += `\n### ${label}\n\n`;
for (const entry of entries) {
output += `- ${entry}\n`;
}
}
return output;
},
/**
* Format the header for a new version
* @param {string} version - Version being released
* @param {string} date - Release date (YYYY-MM-DD format)
* @param {string} [previousVersion] - Previous version
* @returns {string} Formatted version header
*/
formatVersionHeader(version, date, previousVersion) {
return `## [${version}] - ${date}\n`;
},
/**
* Optional: Format version comparison links
* @param {string} version - Current version
* @param {string} previousVersion - Previous version
* @param {string} [template] - URL template from config
* @returns {string} Formatted link
*/
formatVersionLink(version, previousVersion, template) {
if (!template) return "";
const link = template.replace("{version}", version).replace("{previousVersion}", previousVersion);
return `\n[${version}]: ${link}\n`;
},
/**
* Match an existing version header in the changelog
* @param {string} content - Existing changelog content
* @param {string} version - Version to find
* @returns {string|undefined} Matched header or undefined
*/
versionHeaderMatcher(content, version) {
const regex = new RegExp(`^## \\[${version}\\].*$`, "m");
const match = content.match(regex);
return match ? match[0] : undefined;
},
/**
* Find where to insert new changelog entries
* @param {string} content - Existing changelog content
* @returns {number} Index where new entries should be inserted
*/
changelogHeaderMatcher(content) {
// Look for the first version header
const match = content.match(/^## \[.*?\]/m);
if (match && match.index !== undefined) {
return match.index;
}
// Look for main changelog header
const headerMatch = content.match(/^# Changelog/m);
if (headerMatch && headerMatch.index !== undefined) {
return headerMatch.index + headerMatch[0].length + 1;
}
return 0;
},
};
See examples/custom-writing.js for a complete example.
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:
Feature/Add-NEW_thing!!! → feature-add-new-thing.yamlDuplicate Handling: If a file with the same name exists:
feature.yaml exists, creates feature-1234567890.yamlInteractive Prompts:
Directory Structure:
changelog/)Change files are YAML files containing:
significance: patch|minor|major
type: added|changed|deprecated|removed|fixed|security
entry: Description of the change
The changelogger can also be used as a library in your Node.js applications:
import { loadConfig, addCommand, validateCommand, writeCommand, Config, WritingStrategy, VersioningStrategy } from "@stellarwp/changelogger";
// Load configuration from package.json
const config = await loadConfig();
// Add a new change entry programmatically
await addCommand({
significance: "minor",
type: "added",
entry: "New feature added",
filename: "custom-change.yaml",
});
// Validate all change files
const validationResult = await validateCommand();
console.log(validationResult);
// Write changelog (with options)
const writeResult = await writeCommand({
overwriteVersion: "1.2.3",
dryRun: false,
date: "2024-03-20",
});
console.log(writeResult);
const { loadConfig, addCommand, validateCommand, writeCommand } = require("@stellarwp/changelogger");
// Same usage as above
(async () => {
const config = await loadConfig();
console.log("Config loaded:", config.changelogFile);
})();
// TypeScript / ES6 with bundler
import { defaultConfig, getTypeLabel } from "@stellarwp/changelogger";
// Use default configuration as a base
const myConfig = {
...defaultConfig,
changesDir: "my-changes",
};
// Get formatted labels for change types
console.log(getTypeLabel("added")); // "Added"
console.log(getTypeLabel("fix")); // "Fix"
console.log(getTypeLabel("custom-type")); // Falls back to "custom-type" if not defined
// TypeScript / ES6 with bundler
import { loadVersioningStrategy, loadWritingStrategy, versioningStrategies, writingStrategies, getTypeLabel, defaultConfig } from "@stellarwp/changelogger";
// Load built-in strategies
const semverStrategy = versioningStrategies.semverStrategy;
const keepachangelog = writingStrategies.keepachangelog;
// Load custom strategies from files
const customVersioning = await loadVersioningStrategy("./my-versioning.js");
const customWriting = await loadWritingStrategy("./my-writing.js");
// Use strategies directly
const nextVersion = customVersioning.getNextVersion("1.2.3", "minor");
console.log(nextVersion); // Your custom versioning logic result
The package includes TypeScript declarations for full type support:
import { Config, ChangeFile, WriteCommandOptions, VersioningStrategy, WritingStrategy } from "@stellarwp/changelogger";
// All types are available for TypeScript users
const config: Config = await loadConfig();
const change: ChangeFile = {
significance: "patch",
type: "fixed",
entry: "Fixed a bug",
};
const options: WriteCommandOptions = {
overwriteVersion: "1.0.0",
dryRun: true,
};
MIT
FAQs
A TypeScript-based changelog management tool
The npm package @stellarwp/changelogger receives a total of 177 weekly downloads. As such, @stellarwp/changelogger popularity was classified as not popular.
We found that @stellarwp/changelogger demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.