跳到主要内容

项目版本号管理与发布策略

· 阅读需 6 分钟
XingHunm
Tech Enthusiast

本文介绍项目版本号管理的最佳实践,包括语义化版本规范、版本号演进流程、正式版本发布策略、以及如何在不同技术栈中实现版本管理自动化。涵盖从开发环境到生产环境的完整版本控制方案。

1. 版本号规范

项目遵循 语义化版本(Semantic Versioning 2.0.0) 规范:

MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]
  • MAJOR(主版本号):存在不兼容的 API 或重大功能变更时递增
  • MINOR(次版本号):新增功能且兼容旧版本时递增
  • PATCH(修订号):仅做向后兼容的问题修复时递增
  • PRERELEASE(预发布号):标识测试版、候选版(可选)
  • BUILD(构建号):构建或提交标识(可选)

示例:

类型示例说明
开发版本1.0.0-dev.20251103每日构建或开发测试版本
内部测试版1.0.0-alpha.5功能不完整,仅供内部使用
公测版1.0.0-beta.3功能完整但仍可能存在问题
候选版1.0.0-rc.1即将发布的版本,若无问题即转正
正式版1.0.0对外正式发布版本
修复版1.0.1仅修复问题
功能更新1.1.0新增兼容性功能
不兼容更新2.0.0有重大变更或接口修改

2. 版本号演进流程

版本从开发到发布的生命周期:

dev → alpha → beta → rc → release
阶段命名规则使用场景
开发阶段x.y.z-dev.N开发环境构建,内部自测
内部测试x.y.z-alpha.N内部 QA 测试版本
公测阶段x.y.z-beta.N外部试用或小范围测试
发布候选x.y.z-rc.N准备上线,若无阻塞问题即发布为正式版
正式发布x.y.z稳定版本,公开分发
后续修复x.y.(z+1)Bug 修复或安全更新

3 正式版本发布策略

3.1 预发布版本到正式版的转化

x.y.z-rc.N 测试通过后,发布脚本自动去掉 -rc.N 后缀,生成正式版本:

1.0.0-rc.3 → 1.0.0

2. 不跳号策略

版本号递增必须连续,禁止跳过或回退版本号:

✅:1.0.0 → 1.0.1 → 1.1.0 → 2.0.0
❌: 1.0.0 → 2.0.5(中间版本不存在)

3. 版本号来源

3.1 不同技术栈的版本存储位置

基础版本号存储位置因项目技术栈而异:

技术栈版本号存储位置常用工具
Node.jspackage.json 中的 version 字段standard-version, semantic-release
Pythonpyproject.tomlsetup.py__version__.pybump2version, poetry, setuptools-scm
Java (Maven)pom.xml<version>Maven Versions Plugin
Java (Gradle)build.gradlegradle.propertiesGradle version task
RustCargo.tomlpackage.versioncargo bump
GoGit tag(模块版本由 tag 决定)git tag
.NET*.csprojDirectory.Build.propsGitVersion
Androidbuild.gradleversionName/versionCodeGradle task
iOSInfo.plistCFBundleShortVersionStringagvtool, fastlane
容器/HelmChart.yamlversion/appVersionhelm package
通用方案项目根目录的 VERSION 文件自定义脚本

3.2 单一来源策略

版本号必须有且仅有一个权威来源,所有其他位置的版本号都从该来源派生或校验一致。

策略 A:文件为来源(推荐用于应用/服务)

  • 版本号定义在清单文件中(如 package.jsonpom.xmlCargo.tomlVERSION
  • 发布流程:更新文件版本 → 提交代码 → 打 Git tag → 发布
  • CI 负责校验 Git tag 与文件版本一致

策略 B:Tag 为来源(常见于库/SDK、Go 模块)

  • 版本号由 Git tag(如 v1.2.3)决定
  • 发布流程:打 Git tag → CI 从 tag 解析版本 → 注入到构建产物
  • 适用场景:Go 模块、Python + setuptools-scm、版本不需内嵌到应用的库

核心原则

  • 发布必须打 Git tag 作为锚点
  • 禁止文件版本与 tag 版本漂移
  • CI 在构建时强制校验版本一致性

3.3 CI 校验示例

策略 A:文件为来源,校验 tag 一致性
#!/bin/bash
set -e

# 从文件读取版本(根据项目类型自动检测)
if [ -f "package.json" ]; then
FILE_VERSION=$(node -p "require('./package.json').version")
elif [ -f "Cargo.toml" ]; then
FILE_VERSION=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2)
elif [ -f "VERSION" ]; then
FILE_VERSION=$(cat VERSION)
else
echo "Error: No version file found" >&2
exit 1
fi

# 如果存在 Git tag,校验一致性
TAG_VERSION=${GIT_TAG:-$(git describe --tags --exact-match 2>/dev/null || true)}
if [ -n "$TAG_VERSION" ]; then
TAG_VERSION=${TAG_VERSION#v} # 移除 'v' 前缀
if [ "$FILE_VERSION" != "$TAG_VERSION" ]; then
echo "❌ Version mismatch: file=$FILE_VERSION, tag=$TAG_VERSION" >&2
exit 1
fi
echo "✅ Version validated: $FILE_VERSION"
fi

export BASE_VERSION="$FILE_VERSION"
策略 B:Tag 为来源,注入到构建
#!/bin/bash
set -e

# 从 Git tag 获取版本
TAG_VERSION=${GIT_TAG:-$(git describe --tags --abbrev=0)}
BASE_VERSION=${TAG_VERSION#v} # 移除 'v' 前缀

# 导出环境变量供后续构建使用
export BASE_VERSION
echo "BASE_VERSION=$BASE_VERSION"

# 可选:写入到构建产物(如生成 version.txt)
echo "$BASE_VERSION" > version.txt

3.4 完整版本号生成示例

CI/CD 根据基础版本和构建环境,自动生成带预发布信息的完整版本号:

环境基础版本生成规则最终版本号
开发环境1.0.0${BASE}-dev.${DATE}.${BUILD_NUM}1.0.0-dev.20251103.123
测试环境1.0.0${BASE}-beta.${BUILD_NUM}1.0.0-beta.5
预发布1.0.0${BASE}-rc.${BUILD_NUM}1.0.0-rc.1
生产环境1.0.0${BASE}(仅正式版打 tag)1.0.0

4. 自动生成规则(Jenkins/CI)

#!/bin/bash
set -e

BASE_VERSION=$(cat VERSION)
BUILD_DATE=$(date +%Y%m%d)
BUILD_NUMBER=${BUILD_NUMBER:-0}

case "$BUILD_ENV" in
dev)
VERSION_FULL="${BASE_VERSION}-dev.${BUILD_DATE}.${BUILD_NUMBER}"
;;
test)
VERSION_FULL="${BASE_VERSION}-beta.${BUILD_NUMBER}"
;;
rc)
VERSION_FULL="${BASE_VERSION}-rc.${BUILD_NUMBER}"
;;
prod)
VERSION_FULL="${BASE_VERSION}"
;;
*)
echo "Unknown BUILD_ENV: $BUILD_ENV"
exit 1
;;
esac

echo "Final version: ${VERSION_FULL}"

5. Git 标签规范

类型Tag 示例说明
Alpha 测试版v1.0.0-alpha.3内部测试
Beta 公测版v1.0.0-beta.2公测阶段
RC 候选版v1.0.0-rc.1最终预发布
正式发布版v1.0.0对外版本

6. 版本号管理建议

  • 不直接使用测试版号作为正式版
  • 构建号自动生成,不手动递增数字
  • 每个版本必须有 Git tag
  • 应用 About 页面或 API 返回中应展示版本号
  • 仅在必要时增加主版本号

7. 示例版本演进图

0.9.0-alpha.1
0.9.0-alpha.2
0.9.0-beta.1
0.9.0-beta.2
1.0.0-rc.1
1.0.0
1.0.1
1.1.0
2.0.0

8. 总结

阶段示例版本号是否公开自动生成用途
开发1.0.0-dev.20251103内部开发调试
内测1.0.0-alpha.5QA 内部测试
公测1.0.0-beta.2可选小范围用户测试
候选1.0.0-rc.1上线前最后验证
正式1.0.0最终公开发布
修复1.0.1Bug 修复