如何通过Bitbucket Pipelines与分支实现语义化版本控制?
我之前刚好帮团队落地过这套方案,完美适配MAJOR.MINOR.PATCH.BUILD的语义化版本需求,还通过Bitbucket Pipelines实现了全自动化,分享给你具体步骤:
核心思路
咱们把版本号拆成两部分管理:前三个段(MAJOR/MINOR/PATCH)靠手动打标签控制(比如大版本迭代、功能更新、bug修复时手动升级),BUILD段交给Bitbucket Pipelines自动递增——每次流水线跑起来就自动+1,既保留语义化版本的可读性,又不用手动维护构建号。
步骤1:先打个初始版本标签
先给仓库创建第一个基础版本标签,格式用vMAJOR.MINOR.PATCH.BUILD,方便后续脚本识别:
git tag -a v1.0.0.0 -m "Initial version" git push origin v1.0.0.0
步骤2:编写自动生成版本号的脚本
在项目根目录新建generate_version.sh脚本,它会自动读取仓库最新的版本标签,将BUILD段自动加1:
#!/bin/bash # 拉取最新的符合格式的版本标签 LATEST_TAG=$(git describe --abbrev=0 --tags 2>/dev/null | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$") if [ -z "$LATEST_TAG" ]; then # 如果仓库还无标签,默认初始版本 echo "1.0.0.0" else # 拆分版本号各段 TAG_WITHOUT_V=${LATEST_TAG#v} MAJOR=$(echo $TAG_WITHOUT_V | cut -d. -f1) MINOR=$(echo $TAG_WITHOUT_V | cut -d. -f2) PATCH=$(echo $TAG_WITHOUT_V | cut -d. -f3) BUILD=$(echo $TAG_WITHOUT_V | cut -d. -f4) # BUILD段自动递增 NEW_BUILD=$((BUILD + 1)) # 输出新版本号 echo "${MAJOR}.${MINOR}.${PATCH}.${NEW_BUILD}" fi
给脚本添加执行权限:
chmod +x generate_version.sh
步骤3:配置Bitbucket Pipelines自动化流程
在项目根目录创建bitbucket-pipelines.yml,让流水线每次运行时自动生成版本号、打标签并推回仓库:
image: atlassian/default-image:3 pipelines: default: - step: name: 生成并推送新版本标签 script: # 拉取所有标签,确保获取到最新版本 git fetch --tags # 调用脚本生成新版本号 NEW_VERSION=$(./generate_version.sh) echo "本次构建版本号: $NEW_VERSION" # 打新标签 git tag -a v$NEW_VERSION -m "自动生成版本: $NEW_VERSION" # 推送标签到仓库(默认Pipelines账户已有写入权限,若失败可去仓库设置检查) git push origin v$NEW_VERSION # 可选:仅在主分支触发,避免分支构建乱打标签 branches: master: - step: *生成并推送新版本标签
小提示:如果遇到标签推送失败,可前往仓库的
Settings > Pipelines检查构建账户的权限,确保拥有推送标签的权限。
步骤4:手动升级MAJOR/MINOR/PATCH段
当你需要做大版本迭代(如v1→v2)、新增功能(如v1.0→v1.1)或修复bug(如v1.0.0→v1.0.1)时,手动打指定版本的标签即可:
git tag -a v2.1.0.0 -m "发布2.1.0版本" git push origin v2.1.0.0
之后流水线会基于这个标签自动递增BUILD号,生成v2.1.0.1、v2.1.0.2这类版本。
可选:将版本号嵌入Python应用
如果想让Python应用直接获取当前版本号,可在setup.py或项目的__init__.py中添加以下代码:
import subprocess def get_version(): try: # 调用脚本获取版本号 result = subprocess.run(["./generate_version.sh"], capture_output=True, text=True, check=True) return result.stdout.strip() except Exception: # 脚本异常时用默认版本兜底 return "1.0.0.0" __version__ = get_version()
这样在应用中直接调用__version__就能拿到最新的自动化版本号了。
内容的提问来源于stack exchange,提问作者Ludo

