关于 semantic-versioning
semantic-versioning 是用于版本管理和变更日志生成的技能,面向发布流程与软件包维护。它介绍 SemVer 规则,并涵盖自动递增版本、生成日志及多包版本管理。
主要功能
- 01按 SemVer 规则递增版本
- 02根据 Conventional Commits 判定版本
- 03自动生成变更日志
- 04配置 semantic-release 与 standard-version
- 05管理多软件包版本
适用场景
- 01为 CI 发布流程自动定版本
- 02依据提交记录生成变更日志
- 03协调多包仓库的版本发布
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill semantic-versioning安装后在 Claude Code 中输入/semantic-versioning确认已加载。
详细介绍
语义化版本控制
遵循 SemVer 原则,自动管理版本并生成变更日志。
何时使用此技能
在以下情况下使用此技能:
- 实施版本编号标准
- 自动化发行版本管理
- 自动生成变更日志
- 设置发行流水线
- 管理软件包版本
前置条件
- 包含提交历史的 Git 仓库
- Node.js(适用于大多数工具)
- 规范化提交(推荐)
语义化版本控制基础
版本格式
MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]
Examples:
1.0.0
2.1.3
1.0.0-alpha.1
1.0.0-beta.2+build.123
版本组成部分
| 组成部分 | 递增时机 |
|---|---|
| MAJOR | 包含破坏性变更(不兼容的 API 变更) |
| MINOR | 新功能(向后兼容) |
| PATCH | Bug 修复(向后兼容) |
| PRERELEASE | 预发行版本(alpha、beta、rc) |
| BUILD | 构建元数据(不影响优先级) |
版本优先级
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
根据规范化提交确定版本
Commit Type → Version Bump:
feat: → MINOR
fix: → PATCH
docs: → PATCH (or no release)
style: → PATCH (or no release)
refactor: → PATCH
perf: → PATCH
test: → No release
chore: → No release
BREAKING CHANGE: → MAJOR
feat!: → MAJOR
fix!: → MAJOR
semantic-release
安装
npm install --save-dev semantic-release \
@semantic-release/changelog \
@semantic-release/git
配置
// .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"
]
}
高级配置
// release.config.js
module.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 集成
# .github/workflows/release.yml
name: Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
standard-version
安装
npm install --save-dev standard-version
配置
// .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}}"
}
使用方法
# First release
npx standard-version --first-release
# Regular release (auto-detect version bump)
npx standard-version
# Specific version bump
npx standard-version --release-as minor
npx standard-version --release-as 1.1.0
# Pre-release
npx standard-version --prerelease alpha
npx standard-version --prerelease beta
# Dry run
npx standard-version --dry-run
# Skip specific steps
npx standard-version --skip.changelog
NPM 脚本
// 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"
}
}
生成变更日志
conventional-changelog
# Install
npm install -g conventional-changelog-cli
# Generate changelog
conventional-changelog -p angular -i CHANGELOG.md -s
# Generate all history
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
git-cliff
# Install
cargo install git-cliff
# Generate changelog
git 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 = true
filter_unconventional = true
commit_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 = true
tag_pattern = "v[0-9]*"
版本升级脚本
Bash 脚本
#!/bin/bash
# bump-version.sh
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "Current version: $CURRENT_VERSION"
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
case $1 in
major)
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
;;
esac
echo "New version: $NEW_VERSION"
# Update package.json
npm version $NEW_VERSION --no-git-tag-version
# Create git tag
git add package.json package-lock.json
git commit -m "chore: bump version to $NEW_VERSION"
git tag -a "v$NEW_VERSION" -m "Version $NEW_VERSION"
Python 脚本
#!/usr/bin/env python3
# bump_version.py
import re
import sys
import subprocess
def 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 None
def 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}'])
多软件包版本管理
Lerna
// lerna.json
{
"version": "independent",
"npmClient": "npm",
"command": {
"version": {
"conventionalCommits": true,
"message": "chore(release): publish"
},
"publish": {
"conventionalCommits": true
}
}
}
# Version all changed packages
npx lerna version
# Publish all changed packages
npx lerna publish
Changesets
# Initialize
npx @changesets/cli init
# Add changeset
npx changeset add
# Version packages
npx changeset version
# Publish
npx changeset publish
常见问题
问题:版本未升级
问题:semantic-release 未创建发行版本
解决方案:检查提交格式,确认分支配置
问题:计算出的版本错误
问题:错误判定 major/minor/patch
解决方案:检查提交分析器规则,确认是否缺少前缀
问题:标签重复
问题:标签已存在
解决方案:清理标签,确认该版本尚未发行
最佳实践
- 始终使用规范化提交
- 在 CI 中自动升级版本
- 自动生成变更日志
- 在 Git 中为发行版本打标签
- 使用预发行版本进行测试
- 清楚记录破坏性变更
- 为 major 版本提供迁移指南
- 使用精确版本锁定依赖项
相关技能
- git-workflow - 分支策略
- github-actions - CI 自动化
- feature-flags - 渐进式发布
评论
支持 Markdown