app-starlock/tag_generator.sh

123 lines
4.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ========================
# tag_generator.sh
# 用于自动识别并递增以 _sky 结尾的 tag如 v1.5.556_sky),并生成下一个 tag。
# 递增规则feat: 提交递增 minorfix: 或其他提交递增 patch。
# ========================
# 读取环境变量(由 CI/CD 系统注入)
URL=$CI_API_V4_URL # GitLab API v4 地址
TOKEN=$GITLAB_ACCESS_TOKEN # GitLab 访问 Token
PROJECT_ID=$CI_PROJECT_ID # 当前项目 ID
next_tag="" # 新的 tag 变量
newest_tag="" # 最新 tag 变量
echo "PRIVATE-TOKEN: $TOKEN $URL/projects/$PROJECT_ID/repository/tags"
# 获取项目所有 tag 的 json 列表
# 需要 jq 工具解析 json
# tags_json 是所有 tag 的原始 json 数据
tags_json=$(curl -H "Content-Type: application/json" -H "PRIVATE-TOKEN: $TOKEN" "$URL/projects/$PROJECT_ID/repository/tags")
# 提取所有 tag 名称,按时间倒序排列(最新的在前)
tags=$(echo "$tags_json" | jq -r '.[].name')
# 只保留以 _sky 结尾的 tag即只处理 v1.2.3_sky 这种格式的 tag
sky_tags=$(echo "$tags" | grep '_sky$')
# 取最新的 _sky tag即第一个
newest_sky_tag=$(echo "$sky_tags" | head -n 1)
# 如果没有 _sky 结尾的 tag则从最新的 tag 提取版本号,生成 vX.Y.Z_sky
if [ -z "$newest_sky_tag" ]; then
latest_tag=$(echo "$tags" | head -n 1)
echo "DEBUG: tags=[$tags]"
echo "DEBUG: latest_tag=[$latest_tag]"
if [ -n "$latest_tag" ]; then
version_part=${latest_tag#v}
version_part=${version_part%_sky}
version_part=$(echo "$version_part" | tr -d ' \n\r')
echo "DEBUG: version_part=[$version_part]"
major=$(echo "$version_part" | awk -F. '{print $1}')
minor=$(echo "$version_part" | awk -F. '{print $2}')
patch=$(echo "$version_part" | awk -F. '{print $3}')
[ -z "$major" ] && major=1
[ -z "$minor" ] && minor=0
[ -z "$patch" ] && patch=0
next_tag="v${major}.${minor}.${patch}_sky"
else
next_tag="v1.0.0_sky"
fi
else
# 解析版本号部分(去掉 _sky 后缀和 v 前缀)
version_part=${newest_sky_tag%_sky}
version_part=${version_part#v}
version_part=$(echo "$version_part" | tr -d ' \n\r')
echo "DEBUG: version_part=[$version_part]"
major=$(echo "$version_part" | awk -F. '{print $1}')
minor=$(echo "$version_part" | awk -F. '{print $2}')
patch=$(echo "$version_part" | awk -F. '{print $3}')
[ -z "$major" ] && major=1
[ -z "$minor" ] && minor=0
[ -z "$patch" ] && patch=0
compare_json=""
if [[ "$1" == "generate_tag" ]];then
echo "generate_tag:$newest_sky_tag-to-master_sky\n"
compare_json=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" "$URL/projects/$PROJECT_ID/repository/compare?from=$newest_sky_tag&to=master_sky")
elif [[ "$1" == "generate_version" ]]; then
echo "generate_version:master_sky-to-$CI_COMMIT_BRANCH\n"
compare_json=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" "$URL/projects/$PROJECT_ID/repository/compare?from=master_sky&to=$CI_COMMIT_BRANCH")
fi
echo "compare_json:$compare_json\n"
new_patch=$patch
new_minor=$minor
seen_commits="" # 用于去重
while IFS= read -r commit_json; do
commit_id=$(echo "$commit_json" | jq -r '.id')
commit_title=$(echo "$commit_json" | jq -r '.title')
commit_message=$(echo "$commit_json" | jq -r '.message')
# commit id 去重(兼容所有 shell
if echo "$seen_commits" | grep -q "$commit_id"; then
continue
fi
seen_commits="$seen_commits $commit_id"
# 跳过 Merge 和 Revert 提交
if [[ "$commit_title" =~ ^Merge ]] || [[ "$commit_title" =~ ^Revert ]]; then
continue
fi
echo "----$commit_message"
if [[ "$commit_message" =~ ^feat: ]] && [[ $new_minor == $minor ]]; then
((new_minor++))
elif [[ "$commit_message" =~ ^fix: ]]; then
((new_patch++))
fi
done < <(echo "$compare_json" | jq -c '.commits[] | {id: .id, title: .title, message: .message}')
next_tag="v${major}.${new_minor}.${new_patch}_sky"
fi
echo "New Tag:$newest_sky_tag;New version: $next_tag;command: $1"
# 如果是 generate_tag 命令,且新 tag 和最新 tag 一致,则跳过生成
if [[ "$1" == "generate_tag" ]];then
if [ "$next_tag" == "$newest_sky_tag" ]; then
echo "no change from master,skip to generate tag"
exit 0
fi
# 配置 git 用户名(可根据需要补充邮箱等)
git config user.name
# 创建并推送新 tag
git tag $next_tag
git push -u origin $next_tag
echo "generate tag: $next_tag"
elif [[ "$1" == "generate_version" ]]; then
# 如果是 generate_version 命令,仅导出新版本号到环境变量
export NEXT_VERSION="$next_tag"
echo "generate version: $NEXT_VERSION"
fi
# 无论哪种情况,都把新 tag 写入 app_new.version 文件
# 供后续流程使用
echo "$next_tag" > app_new.version