Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: semantic-versioning description: Automate versioning and changelog generation using semantic versioning principles. Configure release automation, version bumping, and changelog tools. Use when implementing version management or automating release processes. license: MIT metadata: author: devops-skills version: "1.0"
Semantic Versioning
Automate version management and changelog generation following SemVer principles.
When to Use This Skill
Use this skill when:
- Implementing version numbering standards
- Automating release versioning
- Generating changelogs automatically
- Setting up release pipelines
- Managing package versions
Prerequisites
- Git repository with commit history
- Node.js (for most tools)
- Conventional commits (recommended)
Semantic Versioning Basics
Version Format
MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]Examples:1.0.02.1.31.0.0-alpha.11.0.0-beta.2+build.123
Version Components
| Component | When to Increment | |
|---|---|---|
| MAJOR | Breaking changes (incompatible API changes) | |
| MINOR | New features (backward compatible) | |
| PATCH | Bug fixes (backward compatible) | |
| PRERELEASE | Pre-release versions (alpha, beta, rc) | |
| BUILD | Build metadata (ignored in precedence) |
Version Precedence
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta< 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11< 1.0.0-rc.1 < 1.0.0 < 2.0.0
Conventional Commits to Version
Commit Type → Version Bump:feat: → MINORfix: → PATCHdocs: → PATCH (or no release)style: → PATCH (or no release)refactor: → PATCHperf: → PATCHtest: → No releasechore: → No releaseBREAKING CHANGE: → MAJORfeat!: → MAJORfix!: → MAJOR
semantic-release
Installation
npm install --save-dev semantic-release \@semantic-release/changelog \@semantic-release/git
Configuration
// .releaserc.json{"branches": ["main"],"plugins": ["@semantic-release/commit-analyzer","@semantic-release/release-notes-generator",["@semantic-release/changelog", {"changelogFile": "CHANGELOG.md"}],["@semantic-release/npm", {"npmPublish": true}],["@semantic-release/git", {"assets": ["CHANGELOG.md", "package.json", "package-lock.json"],"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}],"@semantic-release/github"]}
Advanced Configuration
// release.config.jsmodule.exports = {branches: ['main',{ name: 'beta', prerelease: true },{ name: 'alpha', prerelease: true }],plugins: [['@semantic-release/commit-analyzer', {preset: 'angular',releaseRules: [{ type: 'docs', release: 'patch' },{ type: 'refactor', release: 'patch' },{ type: 'style', release: 'patch' },{ type: 'perf', release: 'patch' },{ breaking: true, release: 'major' }]}],['@semantic-release/release-notes-generator', {preset: 'angular',writerOpts: {commitsSort: ['subject', 'scope']}}],'@semantic-release/changelog','@semantic-release/npm','@semantic-release/git','@semantic-release/github']};
GitHub Actions Integration
# .github/workflows/release.ymlname: Releaseon:push:branches: [main]jobs:release:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4with:fetch-depth: 0persist-credentials: false- uses: actions/setup-node@v4with:node-version: '20'- run: npm ci- name: Releaseenv:GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}NPM_TOKEN: ${{ secrets.NPM_TOKEN }}run: npx semantic-release
standard-version
Installation
npm install --save-dev standard-version
Configuration
// .versionrc.json{"types": [{ "type": "feat", "section": "Features" },{ "type": "fix", "section": "Bug Fixes" },{ "type": "docs", "section": "Documentation" },{ "type": "style", "section": "Styling" },{ "type": "refactor", "section": "Code Refactoring" },{ "type": "perf", "section": "Performance" },{ "type": "test", "section": "Tests" },{ "type": "chore", "section": "Maintenance" }],"skip": {"bump": false,"changelog": false,"commit": false,"tag": false},"commitUrlFormat": "https://github.com/owner/repo/commit/{{hash}}","compareUrlFormat": "https://github.com/owner/repo/compare/{{previousTag}}...{{currentTag}}"}
Usage
# First releasenpx standard-version --first-release# Regular release (auto-detect version bump)npx standard-version# Specific version bumpnpx standard-version --release-as minornpx standard-version --release-as 1.1.0# Pre-releasenpx standard-version --prerelease alphanpx standard-version --prerelease beta# Dry runnpx standard-version --dry-run# Skip specific stepsnpx standard-version --skip.changelog
NPM Scripts
// package.json{"scripts": {"release": "standard-version","release:minor": "standard-version --release-as minor","release:major": "standard-version --release-as major","release:alpha": "standard-version --prerelease alpha","release:beta": "standard-version --prerelease beta","release:dry": "standard-version --dry-run"}}
Changelog Generation
conventional-changelog
# Installnpm install -g conventional-changelog-cli# Generate changelogconventional-changelog -p angular -i CHANGELOG.md -s# Generate all historyconventional-changelog -p angular -i CHANGELOG.md -s -r 0
git-cliff
# Installcargo install git-cliff# Generate changeloggit cliff -o CHANGELOG.md
# cliff.toml[changelog]header = "# Changelog\n\n"body = """{% for group, commits in commits | group_by(attribute="group") %}## {{ group | upper_first }}{% for commit in commits %}- {{ commit.message | upper_first }}\{% endfor %}{% endfor %}"""trim = true[git]conventional_commits = truefilter_unconventional = truecommit_preprocessors = [{ pattern = '\((\w+)\s#([0-9]+)\)', replace = "([#${2}](https://github.com/owner/repo/issues/${2}))" },]commit_parsers = [{ message = "^feat", group = "Features" },{ message = "^fix", group = "Bug Fixes" },{ message = "^doc", group = "Documentation" },{ message = "^perf", group = "Performance" },{ message = "^refactor", group = "Refactoring" },{ message = "^style", group = "Styling" },{ message = "^test", group = "Testing" },{ message = "^chore", group = "Miscellaneous" },]filter_commits = truetag_pattern = "v[0-9]*"
Version Bumping Scripts
Bash Script
#!/bin/bash# bump-version.shCURRENT_VERSION=$(cat package.json | jq -r '.version')echo "Current version: $CURRENT_VERSION"IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"case $1 inmajor)NEW_VERSION="$((MAJOR + 1)).0.0";;minor)NEW_VERSION="$MAJOR.$((MINOR + 1)).0";;patch)NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))";;*)echo "Usage: $0 {major|minor|patch}"exit 1;;esacecho "New version: $NEW_VERSION"# Update package.jsonnpm version $NEW_VERSION --no-git-tag-version# Create git taggit add package.json package-lock.jsongit commit -m "chore: bump version to $NEW_VERSION"git tag -a "v$NEW_VERSION" -m "Version $NEW_VERSION"
Python Script
#!/usr/bin/env python3# bump_version.pyimport reimport sysimport subprocessdef get_current_version():with open('setup.py', 'r') as f:content = f.read()match = re.search(r"version=['\"]([^'\"]+)['\"]", content)return match.group(1) if match else Nonedef bump_version(current, bump_type):major, minor, patch = map(int, current.split('.'))if bump_type == 'major':return f'{major + 1}.0.0'elif bump_type == 'minor':return f'{major}.{minor + 1}.0'elif bump_type == 'patch':return f'{major}.{minor}.{patch + 1}'else:raise ValueError(f'Invalid bump type: {bump_type}')def update_version(old_version, new_version):with open('setup.py', 'r') as f:content = f.read()content = content.replace(f"version='{old_version}'", f"version='{new_version}'")with open('setup.py', 'w') as f:f.write(content)if __name__ == '__main__':bump_type = sys.argv[1] if len(sys.argv) > 1 else 'patch'current = get_current_version()new = bump_version(current, bump_type)print(f'Bumping version: {current} → {new}')update_version(current, new)subprocess.run(['git', 'add', 'setup.py'])subprocess.run(['git', 'commit', '-m', f'chore: bump version to {new}'])subprocess.run(['git', 'tag', '-a', f'v{new}', '-m', f'Version {new}'])
Multi-Package Versioning
Lerna
// lerna.json{"version": "independent","npmClient": "npm","command": {"version": {"conventionalCommits": true,"message": "chore(release): publish"},"publish": {"conventionalCommits": true}}}
# Version all changed packagesnpx lerna version# Publish all changed packagesnpx lerna publish
Changesets
# Initializenpx @changesets/cli init# Add changesetnpx changeset add# Version packagesnpx changeset version# Publishnpx changeset publish
Common Issues
Issue: No Version Bump
Problem: semantic-release not creating release Solution: Check commit format, verify branch configuration
Issue: Wrong Version Calculated
Problem: Major/minor/patch incorrectly determined Solution: Review commit analyzer rules, check for missing prefixes
Issue: Duplicate Tags
Problem: Tag already exists Solution: Clean up tags, verify version wasn't already released
Best Practices
- Use conventional commits consistently
- Automate version bumping in CI
- Generate changelogs automatically
- Tag releases in Git
- Use pre-release versions for testing
- Document breaking changes clearly
- Include migration guides for major versions
- Lock dependencies with exact versions
Related Skills
- git-workflow - Branching strategies
- github-actions - CI automation
- feature-flags - Progressive rollout