MonkeyCode 开源项目的版本管理策略:从语义化版本到发布节奏的完整实践
引言
在开源软件的世界里,版本管理(Version Management) 不仅仅是给代码打标签那么简单——它是项目与用户之间建立信任的契约,是依赖管理的基石,也是团队协作的节拍器。作为一款支持私有化部署的 AI 编程工具,MonkeyCode 在版本管理方面积累了丰富的实践经验。本文将全面分享我们的版本管理策略、工具链配置和最佳实践。
GitHub Issue 邀请:如果您在版本管理、语义化版本规范或发布流程方面有任何问题或建议,欢迎前往 MonkeyCode GitHub 仓库 提交 Issue 或参与讨论!
一、为什么版本管理如此重要?
1.1 版本管理的核心价值
┌─────────────────────────────────────────────────────────────┐
│ 📌 版本管理的六大核心价值 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 🔢 可预测性 │
│ → 用户知道何时升级安全 │
│ → 依赖方可以锁定兼容版本 │
│ → 团队成员理解变更范围 │
│ │
│ 🔗 互操作性 │
│ → API 兼容性清晰定义 │
│ → 依赖冲突可提前发现 │
│ → 集成测试有明确目标 │
│ │
│ 📊 可追溯性 │
│ → Bug 可以关联到具体版本 │
│ → 变更历史有据可查 │
│ → 回滚决策有数据支撑 │
│ │
│ 🤝 信任建设 │
│ → 承诺的稳定性增强用户信心 │
│ → 透明的变更日志建立专业形象 │
│ → 一致的发布节奏培养社区习惯 │
│ │
│ ⚡ 效率提升 │
│ → 自动化流水线减少人工错误 │
│ → 标准化流程降低沟通成本 │
│ → 工具链集成加速开发迭代 │
│ │
│ 🛡️ 风险控制 │
│ → Breaking Changes 有预警机制 │
│ → 安全补丁快速响应通道 │
│ → 灰度发布和回滚能力 │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 版本管理不善的代价
| 问题类型 | 影响 | 实际案例 |
|---|---|---|
| 版本号混乱 | 用户不知道该用哪个版本 | 某知名库同时存在 v1.0, v1.0.1, v2.0-alpha, v2.0-rc1, v2.0-final |
| Breaking Change 无预警 | 依赖方大规模故障 | left-pad 事件(2016) |
| Changelog 缺失 | 无法评估升级风险 | 多个 npm 包无更新说明导致升级困难 |
| 发布节奏不稳定 | 用户无法规划升级时间 | 某框架半年不更新,一周发5个版本 |
二、MonkeyCode 的版本管理架构
2.1 语义化版本(SemVer)实践
semver_implementation:
format: "MAJOR.MINOR.PATCH[-prerelease][+build]"
rules:
MAJOR:
trigger: "不兼容的 API 变更"
examples:
- "移除已废弃的 API endpoint"
- "改变核心配置文件格式"
- "修改插件接口签名"
process: "RFC 讨论 → 废弃期(≥2个版本) → 移除"
MINOR:
trigger: "向后兼容的功能新增"
examples:
- "新增 AI 模型提供商支持"
- "增加新的 CLI 命令"
- "扩展 API 能力(不影响现有调用)"
PATCH:
trigger: "向后兼容的问题修复"
examples:
- "修复特定场景下的 bug"
- "更新文档中的错误描述"
- "改进错误提示信息"
prerelease:
formats:
- "alpha.{n}": "内部测试阶段,API 可能变化"
- "beta.{n}": "公开测试,功能冻结但可能有 bug"
- "rc.{n}": "候选发布版,仅修复 critical bug"
2.2 版本号示例
MonkeyCode 版本演进示例:
v0.1.0-alpha.1 → 初始原型,仅核心功能可用
v0.1.0-beta.1 → 功能基本完成,邀请早期体验者
v0.1.0 → 首个公开版本
v0.2.0 → 新增 GPT-4 支持(功能新增)
v0.2.1 → 修复 GPT-4 超时处理(bug 修复)
v1.0.0-rc.1 → API 稳定,准备正式发布
v1.0.0 → 正式发布!API 兼容性承诺生效
v1.1.0 → 新增 Claude 支持
v1.2.0 → 新增本地模型运行能力
v2.0.0-alpha.1 → 重构插件系统(breaking change)
三、分支管理与发布流程
3.1 Git 分支策略
graph TD
A[main<br/>稳定发布版] -->|hotfix| B[hotfix/x.y.z]
B -->|merge + tag| A
A -->|release branch| C[release/vx.y.z]
C -->|bug fixes only| C
C -->|tag + merge| A
C -->|backport to| D[develop]
D[develop<br/>开发集成分支] -->|feature| E[feature/xxx]
E -->|PR review| D
D -->|ready for release| C
style A fill:#2ECC40,color:#fff
style D fill:#3498DB,color:#fff
style C fill:#F39C12,color:#000
style E fill:#9B59B6,color:#fff
style B fill:#E74C3C,color:#fff
3.2 分支命名与保护规则
branch_strategy:
main:
name: "main"
protection:
required_reviews: 2
required_status_checks:
- "CI / Build (ubuntu-latest)"
- "CI / Test (ubuntu-latest)"
- "CodeQL Analysis"
- "Dependabot Security"
dismiss_stale_reviews: true
restrict_push: true
allowed_pushers: ["release-bot", "maintainers-team"]
commit_message_format: "release(v{version})"
develop:
name: "develop"
purpose: "开发集成分支"
base_for_feature_branches: true
sync_with_main: "daily via bot"
feature:
pattern: "feature/{ticket-id}-{short-description}"
source: "develop"
target: "develop"
lifecycle: "delete after merge"
release:
pattern: "release/v{major}.{minor}"
source: "develop"
target: "main + develop"
lifecycle: "delete after release"
hotfix:
pattern: "hotfix/v{major}.{minor}.{patch}"
source: "main"
target: "main + develop"
lifecycle: "delete after merge"
3.3 发布流程详解
## 🚀 MonkeyCode 标准发布流程
### Phase 1: 准备阶段
**触发条件**:
- [ ] develop 分支的所有 PR 已合并
- [ ] CI 全绿
- [ ] 测试覆盖率 ≥ 目标阈值
- [ ] Changelog 已更新
- [ ] 文档已同步更新
**操作步骤**:
1. 从 develop 创建 `release/vX.Y.Z` 分支
2. 更新版本号(所有涉及位置)
3. 运行完整的 Release CI 流水线
### Phase 2: 候选发布(RC)
**RC 发布检查清单**:
- [ ] 所有 Critical/High bug 已修复或接受延期
- [ ] 性能基准测试通过
- [ ] 安全扫描无 High/Critical 发现
- [ ] 向前兼容性验证通过
- [ ] 向后兼容性验证通过
- [ ] 升级路径测试完成(从 N-2 到当前版本)
**RC 发布操作**:
```bash
# 创建 RC tag
git tag -a v1.2.0-rc.1 -m "Release candidate 1 for v1.2.0"
git push origin v1.2.0-rc.1
# GitHub Release(Draft)
gh release create v1.2.0-rc.1 \
--title "v1.2.0-rc.1 (Release Candidate)" \
--notes-file CHANGELOG.md \
--prerelease \
--draft
Phase 3: 正式发布
最终检查:
发布操作:
# 正式 tag
git tag -a v1.2.0 -m "Release v1.2.0"
git push origin v1.2.0
# 合并到 main
# (由 release-bot 或 maintainer 执行)
# GitHub Release
gh release create v1.2.0 \
--title "🎉 MonkeyCode v1.2.0" \
--notes-file RELEASE_NOTES.md \
--generate-notes
# Publish to package registries
npm publish
# 或其他包管理器的发布命令
---
## 四、自动化工具链
### 4.1 Version Automation 配置
```typescript
// .github/version.ts — MonkeyCode 版本自动管理脚本
import { readFileSync, writeFileSync } from 'fs';
import { execSync } from 'child_process';
interface Version {
major: number;
minor: number;
patch: string;
prerelease?: string;
}
export function getCurrentVersion(): Version {
const pkg = JSON.parse(readFileSync('package.json', 'utf-8'));
return parseVersion(pkg.version);
}
export function parseVersion(versionStr: string): Version {
const match = versionStr.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
if (!match) throw new Error(`Invalid version: ${versionStr}`);
return {
major: parseInt(match[1]),
minor: parseInt(match[2]),
patch: match[3],
prerelease: match[4],
};
}
export function bumpVersion(
current: Version,
type: 'major' | 'minor''patch' | 'prerelease'
): Version {
switch (type) {
case 'major':
return { ...current, major: current.major + 1, minor: 0, patch: '0', prerelease: undefined };
case 'minor':
return { ...current, minor: current.minor + 1, patch: '0', prerelease: undefined };
case 'patch':
return { ...current, patch: String(parseInt(current.patch) + 1), prerelease: undefined };
case 'prerelease': {
const prerelease = current.prerelease || 'alpha.0';
const [prefix, num] = prerelease.split('.');
return { ...current, prerelease: `${prefix}.${parseInt(num) + 1}` };
}
}
}
export function updateAllVersionFiles(newVersion: Version): void {
const versionStr = formatVersion(newVersion);
// Update package.json
const pkg = JSON.parse(readFileSync('package.json', 'utf-8'));
pkg.version = versionStr;
writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
// Update Cargo.toml if exists
// Update pyproject.toml if exists
// Update VERSION file
writeFileSync('VERSION', versionStr + '\n');
console.log(`✅ Updated all version files to ${versionStr}`);
}
function formatVersion(v: Version): string {
let result = `${v.major}.${v.minor}.${v.patch}`;
if (v.prerelease) result += `-${v.prerelease}`;
return result;
}
4.2 GitHub Actions Release Workflow
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # 正式版本
- 'v[0-9]+.[0-9]+.[0-9]+-*' # 预发布版本
permissions:
contents: write
packages: write
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
is_prerelease: ${{ steps.version.outputs.is_prerelease }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: version
name: Extract version info
run: |
VERSION=${GITHUB_REF_NAME#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
if [[ "$VERSION" == *-* ]]; then
echo "is_prerelease=true" >> $GITHUB_OUTPUT
else
echo "is_prerelease=false" >> $GITHUB_OUTPUT
fi
build:
needs: prepare
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
artifact_name: monkeycode-linux-amd64
asset_name: monkeycode-${{ needs.prepare.outputs.version }}-linux-amd64.tar.gz
- os: macos-latest
artifact_name: monkeycode-darwin-amd64
asset_name: monkeycode-${{ needs.prepare.outputs.version }}-darwin-amd64.tar.gz
- os: windows-latest
artifact_name: monkeycode-windows-amd64.exe
asset_name: monkeycode-${{ needs.prepare.outputs.version }}-windows-amd64.zip
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- run: npm run package:${{ matrix.os == 'windows-latest' && 'win' || matrix.os == 'macos-latest' && 'mac' || 'linux' }}
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: dist/
release:
needs: [prepare, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: artifacts/
pattern: monkeycode-*
merge-multiple: true
- name: Generate changelog
id: changelog
run: |
# 使用 git-chglog 或自定义脚本生成 changelog
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
node .github/scripts/generate-changelog.js > RELEASE_BODY.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ needs.prepare.outputs.version }}
body_path: RELEASE_BODY.md
draft: false
prerelease: ${{ needs.prepare.outputs.is_prerelease == 'true' }}
files: artifacts/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-npm:
needs: [prepare, build]
runs-on: ubuntu-latest
if: needs.prepare.outputs.is_prerelease != 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
docker-push:
needs: [prepare, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
monkeycode/monkeyCode:${{ needs.prepare.outputs.version }}
${{ needs.prepare.outputs.is_prerelease != 'true' && 'monkeycode/monkeyCode:latest' || '' }}
cache-from: type=gha
cache-to: type=gha,mode=max
4.3 Changelog 自动生成
// .github/scripts/generate-changelog.js
const { execSync } = require('child_process');
const TYPE_EMOJI = {
feat: '✨',
fix: '🐛',
docs: '📝',
style: '💎',
refactor: '♻️',
perf: '⚡',
test: '✅',
build: '📦',
ci: '🔄',
chore: '🔧',
revert: '⏪',
};
const TYPE_LABELS = {
feat: '新功能',
fix: 'Bug 修复',
docs: '文档',
style: '样式',
refactor: '重构',
perf: '性能优化',
test: '测试',
build: '构建',
ci: '持续集成',
chore: '杂项',
revert: '回退',
};
function getCommitsSinceLastTag() {
try {
const lastTag = execSync('git describe --tags --abbrev=0 HEAD^')
.toString().trim();
const log = execSync(
`git log ${lastTag}..HEAD --pretty=format:"%H|%s|%b"`
).toString().trim();
return log.split('\n').map(line => {
const [hash, subject, body] = line.split('|');
return { hash, subject, body };
});
} catch {
return [];
}
}
function parseConventionalCommit(message) {
const match = message.match(/^(\w+)(?:\(([^)]+)\))?!?:\s+(.+)$/);
if (!match) return null;
return {
type: match[1],
scope: match[2] || null,
breaking: message.includes('!'),
description: match[3].trim(),
};
}
function generateChangelog() {
const commits = getCommitsSinceLastTag();
const grouped = {};
commits.forEach(({ subject }) => {
const parsed = parseConventionalCommit(subject);
if (!parsed) return;
const type = parsed.type in TYPE_LABELS ? parsed.type : 'chore';
if (!grouped[type]) grouped[type] = [];
const entry = `${TYPE_EMOJI[type]} **${parsed.description}`;
if (parsed.scope) entry += \` (\${parsed.scope})\`;
if (parsed.breaking) entry += ' **⚠️ BREAKING';
entry += '**';
grouped[type].push(entry);
});
let output = '## What\'s Changed\n\n';
Object.entries(grouped).forEach(([type, items]) => {
output += \`### \${TYPE_LABELS[type]}\n\n\`;
items.forEach(item => { output += \`- \${item}\n\`; });
output += '\n';
});
return output;
}
console.log(generateChangelog());
五、发布节奏与策略
5.1 MonkeyCode 发布日历
release_rhythm:
regular_releases:
schedule: "每两周一次(周二)"
version_type: "MINOR or PATCH"
content: "累积的功能和修复"
freeze_period: "发布前 3 天代码冻结"
lts_releases:
schedule: "每季度一次"
version_type: "LTS (Long Term Support)"
support_duration: "18 个月"
criteria: "经过充分验证的稳定版本"
security_patches:
trigger: "Critical/High 安全漏洞发现"
response_time: "< 48 小时(Critical)/< 7 天(High)"
version_type: "PATCH on latest LTS"
emergency_hotfixes:
trigger: "生产环境阻断性问题"
approval: "需要 ≥2 maintainers 批准"
version_type: "PATCH"
post_release: "必须包含回归测试计划"
5.2 发布窗口管理
MonkeyCode 2026 H2 发布日历:
7月 ───┬── 8月 ───┬── 9月 ───┬── 10月 ──┬── 11月 ──┬── 12月 ──
│ │ │ │ │ │
Week 1 │ │ │ │ │ │
Week 2 │ 🔵v1.3.0 │ │ 🔵v1.4.0 │ │ 🔵v1.5.0 │
Week 3 │ │ │ │ │ │
Week 4 │ │ 🟢LTS1.2 │ │ │ │ 🟢LTS1.5
图例:
🔵 定期发布(双周)
🟢 LTS 季度发布
🔴 紧急热修复(按需)
六、版本兼容性与迁移
6.1 兼容性矩阵
-- MonkeyCode 版本兼容性查询视图
CREATE VIEW version_compatibility AS
SELECT
v.version,
v.release_date,
v.status,
v.support_until,
CASE
WHEN v.status = 'lts' THEN '18 months from release'
WHEN v.status = 'stable' THEN '6 months from next minor'
ELSE '3 months from release'
END AS support_policy,
ARRAY(
SELECT DISTINCT api_version
FROM api_changes ac
WHERE ac.version_from <= v.version
AND ac.version_to >= v.version
AND ac.change_type != 'breaking'
) AS compatible_api_versions,
COUNT(CASE WHEN ac.change_type = 'breaking' THEN 1 END) AS breaking_changes_count
FROM versions v
LEFT JOIN api_changes ac ON v.version = ac.version_to
WHERE v.release_date >= CURRENT_DATE - INTERVAL '2 years'
GROUP BY v.version, v.release_date, v.status, v.support_until
ORDER BY v.release_date DESC;
6.2 Deprecation 流程
## 📋 MonkeyCode API 废弃标准流程
### 时间线
T=0 宣布废弃(在 Changelog 和文档中标注 @deprecated)
↓
T+2周 发送废弃通知(GitHub Discussion + Discord 公告)
↓
T+1版本 新版本中标记为 deprecated(编译时警告)
↓
T+2版本 保留功能但默认禁用(需显式启用)
↓
T+3版本 完全移除(Breaking Change,进入下一个 MAJOR 版本)
### 废弃声明模板
```typescript
/**
* @deprecated Since v1.3.0. Will be removed in v2.0.0.
* Use `generateCodeWithConfig()` instead.
*
* Migration guide: https://docs.monkeyCode.dev/migration/v1-to-v2
* Discussion: https://github.com/monkeyCode/discussions/42
*
* @reason The old API doesn't support streaming responses and has
* limited configuration options. The new API provides a
* more flexible and future-proof interface.
*/
export function generateCodeLegacy(prompt: string): Promise<string> {
console.warn(
'[MonkeyCode] generateCodeLegacy is deprecated since v1.3.0. ' +
'Use generateCodeWithConfig instead. ' +
'See: https://docs.monkeyCode.dev/migration/v1-to-v2'
);
// ... legacy implementation
}
---
## 七、多包/多仓库版本协调
### 7.1 Monorepo 版本策略
```json
{
"name": "monkeyCode",
"version": "1.3.0",
"private": true,
"workspaces": [
"packages/*",
"apps/*",
"tools/*"
],
"packages": {
"@monkeyCode/core": { "version": "1.3.0", "public": true },
"@monkeyCode/cli": { "version": "1.3.0", "public": true },
"@monkeyCode/server": { "version": "1.3.0", "public": true },
"@monkeyCode/plugin-system": { "version": "1.3.0", "public": true },
"@monkeyCode/ui": { "version": "1.3.0", "public": true },
"@monkeyCode/config-types": { "version": "1.3.0", "public": true },
"monkeyCode-vscode-extension": { "version": "1.3.0", "public": true },
"@monkeyCode/eslint-config": { "version": "1.3.0", "public": true },
"@monkeyCode/testing-utils": { "version": "1.3.0", "public": false },
"@monkeyCode/scripts": { "version": "1.3.0", "public": false }
}
}
7.2 版本联动规则
monorepo_version_rules:
synchronization:
mode: "single source of truth"
source: "root package.json version"
propagation: "all packages inherit root version"
tool: "changesets (for independent versioning when needed)"
dependency_updates:
internal_deps: "auto-bump to same version on release"
external_deps: "manual review during release prep"
peer_deps: "must match major version range"
publishing_order:
order:
- "@monkeyCode/config-types" # 无内部依赖
- "@monkeyCode/core" # 核心逻辑
- "@monkeyCode/plugin-system" # 依赖 core
- "@monkeyCode/server" # 依赖 core + plugins
- "@monkeyCode/cli" # 依赖 server
- "@monkeyCode/ui" # 独立 UI 组件
- "monkeyCode-vscode-extension" # 依赖 cli
- "@monkeyCode/eslint-config" # 开发工具
validation: "integration tests after each publish"
八、监控与度量
8.1 版本健康仪表盘指标
# version_health.py — MonkeyCode 版本健康度计算
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import List, Optional
@dataclass
class VersionMetrics:
version: str
release_date: datetime
days_since_release: int
open_issues: int
critical_bugs: int
adoption_rate: float # 0-1
avg_time_to_upgrade: Optional[int] # days from previous version
churn_rate: float # % of users downgrading
satisfaction_score: Optional[float] # 1-5 from surveys
def health_score(self) -> int:
"""计算版本健康分数 (0-100)"""
score = 100
# Bug penalty
score -= self.critical_bugs * 15
score -= min(self.open_issues * 2, 30)
# Age factor (newer is better for recent releases)
if self.days_since_release < 30:
score += 10
elif self.days_since_release > 180:
score -= 10
# Adoption bonus
score += int(self.adoption_rate * 20)
# Satisfaction factor
if self.satisfaction_score:
score += int((self.satisfaction_score - 3) * 10)
# Churn penalty
score -= int(self.churn_rate * 30)
return max(0, min(100, score))
def status(self) -> str:
health = self.health_score()
if health >= 80: return "🟢 Healthy"
elif health >= 60: return "🟡 Warning"
elif health >= 40: return "🟠 At Risk"
else: return "🔴 Critical"
def generate_version_report(versions: List[VersionMetrics]) -> str:
"""生成版本健康报告"""
report = "# MonkeyCode Version Health Report\n\n"
report += f"Generated: {datetime.now().isoformat()}\n\n"
report += "| Version | Age | Issues | Critical | Adoption | Health | Status |\n"
report += "|---------|-----|--------|----------|----------|--------|--------|\n"
for v in sorted(versions, key=lambda x: x.release_date, reverse=True):
report += (
f"| {v.version} "
f"| {v.days_since_release}d "
f"| {v.open_issues} "
f"| {v.critical_bugs} "
f"| {v.adoption_rate:.0%} "
f"| {v.health_score()} "
f"| {v.status()} |\n"
)
return report
8.2 发布质量门禁
release_quality_gates:
pre_release_gates:
- name: "Test Coverage"
threshold: ">= 80%"
blocking: true
measurement: "codecov/patch"
- name: "Critical Bugs"
threshold: "== 0"
blocking: true
scope: "current release scope"
- name: "Security Scan"
threshold: "No HIGH/CRITICAL"
blocking: true
tools: ["CodeQL", "Dependabot", "Snyk"]
- name: "Performance Regression"
threshold: "< 5% degradation"
blocking: false
warning_only: true
- name: "Documentation Coverage"
threshold: ">= 90% APIs documented"
blocking: false
post_release_monitoring:
- name: "Error Rate Spike"
threshold: "< 2x baseline within 24h"
alert_channel: "#ops-alerts"
- name: "Adoption Rate"
threshold: "> 10% within 7 days"
comparison: "vs previous version"
- name: "Support Ticket Volume"
threshold: "< 1.5x baseline"
tracking_period: "14 days"
九、常见问题与解决方案
9.1 FAQ
## ❓ 常见问题
### Q1: 什么时候应该发布 Major 版本?
**A**: 当你需要做以下任一操作时:
- 删除或改变现有公共 API 的行为
- 改变配置文件的格式(不可向前兼容)
- 更改 CLI 命令的参数结构
- 移除某个已存在的功能模块
**最佳实践**:使用废弃期(至少 2 个 minor 版本)给用户足够的迁移时间。
### Q2: Hotfix 应该如何处理?
**A**:
1. 从 main 创建 `hotfix/vX.Y.Z` 分支
2. 修复问题并添加测试
3. 合并回 main 并打 tag
4. 同时 cherry-pick 回 develop 分支
5. 发布 Hotfix 版本(PATCH 版本号递增)
### Q3: 如何处理预发布版本的依赖?
**A**:
- 预发布版本应使用 `~` (tilde) 范围锁定
- 例如 `"@monkeyCode/core": "~1.3.0-alpha.1"`
- 正式发布时切换到 `^` (caret) 范围
### Q4: 版本号泄露了怎么办?
**A**:
- 如果是 pre-release:直接删除 tag 和 release,重新发布
- 如果是正式版本且未广泛传播:同上
- 如果已经有人在使用:发布 PATCH 版本修复,并在 Changelog 中说明
### Q5: Monorepo 中如何处理独立版本?
**A**:
- 默认模式:所有包共享根版本号(推荐)
- 特殊情况:使用 changesets 进行独立版本控制
- 内部工具包可以跟随主版本,不需要独立发版
十、总结与行动号召
10.1 核心要点回顾
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 📦 MonkeyCode 版本管理七大原则 ║
║ ║
║ 1️⃣ 严格 SemVer — MAJOR/MINOR/PATCH 含义明确 ║
║ 2️⃣ 自动化优先 — 手动改版本号是错误之源 ║
║ 3️⃣ Changelog 必要 — 每次发布都有清晰的变更记录 ║
║ 4️⃣ 分支保护 — main 分支受严格保护 ║
║ 5️⃣ 发布节奏稳定 — 用户可以预期和规划 ║
║ 6️⃣ 废弃有流程 — 给用户足够的时间迁移 ║
║ 7️⃣ 监控反馈 — 发布后的健康度持续追踪 ║
║ ║
╚═══════════════════════════════════════════════════════════╝
10.2 如何参与?
- 💬 讨论版本策略:前往 GitHub Discussions 参与 RFC 讨论
- 🐛 报告版本相关问题:提交 Issue 时标注
area: versioning标签 - 🔧 贡献改进:我们欢迎更好的 changelog 生成器、版本检查工具等贡献
- 📖 阅读更多:查看 MonkeyCode 贡献指南
现在就访问 MonkeyCode GitHub,查看最新版本,或为下一个版本贡献力量!
本文最后更新于 2026 年 7 月 1 日。版本号不是数字游戏,而是对用户的承诺。
相关文章推荐:
© 2026 MonkeyCode Open Source Project. Licensed under Apache License 2.0.
Discord: https://discord.gg/monkeyCode | Twitter/X: @monkeyCode_dev
浙公网安备 33010602011771号