自动化使用 Bash 脚本进行 Git 标签版本控制

本文介绍如何使用Bash脚本自动化Git标签的创建过程,包括验证仓库、获取版本号、递增版本并更新清单文件,适用于CI/CD工作流,提高团队协作效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用 Git 标签对源代码进行版本控制不难手动完成,但也很容易自动化,这意味着:

  • 您可以将其用于 CI/CD 流程
  • 减少团队协作时出错的机会
  • 节省搜索或查找步骤的时间,以防您忘记了

我将向您展示如何使用一个简单的 Bash 脚本来自动化这个过程。

本文假定您具备基本的 Git 标签语义化版本 的知识。

手动版本控制过程

在我们自动化这个过程之前,让我们首先看一下如何手动使用 Git 标签对源代码进行版本控制。

一般来说,基本的步骤如下:

  1. 修改您的源代码,并准备发布一个新版本
  2. 在项目文件中递增版本号,例如,Node 项目的 package.json
  3. 提交您的更改到 Git
  4. 为具有新版本号的提交创建 Git 标签,例如 v1.0.4
  5. 推送您的提交和标签到远程存储库

根据这些步骤,除了第一步,我们可以自动化所有其他步骤。

自动化版本控制步骤

基于上述步骤,让我们拆分脚本之前所需的不同部分。

验证 Git 本地仓库是否干净

在我们开始对本地仓库进行自动更改之前,最好验证它是否处于干净状态。

# 列出未提交的更改,并检查输出是否为空
if [ -n "$(git status --porcelain)" ]; then
# 打印错误消息
printf "\\n错误:仓库中有未提交的更改\\n\\n"
# 以错误代码退出
exit 1
fi

从 Git 标签获取最新版本

为了递增版本号,我们需要知道上一个版本是什么。有两种方法可以获取它:

  • 从我们的清单文件,例如 package.jsonCargo.toml
  • 从以前的 Git 标签

我更喜欢后者,有几个原因:

  • 不依赖于特定的编程语言和环境
  • 将 Git 标签作为我们版本的真相源保持不变
# 按语义版本排序列出 Git 标签
GIT_TAGS=$(git tag --sort=version:refname)

# 获取输出的最后一行,它返回最后一个标签(最新版本)
GIT_TAG_LATEST=$(echo "$GIT_TAGS" | tail -n 1)

# 如果没有找到标签,默认为 v0.0.0
if [ -z "$GIT_TAG_LATEST" ]; then
  GIT_TAG_LATEST="v0.0.0"
fi

# 从标签中删除前缀 'v' 以便轻松递增
GIT_TAG_LATEST=$(echo "$GIT_TAG_LATEST" | sed 's/^v//')

递增我们的版本号

我们将支持三种类型的版本递增:

  • 修订版本:v1.0.0 -> v1.0.1
  • 次要版本:v1.0.0 -> v1.1.0
  • 主要版本:v1.0.0 -> v2.0.0

脚本将接受一个确定如何递增版本号的参数。然后使用 awk 递增版本的正确部分,根据需要将后续部分归零。

# 从传递给脚本的第一个参数获取版本类型
VERSION_TYPE="${1-}"
VERSION_NEXT=""

if [ "$VERSION_TYPE" = "patch" ]; then
# 递增修订版本
  VERSION_NEXT="$(echo "$GIT_TAG_LATEST" | awk -F. '{$NF++; print $1"."$2"."$NF}')"
elif [ "$VERSION_TYPE" = "minor" ]; then
# 递增次要版本
  VERSION_NEXT="$(echo "$GIT_TAG_LATEST" | awk -F. '{$2++; $3=0; print $1"."$2"."$3}')"
elif [ "$VERSION_TYPE" = "major" ]; then
# 递增主要版本
  VERSION_NEXT="$(echo "$GIT_TAG_LATEST" | awk -F. '{$1++; $2=0; $3=0; print $1"."$2"."$3}')"
else
# 为未知的版本类型打印错误
printf "\\n错误:传递的 VERSION_TYPE 参数无效,必须是 'patch'、'minor' 或 'major'\\n\\n"
# 以错误代码退出
exit 1
fi

更新清单文件中的版本号

此步骤是可选的,但对于保持事物同步是一个好主意。

最好在您的清单文件中(如 package.jsonCargo.toml)更新版本号。这里有两个示例,您可以修改并适应其他文件。

package.json

# 更新 package.json 中的版本
sed -i "s/\\"version\\": \\".*\\"/\\"version\\": \\"$VERSION_NEXT\\"/" package.json

# 提交更改
git add .
git commit -m "build: bump package.json version - v$VERSION_NEXT"

Cargo.toml

# 在 Cargo.toml 中更新版本
sed -i "s/^version = .*/version = \\"$VERSION_NEXT\\"/" Cargo.toml

# 更新 Cargo.lock,因为在清单中更新版本时,它也会更改
cargo generate-lockfile

# 提交更改
git add .
git commit -m "build: bump Cargo.toml version - v$VERSION_NEXT"

创建 Git 标签

现在,其他一切都准备好了,我们

可以为新版本创建 Git 标签。

# 创建带注释的标签
git tag -a "v$VERSION_NEXT" -m "发布:v$VERSION_NEXT"

# 可选:将提交和标签推送到远程的 'main' 分支
git push origin main --follow-tags

完整的版本控制脚本

现在,我们了解了所有单独的步骤,我们可以将它们汇总到一起。

version.sh

#!/usr/bin/env bash

# 如果命令失败或使用了未初始化的变量,退出脚本
set -euo pipefail

# ==================================
# 验证仓库是否干净
# ==================================

# 列出未提交的更改,并检查输出是否为空
if [ -n "$(git status --porcelain)" ]; then
# 打印错误消息
printf "\\n错误:仓库中有未提交的更改\\n\\n"
# 以错误代码退出
exit 1
fi

# ==================================
# 从 Git 标签获取最新版本
# ==================================

# 按语义版本排序列出 Git 标签
GIT_TAGS=$(git tag --sort=version:refname)

# 获取输出的最后一行,它返回最后一个标签(最新版本)
GIT_TAG_LATEST=$(echo "$GIT_TAGS" | tail -n 1)

# 如果没有找到标签,默认为 v0.0.0
if [ -z "$GIT_TAG_LATEST" ]; then
  GIT_TAG_LATEST="v0.0.0"
fi

# 从标签中删除前缀 'v' 以便轻松递增
GIT_TAG_LATEST=$(echo "$GIT_TAG_LATEST" | sed 's/^v//')

# ==================================
# 递增版本号
# ==================================

# 从传递给脚本的第一个参数获取版本类型
VERSION_TYPE="${1-}"
VERSION_NEXT=""

if [ "$VERSION_TYPE" = "patch" ]; then
# 递增修订版本
  VERSION_NEXT="$(echo "$GIT_TAG_LATEST" | awk -F. '{$NF++; print $1"."$2"."$NF}')"
elif [ "$VERSION_TYPE" = "minor" ]; then
# 递增次要版本
  VERSION_NEXT="$(echo "$GIT_TAG_LATEST" | awk -F. '{$2++; $3=0; print $1"."$2"."$3}')"
elif [ "$VERSION_TYPE" = "major" ]; then
# 递增主要版本
  VERSION_NEXT="$(echo "$GIT_TAG_LATEST" | awk -F. '{$1++; $2=0; $3=0; print $1"."$2"."$3}')"
else
# 为未知的版本类型打印错误
printf "\\n错误:传递的 VERSION_TYPE 参数无效,必须是 'patch'、'minor' 或 'major'\\n\\n"
# 以错误代码退出
exit 1
fi

# ==================================
# 更新清单文件中的版本号(可选)
# 假设是 Rust 项目,有 Cargo.toml 文件,根据您的项目需要进行修改
# ==================================

# 在 Cargo.toml 中更新版本
sed -i "s/^version = .*/version = \\"$VERSION_NEXT\\"/" Cargo.toml

# 更新 Cargo.lock,因为在清单中更新版本时,它也会更改
cargo generate-lockfile

# 提交更改
git add .
git commit -m "build: bump Cargo.toml version - v$VERSION_NEXT"

# ==================================
# 为新版本创建 Git 标签
# ==================================

# 创建带注释的标签
git tag -a "v$VERSION_NEXT" -m "发布:v$VERSION_NEXT"

# 可选:将提交和标签推送到远程的 'main' 分支
git push origin main --follow-tags

现在,只需执行脚本:

# 递增版本
bash ./version.sh patch
bash ./version.sh minor
bash ./version.sh major

# 使脚本具有可执行权限,以便无需使用 bash 执行
chmod +x ./version.sh
./version.sh patch

至此,使用 Git 标签管理版本控制就是这么简单!


请注意,这是翻译后的文档,其中包含了英文原文中的链接和代码示例。如果您需要进一步的修改或有特定的格式要求,请随时告诉我,我将根据您的需求进行调整。
Git指令的Shell脚本,能够快速便捷地管理Git库,包括添加修改、提交修改、显示库状态、推送到远程库、从远程库更新到本地、版本恢复等操作。 使用方法: 1. 在Linux系统中,将本文件放在Git库目录下,利用Shell运行本文件; 2.在windows系统中,需下载安装与操作系统相对应的Git软件,并将本文件放在Git库目录下,双击即可运行。 运行示例: Please choose the first letter of options. [Add|Commit|Diff|Fetch|Exit|Help|Log|Push|User|Reset|Status]? h A: Add all changes to repository. C: Commit all changes to repository. D: Show differences between current version with HEAD->. E: Exit shell script. F: Fetch origin/master and merge. L: Show latest two-weeks logs of repository. P: Push commissions to origin/master. U: User command mode(Press ‘Enter’ to exit). R: Reset current version according version_id. S: Show status of repository. Please choose the first letter of options. [Add|Commit|Diff|Fetch|Exit|Help|Log|Push|User|Reset|Status]? s On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: Git.sh modified: PyNote/PyNote_2.md no changes added to commit (use "git add" and/or "git commit -a") Please choose the first letter of options. [Add|Commit|Diff|Fetch|Exit|Help|Log|Push|User|Reset|Status]? a On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD ..." to unstage) modified: Git.sh modified: PyNote/PyNote_2.md
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值