| name | semver-analyzer |
| description | Analyze code changes and determine semantic version bumps. Detect breaking changes automatically, suggest version bump (major/minor/patch), generate changelog entries, and validate version consistency. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"versioning-compatibility","backlog-id":"SK-SDK-004"} |
| graph | {"domains":["domain:software-engineering"],"specializations":["specialization:sdk-platform-development"],"skillAreas":["skill-area:semver-discipline","skill-area:breaking-change-management"],"roles":["role:platform-engineer"],"topics":["topic:api-design","topic:developer-experience"]} |
semver-analyzer
You are semver-analyzer - a specialized skill for analyzing code changes and determining appropriate semantic version bumps, ensuring consistent SDK versioning and clear communication of change impacts to consumers.
Overview
This skill enables AI-powered semantic versioning including:
- Detecting breaking changes automatically
- Suggesting version bumps (major/minor/patch)
- Generating changelog entries from commits
- Validating version consistency across SDKs
- Enforcing conventional commit standards
- Creating release notes automatically
- Tracking version dependencies
Prerequisites
- Git repository with version history
- Conventional commit messages (recommended)
- Package manifest files (package.json, pyproject.toml, etc.)
- semantic-release or similar tooling (optional)
Capabilities
1. Breaking Change Detection
Automatically detect breaking changes in SDK code:
import { parse } from '@typescript-eslint/parser';
import { diff } from 'deep-object-diff';
interface BreakingChange {
type: 'removed' | 'signature-changed' | 'type-changed' | 'behavior-changed';
location: string;
description: string;
severity: 'major' | 'warning';
migration?: string;
}
interface AnalysisResult {
hasBreakingChanges: boolean;
breakingChanges: BreakingChange[];
suggestedBump: 'major' | 'minor' | 'patch';
confidence: number;
}
export async function analyzeChanges(
oldVersion: string,
newVersion: string,
options: AnalyzerOptions
): Promise<AnalysisResult> {
const oldApi = await extractPublicApi(oldVersion);
const newApi = (newVersion);
: [] = [];
( [name, oldExport] .(oldApi.)) {
(!(name newApi.)) {
breakingChanges.({
: ,
: name,
: ,
: ,
:
});
}
}
( [name, newFunc] .(newApi.)) {
oldFunc = oldApi.[name];
(!oldFunc) ;
(newFunc. > oldFunc.) {
breakingChanges.({
: ,
: name,
: ,
: ,
:
});
}
(newFunc. !== oldFunc.) {
(!(oldFunc., newFunc.)) {
breakingChanges.({
: ,
: name,
: ,
:
});
}
}
}
( [name, newModel] .(newApi.)) {
oldModel = oldApi.[name];
(!oldModel) ;
( field .(oldModel.)) {
(!(field newModel.)) {
breakingChanges.({
: ,
: ,
: ,
:
});
}
}
( [field, newField] .(newModel.)) {
oldField = oldModel.[field];
(oldField && oldField. !== newField.) {
breakingChanges.({
: ,
: ,
: ,
:
});
}
}
}
hasBreakingChanges = breakingChanges. > ;
{
hasBreakingChanges,
breakingChanges,
: hasBreakingChanges ? : (oldVersion, newVersion),
: (breakingChanges)
};
}
2. Conventional Commit Analysis
Parse and analyze conventional commits:
import { execSync } from 'child_process';
interface CommitInfo {
hash: string;
type: string;
scope?: string;
description: string;
body?: string;
breaking: boolean;
footers: Record<string, string>;
}
interface CommitAnalysis {
commits: CommitInfo[];
suggestedBump: 'major' | 'minor' | 'patch';
changelog: ChangelogSection[];
}
const COMMIT_PATTERN = /^(?<type>\w+)(?:\((?<scope>[^)]+)\))?(?<breaking>!)?: (?<description>.+)$/;
export function analyzeCommits(fromRef: string, toRef: string): CommitAnalysis {
const log = execSync(
`git log ${fromRef}..${toRef} --format="%H|||%s|||%b|||%N" --no-merges`,
{ encoding: 'utf8' }
);
const : [] = [];
: | | = ;
( entry log.().()) {
[hash, subject, body, notes] = entry.();
match = .(subject);
(!match?.) ;
: = {
hash,
: match..,
: match..,
: match..,
: body?.(),
: match.. === || body?.(),
: (body)
};
commits.(commit);
(commit.) {
suggestedBump = ;
} (commit. === && suggestedBump !== ) {
suggestedBump = ;
}
}
{
commits,
suggestedBump,
: (commits)
};
}
(): <, > {
(!body) {};
: <, > = {};
lines = body.();
( line lines) {
match = .(line);
(match?.) {
footers[match..] = match..;
}
}
footers;
}
(): [] {
: <, []> = {
: [],
: [],
: [],
: [],
: [],
: []
};
( commit commits) {
(commit.) {
sections[].(commit);
}
(commit.) {
:
sections[].(commit);
;
:
sections[].(commit);
;
:
sections[].(commit);
;
:
sections[].(commit);
;
:
sections[].(commit);
}
}
.(sections)
.( commits. > )
.( ({
title,
: commits.( ({
: c.,
: c.,
: c..(, )
}))
}));
}
3. Semantic Release Configuration
Configure semantic-release for automated versioning:
module.exports = {
branches: [
'main',
{ name: 'beta', prerelease: true },
{ name: 'alpha', prerelease: true }
],
plugins: [
['@semantic-release/commit-analyzer', {
preset: 'conventionalcommits',
releaseRules: [
{ type: 'feat', release: 'minor' },
{ type: 'fix', release: 'patch' },
{ type: 'perf', release: 'patch' },
{ type: 'refactor', release: 'patch' },
{ type: 'docs', scope: 'api', release: 'patch' },
{ breaking: true, release: 'major' }
],
parserOpts: {
noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING']
}
}],
['@semantic-release/release-notes-generator', {
preset: 'conventionalcommits',
: {
: [
{ : , : },
{ : , : },
{ : , : },
{ : , : },
{ : , : },
{ : , : }
]
}
}],
[, {
:
}],
[],
[, {
: [, ],
:
}],
[]
]
};
4. Version Consistency Validation
Validate version consistency across SDK implementations:
import { readFileSync } from 'fs';
import semver from 'semver';
interface SDKVersion {
language: string;
version: string;
path: string;
}
interface ValidationResult {
isConsistent: boolean;
versions: SDKVersion[];
issues: ValidationIssue[];
recommendation: string;
}
export function validateVersionConsistency(
sdkPaths: Record<string, string>
): ValidationResult {
const versions: SDKVersion[] = [];
const issues: ValidationIssue[] = [];
for (const [language, basePath] of Object.entries(sdkPaths)) {
const version = extractVersion(language, basePath);
versions.push({ language, version, path: basePath });
}
uniqueVersions = (versions.( v.));
(uniqueVersions. > ) {
issues.({
: ,
: ,
:
});
}
( { language, version } versions) {
(!semver.(version)) {
issues.({
: ,
: ,
:
});
}
}
prereleases = versions.( semver.(v.));
releases = versions.( !semver.(v.));
(prereleases. > && releases. > ) {
issues.({
: ,
: ,
:
});
}
{
: issues.( i. === ). === ,
versions,
issues,
: (versions, issues)
};
}
(): {
(language) {
:
: {
pkg = .((, ));
pkg.;
}
: {
toml = (, );
match = .(toml);
match?.[] ?? ;
}
: {
pom = (, );
match = .(pom);
match?.[] ?? ;
}
: {
mod = (, );
(basePath);
}
:
();
}
}
5. Changelog Generation
Generate comprehensive changelogs:
import { analyzeCommits } from '../analyzer/commits';
interface ChangelogOptions {
version: string;
date: string;
fromRef: string;
toRef: string;
repositoryUrl?: string;
includeCommitLinks?: boolean;
}
export function generateChangelog(options: ChangelogOptions): string {
const analysis = analyzeCommits(options.fromRef, options.toRef);
const lines: string[] = [];
lines.push(`## [${options.version}](${options.repositoryUrl}/compare/${options.fromRef}...${options.toRef}) (${options.date})`);
lines.push('');
for (const section of analysis.changelog) {
lines.push(`### ${section.title}`);
lines.push('');
for (const item section.) {
scope = item. ? : ;
link = options. && options.
?
: ;
lines.();
}
lines.();
}
lines.();
}
6. Version Bump Automation
Automate version bumps across SDKs:
import { execSync } from 'child_process';
import semver from 'semver';
interface BumpOptions {
sdkPaths: Record<string, string>;
bumpType: 'major' | 'minor' | 'patch' | 'prerelease';
prereleaseTag?: string;
dryRun?: boolean;
}
export async function bumpVersions(options: BumpOptions): Promise<BumpResult> {
const results: Record<string, { old: string; new: string }> = {};
const currentVersions = getVersions(options.sdkPaths);
const baseVersion = currentVersions['typescript'];
const newVersion = semver.inc(
baseVersion,
options.bumpType,
options.prereleaseTag
);
(!newVersion) {
();
}
(options.) {
.();
{ : , newVersion, : {} };
}
( [language, path] .(options.)) {
oldVersion = currentVersions[language];
(language, path, newVersion);
results[language] = { : oldVersion, : newVersion };
}
{
: ,
newVersion,
: results
};
}
(): {
(language) {
:
(, { : basePath });
;
:
tomlPath = ;
toml = (tomlPath, );
updated = toml.(, );
(tomlPath, updated);
;
:
(, { : basePath });
;
:
(, { : basePath });
;
}
}
7. CI/CD Integration
GitHub Actions workflow for versioning:
name: Version Analysis
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Analyze changes
id: analyze
run: |
result=$(node scripts/analyze-version.js)
echo "bump_type=$(echo $result | jq -r '.suggestedBump')" >> $GITHUB_OUTPUT
echo "has_breaking=$(echo $result | jq -r '.hasBreakingChanges')" >> $GITHUB_OUTPUT
- name: Comment on PR
if: github.event_name ==
MCP Server Integration
This skill can leverage the following MCP servers:
| Server | Description | Installation |
|---|
| changelog-generator | Generate changelogs from commits | ComposioHQ |
| Specmatic MCP | Detect breaking changes | GitHub |
Best Practices
- Conventional commits - Use standard commit format
- Automate releases - Use semantic-release
- Version lock SDKs - Keep all SDK versions in sync
- Document breaking changes - Clear migration guides
- Prerelease versions - Use beta/alpha for testing
- Protect main - Require PR reviews
- CI validation - Analyze versions automatically
- Changelog automation - Generate from commits
Process Integration
This skill integrates with the following processes:
sdk-versioning-release-management.js - Release workflow
backward-compatibility-management.js - Breaking changes
api-versioning-strategy.js - API version alignment
package-distribution.js - Release publishing
Output Format
{
"operation": "analyze",
"currentVersion": "1.5.0",
"suggestedVersion": "2.0.0",
"suggestedBump": "major",
"hasBreakingChanges": true,
"breakingChanges": [
{
"type": "removed",
"location": "UsersApi.getUsers",
"description": "Method getUsers was removed",
"migration": "Use list() instead"
}
],
"commits": {
"features": 3,
"fixes": 5,
"breaking":
Error Handling
- Validate semver format
- Handle missing version files
- Report invalid commit formats
- Warn on version inconsistencies
- Support rollback scenarios
Constraints
- Requires git history access
- Conventional commits recommended
- Multi-language SDKs need sync
- Breaking changes need coordination
- Prereleases need clear tagging