版本管理脚本#
脚本说明#
版本管理脚本用于管理项目版本,包括版本号管理、Git标签管理、变更日志生成等。
脚本代码#
#!/bin/bash
# 版本管理脚本
# 功能:管理项目版本、Git标签、变更日志
# 作者:System Admin
# 日期:2024-01-01
set -euo pipefail
# 配置变量
PROJECT_DIR=""
VERSION_FILE="version.txt"
CHANGELOG_FILE="CHANGELOG.md"
VERSION_TYPE="patch"
COMMIT_MESSAGE=""
DRY_RUN=false
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log() {
local level=$1
shift
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $@"
}
log_info() {
log "INFO" "$@"
}
log_error() {
log "ERROR" "$@"
}
# 检查项目目录
check_project_dir() {
if [ ! -d "$PROJECT_DIR" ]; then
log_error "项目目录不存在: $PROJECT_DIR"
return 1
fi
return 0
}
# 检查Git仓库
check_git_repo() {
if [ ! -d ".git" ]; then
log_error "不是Git仓库"
return 1
fi
return 0
}
# 获取当前版本
get_current_version() {
local dir=$1
if [ -f "$dir/$VERSION_FILE" ]; then
cat "$dir/$VERSION_FILE"
else
echo "0.0.0"
fi
}
# 解析版本号
parse_version() {
local version=$1
local major=$(echo "$version" | cut -d. -f1)
local minor=$(echo "$version" | cut -d. -f2)
local patch=$(echo "$version" | cut -d. -f3)
echo "$major $minor $patch"
}
# 计算新版本号
calculate_new_version() {
local current_version=$1
local version_type=$2
local major minor patch
read major minor patch <<< $(parse_version "$current_version")
case $version_type in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
*)
log_error "无效的版本类型: $version_type"
return 1
;;
esac
echo "${major}.${minor}.${patch}"
}
# 更新版本号
update_version() {
local dir=$1
local new_version=$2
log_info "更新版本号: $new_version"
echo "$new_version" > "$dir/$VERSION_FILE"
# 更新package.json
if [ -f "$dir/package.json" ]; then
sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$new_version\"/" "$dir/package.json"
fi
# 更新setup.py
if [ -f "$dir/setup.py" ]; then
sed -i "s/version='[^']*'/version='$new_version'/" "$dir/setup.py"
fi
# 更新pyproject.toml
if [ -f "$dir/pyproject.toml" ]; then
sed -i "s/version = \"[^\"]*\"/version = \"$new_version\"/" "$dir/pyproject.toml"
fi
log_info "版本号更新完成"
}
# 创建Git标签
create_git_tag() {
local version=$1
local message=$2
log_info "创建Git标签: v$version"
if [ "$DRY_RUN" = true ]; then
log_info "[DRY RUN] 将创建标签: v$version"
return 0
fi
# 创建标签
git tag -a "v$version" -m "$message"
# 推送标签
git push origin "v$version"
log_info "Git标签创建完成"
}
# 获取Git提交历史
get_git_commits() {
local since_tag=$1
if [ -z "$since_tag" ]; then
git log --pretty=format:"%h - %s (%an, %ar)" --no-merges
else
git log --pretty=format:"%h - %s (%an, %ar)" --no-merges "$since_tag..HEAD"
fi
}
# 生成变更日志
generate_changelog() {
local dir=$1
local version=$2
local version_type=$3
log_info "生成变更日志: $version"
local changelog_file="$dir/$CHANGELOG_FILE"
local date=$(date +%Y-%m-%d)
local previous_version=$(get_current_version "$dir")
# 获取Git提交历史
local commits=$(get_git_commits "v$previous_version")
# 生成变更日志
local new_changelog="## [$version] - $date\n\n"
case $version_type in
major)
new_changelog+="### Breaking Changes\n\n"
;;
minor)
new_changelog+="### Added\n\n"
;;
patch)
new_changelog+="### Fixed\n\n"
;;
esac
new_changelog+="$commits\n\n"
# 更新变更日志文件
if [ -f "$changelog_file" ]; then
# 在文件开头插入新内容
local existing_content=$(cat "$changelog_file")
echo -e "$new_changelog$existing_content" > "$changelog_file"
else
echo -e "$new_changelog" > "$changelog_file"
fi
log_info "变更日志生成完成"
}
# 显示版本信息
show_version_info() {
local dir=$1
log_info "显示版本信息"
local current_version=$(get_current_version "$dir")
echo "版本信息"
echo "========"
echo "当前版本: $current_version"
# 显示Git标签
echo ""
echo "Git标签:"
git tag -l | sort -V | tail -5
# 显示最新提交
echo ""
echo "最新提交:"
git log -1 --pretty=format:"%h - %s (%an, %ar)"
}
# 预览版本变更
preview_version_change() {
local dir=$1
local version_type=$2
log_info "预览版本变更"
local current_version=$(get_current_version "$dir")
local new_version=$(calculate_new_version "$current_version" "$version_type")
echo "版本变更预览"
echo "============"
echo "当前版本: $current_version"
echo "版本类型: $version_type"
echo "新版本: $new_version"
}
# 发布版本
release_version() {
local dir=$1
local version_type=$2
local message=$3
log_info "发布版本: $version_type"
# 检查Git仓库
if ! check_git_repo; then
return 1
fi
# 检查是否有未提交的更改
if [ -n "$(git status --porcelain)" ]; then
log_error "存在未提交的更改"
return 1
fi
# 获取当前版本
local current_version=$(get_current_version "$dir")
# 计算新版本
local new_version=$(calculate_new_version "$current_version" "$version_type")
# 更新版本号
update_version "$dir" "$new_version"
# 提交版本更新
if [ "$DRY_RUN" = false ]; then
git add "$VERSION_FILE"
if [ -f "package.json" ]; then
git add package.json
fi
if [ -f "setup.py" ]; then
git add setup.py
fi
if [ -f "pyproject.toml" ]; then
git add pyproject.toml
fi
git commit -m "chore: bump version to $new_version"
git push
fi
# 生成变更日志
generate_changelog "$dir" "$new_version" "$version_type"
# 提交变更日志
if [ "$DRY_RUN" = false ]; then
git add "$CHANGELOG_FILE"
git commit -m "docs: update changelog for $new_version"
git push
fi
# 创建Git标签
create_git_tag "$new_version" "Release version $new_version"
log_info "版本发布完成: $new_version"
}
# 回滚版本
rollback_version() {
local dir=$1
local version=$2
log_info "回滚版本: $version"
# 检查标签是否存在
if ! git rev-parse "v$version" &>/dev/null; then
log_error "标签不存在: v$version"
return 1
fi
# 回退到指定版本
if [ "$DRY_RUN" = false ]; then
git checkout "v$version"
git push -f origin HEAD
fi
# 更新版本文件
echo "$version" > "$dir/$VERSION_FILE"
log_info "版本回滚完成: $version"
}
# 显示帮助
show_help() {
echo "用法: $0 [选项] <命令> [参数]"
echo ""
echo "选项:"
echo " -d <目录> 项目目录"
echo " -m <消息> 提交消息"
echo " -n 试运行模式"
echo " -h 显示帮助信息"
echo ""
echo "命令:"
echo " show 显示版本信息"
echo " preview <类型> 预览版本变更(major/minor/patch)"
echo " release <类型> 发布版本(major/minor/patch)"
echo " rollback <版本> 回滚版本"
echo " tag <版本> <消息> 创建Git标签"
echo " changelog 生成变更日志"
echo ""
echo "示例:"
echo " $0 -d /path/to/project show"
echo " $0 -d /path/to/project preview patch"
echo " $0 -d /path/to/project release patch"
echo " $0 -d /path/to/project rollback 1.0.0"
echo " $0 -d /path/to/project tag 1.0.0 \"Release 1.0.0\""
}
# 主函数
main() {
# 解析选项
while getopts "d:m:nh" opt; do
case $opt in
d)
PROJECT_DIR="$OPTARG"
log_info "项目目录: $PROJECT_DIR"
;;
m)
COMMIT_MESSAGE="$OPTARG"
log_info "提交消息: $COMMIT_MESSAGE"
;;
n)
DRY_RUN=true
log_info "试运行模式"
;;
h)
show_help
exit 0
;;
*)
log_error "无效选项: $opt"
show_help
exit 1
;;
esac
done
shift $((OPTIND - 1))
# 检查项目目录
if [ -z "$PROJECT_DIR" ]; then
PROJECT_DIR=$(pwd)
log_info "使用当前目录: $PROJECT_DIR"
fi
if ! check_project_dir; then
exit 1
fi
# 检查命令
if [ $# -eq 0 ]; then
log_error "缺少命令"
show_help
exit 1
fi
COMMAND=$1
shift
# 执行命令
case $COMMAND in
show)
show_version_info "$PROJECT_DIR"
;;
preview)
if [ $# -eq 0 ]; then
log_error "缺少版本类型"
show_help
exit 1
fi
preview_version_change "$PROJECT_DIR" "$1"
;;
release)
if [ $# -eq 0 ]; then
log_error "缺少版本类型"
show_help
exit 1
fi
local message=${COMMIT_MESSAGE:-"Release version"}
release_version "$PROJECT_DIR" "$1" "$message"
;;
rollback)
if [ $# -eq 0 ]; then
log_error "缺少版本号"
show_help
exit 1
fi
rollback_version "$PROJECT_DIR" "$1"
;;
tag)
if [ $# -lt 2 ]; then
log_error "缺少参数"
show_help
exit 1
fi
create_git_tag "$1" "$2"
;;
changelog)
local current_version=$(get_current_version "$PROJECT_DIR")
local new_version=$(calculate_new_version "$current_version" "patch")
generate_changelog "$PROJECT_DIR" "$new_version" "patch"
;;
*)
log_error "无效的命令: $COMMAND"
show_help
exit 1
;;
esac
}
# 执行主函数
main "$@"使用说明#
添加执行权限:
chmod +x version_manager.sh基本用法:
# 显示版本信息 ./version_manager.sh -d /path/to/project show # 预览版本变更 ./version_manager.sh -d /path/to/project preview patch # 发布补丁版本 ./version_manager.sh -d /path/to/project release patch # 发布次版本 ./version_manager.sh -d /path/to/project release minor # 发布主版本 ./version_manager.sh -d /path/to/project release major高级用法:
# 试运行模式 ./version_manager.sh -n -d /path/to/project release patch # 指定提交消息 ./version_manager.sh -m "Release 1.0.0" -d /path/to/project release major # 回滚版本 ./version_manager.sh -d /path/to/project rollback 1.0.0 # 创建Git标签 ./version_manager.sh -d /path/to/project tag 1.0.0 "Release 1.0.0" # 生成变更日志 ./version_manager.sh -d /path/to/project changelog
功能特点#
- 版本号管理(遵循语义化版本规范)
- Git标签管理
- 变更日志生成
- 版本发布
- 版本回滚
- 试运行模式
- 多项目支持
依赖项#
- git: 用于版本控制
注意事项#
- 需要Git仓库环境
- 发布前确保代码已提交
- 版本号遵循语义化版本规范
- 试运行模式不会实际执行操作
- 回滚操作会强制推送,请谨慎使用