@bernierllc/validators-semver-consistency
v1.2.2
Published
Semver consistency validation - package versions vs changesets
Readme
@bernierllc/validators-semver-consistency
Semver consistency validation - package versions vs changesets
Installation
npm install @bernierllc/validators-semver-consistencyOverview
A primitive validator package that validates semantic versioning consistency between package versions and changesets. Ensures version bumps align with the nature of changes (breaking changes, features, bug fixes) following Semantic Versioning 2.0.0 specification.
Features
- Version Bump Validation: Validates semantic version progression (major, minor, patch)
- Breaking Change Detection: Ensures breaking changes correspond to major version bumps
- Feature Addition Validation: Ensures features correspond to minor version bumps
- Bug Fix Validation: Ensures fixes correspond to patch version bumps
- Prerelease Tag Validation: Validates prerelease tags (alpha, beta, rc, etc.)
- Build Metadata Support: Parses and validates build metadata
- Changeset Analysis: Parses conventional commits, markdown, and simple formats
- Flexible Configuration: Customizable validation rules and allowed prerelease tags
Usage
Basic Version Bump Validation
import { validateSemverConsistency, isValidVersionBump } from '@bernierllc/validators-semver-consistency';
// Validate a version bump
const problems = await validateSemverConsistency('1.0.0 -> 1.1.0');
if (problems.filter(p => p.severity === 'error').length === 0) {
console.log('Valid version bump');
}
// Quick validation check
const isValid = await isValidVersionBump('1.0.0', '1.1.0');
console.log('Is valid:', isValid); // trueValidation with Changesets
import { validateSemverConsistency } from '@bernierllc/validators-semver-consistency';
// Validate version bump with changesets
const problems = await validateSemverConsistency(
'1.0.0 -> 2.0.0 | breaking!: Remove deprecated API\nfeat: Add new API'
);
// Check for errors
const errors = problems.filter(p => p.severity === 'error');
if (errors.length > 0) {
console.error('Validation failed:', errors.map(e => e.message));
}Comprehensive Analysis
import { analyzeSemverBump } from '@bernierllc/validators-semver-consistency';
// Analyze version bump with detailed results
const result = await analyzeSemverBump(
'1.0.0',
'2.0.0',
'breaking!: Remove deprecated API\nfeat: Add new API\nfix: Fix bug'
);
console.log('Is valid:', result.isValid);
console.log('Bump type:', result.versionBump?.type); // 'major'
console.log('Changesets:', result.changesets);
console.log('Problems:', result.problems);Custom Validation Options
import { validateSemverConsistency } from '@bernierllc/validators-semver-consistency';
const problems = await validateSemverConsistency(
'1.0.0 -> 1.1.0-dev.1',
{
checkBreakingChanges: true,
checkFeatureAdditions: true,
checkBugFixes: true,
validatePreReleaseTags: true,
allowedPreReleaseTags: ['dev', 'alpha', 'beta', 'rc'],
requireChangelog: false,
}
);Using Utility Functions
import {
parseVersion,
compareVersions,
determineBumpType,
isValidSemver,
parseChangesets,
analyzeRequiredBump,
} from '@bernierllc/validators-semver-consistency';
// Parse a semantic version
const version = parseVersion('1.2.3-alpha.1+build.123');
console.log(version);
// {
// major: 1,
// minor: 2,
// patch: 3,
// prerelease: ['alpha', '1'],
// build: ['build', '123'],
// raw: '1.2.3-alpha.1+build.123'
// }
// Compare versions
const v1 = parseVersion('1.0.0')!;
const v2 = parseVersion('2.0.0')!;
console.log(compareVersions(v2, v1)); // 1 (v2 > v1)
// Determine bump type
const bumpType = determineBumpType(v1, v2);
console.log(bumpType); // 'major'
// Validate semver format
console.log(isValidSemver('1.2.3')); // true
console.log(isValidSemver('v1.2.3')); // false
// Parse changesets
const changesets = parseChangesets('feat: Add feature\nfix: Fix bug');
console.log(changesets);
// [
// { type: 'feature', description: 'Add feature', breaking: false },
// { type: 'fix', description: 'Fix bug', breaking: false }
// ]
// Analyze required bump
const requiredBump = analyzeRequiredBump(changesets);
console.log(requiredBump); // 'minor'Changeset Formats
The validator supports multiple changeset formats:
Conventional Commits
feat: Add new feature
fix: Fix bug
breaking!: Remove deprecated API
feat(api): Add new endpointMarkdown Format
- **FEAT**: Add new feature
- **FIX**: Fix bug
- **BREAKING**: Remove deprecated APISimple Format
FEAT: Add new feature
FIX: Fix bug
BREAKING: Remove deprecated APIValidation Rules
Version Bump Rule (semver-version-bump)
Validates that:
- New version is greater than old version
- Version follows semantic versioning format
- Major bumps reset minor and patch to 0
- Minor bumps reset patch to 0
Breaking Change Rule (semver-breaking-changes)
Validates that:
- Breaking changes require major version bump
- Major bumps (>1.0.0) should have documented breaking changes
Prerelease Tag Rule (semver-prerelease-tags)
Validates that:
- Prerelease tags are in allowed list (default: alpha, beta, rc)
- Prerelease format includes version number (e.g., alpha.1)
- Prerelease version numbers are numeric
Options
interface SemverConsistencyOptions {
/**
* Check breaking change alignment with major version bumps
* @default true
*/
checkBreakingChanges?: boolean;
/**
* Validate feature additions correspond to minor version bumps
* @default true
*/
checkFeatureAdditions?: boolean;
/**
* Validate bug fixes correspond to patch version bumps
* @default true
*/
checkBugFixes?: boolean;
/**
* Validate pre-release tag format (alpha, beta, rc, etc.)
* @default true
*/
validatePreReleaseTags?: boolean;
/**
* Validate build metadata format
* @default true
*/
validateBuildMetadata?: boolean;
/**
* Validate dependency version consistency
* @default true
*/
checkDependencyVersions?: boolean;
/**
* Allowed pre-release tag prefixes
* @default ['alpha', 'beta', 'rc']
*/
allowedPreReleaseTags?: string[];
/**
* Require changelog entry for version changes
* @default false
*/
requireChangelog?: boolean;
/**
* Minimum version to validate (optional)
*/
minVersion?: string;
/**
* Maximum version to validate (optional)
*/
maxVersion?: string;
}Problem Severity
The validator returns problems with two severity levels:
- error: Version bump violates semantic versioning rules (e.g., breaking change without major bump)
- warning: Best practice violations (e.g., major bump without documented breaking changes)
Use Cases
Package Publishing
import { analyzeSemverBump } from '@bernierllc/validators-semver-consistency';
async function validateRelease(currentVersion: string, newVersion: string, changelog: string) {
const result = await analyzeSemverBump(currentVersion, newVersion, changelog);
if (!result.isValid) {
throw new Error(`Invalid version bump: ${result.problems.map(p => p.message).join(', ')}`);
}
console.log(`✓ Valid ${result.versionBump?.type} bump from ${currentVersion} to ${newVersion}`);
}CI/CD Pipeline
import { validateSemverConsistency } from '@bernierllc/validators-semver-consistency';
import { readFileSync } from 'fs';
async function validateVersionInCI() {
const packageJson = JSON.parse(readFileSync('package.json', 'utf-8'));
const changelog = readFileSync('CHANGELOG.md', 'utf-8');
const problems = await validateSemverConsistency(
`${process.env.PREVIOUS_VERSION} -> ${packageJson.version} | ${changelog}`
);
const errors = problems.filter(p => p.severity === 'error');
if (errors.length > 0) {
console.error('Version validation failed:');
errors.forEach(e => console.error(` - ${e.message}`));
process.exit(1);
}
console.log('✓ Version validation passed');
}Changeset Validation
import { parseChangesets, validateBumpMatchesChangesets } from '@bernierllc/validators-semver-consistency';
function validateChangesetFile(changesetPath: string, bumpType: BumpType) {
const changesetContent = readFileSync(changesetPath, 'utf-8');
const changesets = parseChangesets(changesetContent);
const result = validateBumpMatchesChangesets(bumpType, changesets);
if (!result.isValid) {
console.error('Changeset validation failed:');
result.errors.forEach(e => console.error(` - ${e}`));
return false;
}
return true;
}Integration Status
- Logger: not-applicable - Pure validation functions with no side effects
- Docs-Suite: ready - Full JSDoc/TypeDoc documentation with examples
- NeverHub: not-applicable - Primitive validator with no external service dependencies
Dependencies
@bernierllc/validators-core- Foundation for validation rules and primitives
Related Validators
@bernierllc/validators-changelog-presence- Validates changelog presence and format@bernierllc/validators-release- Domain validator combining release validation rules@bernierllc/validators-ci-workflow- Validates CI/CD workflow configurations
License
Copyright (c) 2025 Bernier LLC. All rights reserved.
Contributing
This package follows the BernierLLC package quality standards:
- TypeScript strict mode
- 85%+ test coverage
- Zero linting errors
- Comprehensive documentation
- Real data testing (minimal mocking)
Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests once (CI mode)
npm run test:runBuilding
# Build the package
npm run build
# Clean build artifacts
npm run cleanQuality Standards
This package meets BernierLLC quality requirements:
- ✅ TypeScript strict mode enabled
- ✅ 85%+ test coverage
- ✅ Zero ESLint errors/warnings
- ✅ Comprehensive JSDoc documentation
- ✅ Integration status documented
- ✅ Real data testing approach
