Files
map-client-vue/rel.sh
2025-10-15 16:30:50 +08:00

218 lines
8.3 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
set -e
# Git 自动发布脚本
# 功能:检查分支、工作区,生成 tag并在 Gitea 上创建 Release
# 1. 检查分支
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch" != "main" ]; then
echo "❌ 错误:请在 main 分支运行,当前是 $branch"
exit 1
fi
echo "✅ 分支: $branch"
# 可选:检查本地 Gitea 配置中的默认分支设置(如果仓库里包含 Gitea 配置)
# 读取 custom/conf/app.ini 中的 DEFAULT_BRANCH 值并给出警告(不强制退出)
if [ -f custom/conf/app.ini ]; then
DEFAULT_BRANCH=$(grep -i '^DEFAULT_BRANCH' custom/conf/app.ini | head -n1 | cut -d'=' -f2 | tr -d ' ')
if [ -n "$DEFAULT_BRANCH" ]; then
if [ "$DEFAULT_BRANCH" = "main" ]; then
echo "⚠️ 警告: Gitea 配置 custom/conf/app.ini 中 DEFAULT_BRANCH 设置为 'main',这可能存在风险"
echo " 如果希望强制中止发布,请在脚本中启用退出逻辑。"
else
echo " Gitea 配置 DEFAULT_BRANCH=$DEFAULT_BRANCH"
fi
fi
fi
# 2. 检查工作区是否干净
if [ -n "$(git status --porcelain)" ]; then
echo "❌ 错误:工作区有未提交的更改,请先提交或 stash"
git status
exit 1
fi
echo "✅ 工作区干净"
# 3. 更新代码
echo "⬇️ 拉取远程代码..."
git fetch origin
git pull origin main
echo "✅ 已同步最新代码"
# 4. 从 release.md 提取版本和说明
if [ ! -f release.md ]; then
echo "❌ 未找到 release.md"
exit 1
fi
VERSION=$(grep "^## v" release.md | tail -n 1 | sed 's/^## //')
TAG_MESSAGE=$(awk "/^## $VERSION/{flag=1;next}/^## v/{flag=0}flag" release.md)
if [ -z "$VERSION" ]; then
echo "❌ release.md 中未找到版本号"
exit 1
fi
echo "📝 版本号: $VERSION"
echo "说明:"
echo "$TAG_MESSAGE"
# 5. 创建 tag如已存在则删除后重建
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "⚠️ 标签 $VERSION 已存在,删除旧标签..."
git tag -d "$VERSION"
git push origin ":refs/tags/$VERSION"
fi
git tag -a "$VERSION" -m "$TAG_MESSAGE"
echo "✅ 已创建 tag $VERSION"
# 6. 推送代码和 tag
echo "🚀 推送到远程..."
git push origin main
git push origin "$VERSION"
# 7. 创建 Gitea Release
echo ""
echo "🌐 创建 Gitea Release..."
# 自动解析 GITEA_URL 和 REPO
remote_url=$(git config --get remote.origin.url)
if [[ "$remote_url" == ssh://git@biboer.cn:21174/* ]]; then
# 特殊处理 biboer.cn:21174 的情况Web 界面在 /gitea 路径下
GITEA_URL="https://biboer.cn/gitea"
GITEA_REPO=$(echo "$remote_url" | sed 's|ssh://git@biboer\.cn:21174/||' | sed 's|\.git$||')
elif [[ "$remote_url" =~ ^ssh://([^/]+)/([^/]+)/(.+)\.git$ ]]; then
GITEA_URL="https://${BASH_REMATCH[1]}"
GITEA_REPO="${BASH_REMATCH[2]}/${BASH_REMATCH[3]}"
elif [[ "$remote_url" =~ ^([^@]+@[^:]+):([^/]+)/(.+)\.git$ ]]; then
# git@biboer.cn:21174/gavin/note-to-mp.git
hostport=$(echo "${BASH_REMATCH[1]}" | cut -d@ -f2)
GITEA_URL="https://${hostport}"
GITEA_REPO="${BASH_REMATCH[2]}/${BASH_REMATCH[3]}"
else
echo "❌ 无法解析远程地址: $remote_url"
exit 1
fi
if [ -z "$GITEA_TOKEN" ]; then
echo "⚠️ 未设置 GITEA_TOKEN只推送了 tag没有创建 Release"
exit 0
fi
# 如果远程已经存在该 Release通过 tag 查询),先删除它(避免 409 Conflict
echo "🔍 检查远程 Release 是否已存在..."
check_response=$(curl -s -w "\n%{http_code}" \
-X GET "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/tags/$VERSION" \
-H "Authorization: token $GITEA_TOKEN")
check_http_code=$(echo "$check_response" | tail -n 1)
check_body=$(echo "$check_response" | sed '$d')
if [ "$check_http_code" -eq 200 ]; then
release_id=$(echo "$check_body" | jq -r '.id')
echo "⚠️ 远程已存在 Release $VERSION (ID: $release_id),正在删除..."
delete_response=$(curl -s -w "\n%{http_code}" \
-X DELETE "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$release_id" \
-H "Authorization: token $GITEA_TOKEN")
delete_http_code=$(echo "$delete_response" | tail -n 1)
if [ "$delete_http_code" -eq 204 ] || [ "$delete_http_code" -eq 200 ]; then
echo "✅ 已删除旧的 Release"
else
echo "⚠️ 删除旧 Release 失败 (HTTP $delete_http_code),继续尝试创建新的 Release"
fi
fi
# 使用 jq 生成正确的 JSON
JSON_PAYLOAD=$(echo "$TAG_MESSAGE" | jq -R -s -c --arg version "$VERSION" '{
tag_name: $version,
name: $version,
body: .,
draft: false,
prerelease: false
}')
# 尝试创建 Release若返回 409冲突再查询并删除后重试一次
echo "🔄 正在创建 Release首次尝试..."
response_full=$(curl -s -w "\n%{http_code}" \
-X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
-H "Content-Type: application/json" \
-H "Authorization: token $GITEA_TOKEN" \
-d "$JSON_PAYLOAD")
http_code=$(echo "$response_full" | tail -n 1)
resp_body=$(echo "$response_full" | sed '$d')
if [ "$http_code" -eq 201 ]; then
echo "✅ Release 创建成功: $VERSION"
else
if [ "$http_code" -eq 409 ]; then
echo "⚠️ 创建 Release 返回 409 Conflict尝试删除远程冲突的 Release 并重试..."
# 再次查询 Release id
check_response=$(curl -s -w "\n%{http_code}" \
-X GET "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/tags/$VERSION" \
-H "Authorization: token $GITEA_TOKEN")
check_http_code=$(echo "$check_response" | tail -n 1)
check_body=$(echo "$check_response" | sed '$d')
if [ "$check_http_code" -eq 200 ]; then
release_id=$(echo "$check_body" | jq -r '.id')
delete_response=$(curl -s -w "\n%{http_code}" \
-X DELETE "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$release_id" \
-H "Authorization: token $GITEA_TOKEN")
delete_http_code=$(echo "$delete_response" | tail -n 1)
if [ "$delete_http_code" -eq 204 ] || [ "$delete_http_code" -eq 200 ]; then
echo "✅ 已删除冲突的 Release准备重试创建..."
# 重试创建一次
retry_response=$(curl -s -w "\n%{http_code}" \
-X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
-H "Content-Type: application/json" \
-H "Authorization: token $GITEA_TOKEN" \
-d "$JSON_PAYLOAD")
retry_code=$(echo "$retry_response" | tail -n 1)
retry_body=$(echo "$retry_response" | sed '$d')
if [ "$retry_code" -eq 201 ]; then
echo "✅ Release 创建成功 (重试): $VERSION"
else
echo "❌ 重试创建 Release 仍然失败 (HTTP $retry_code)"
echo "响应: $retry_body"
fi
else
echo "❌ 删除冲突 Release 失败 (HTTP $delete_http_code),无法重试"
echo "响应: $delete_response"
fi
else
echo "❌ 查询冲突 Release 失败 (HTTP $check_http_code),响应: $check_body"
fi
else
# 如果是 500 并且包含 collation/utf8 相关错误,回退到英文 body 重试
if [ "$http_code" -eq 500 ] || echo "$resp_body" | grep -qi "collation\|utf8\|Conversion from collation"; then
echo "⚠️ 检测到字符集/编码错误 (HTTP $http_code),尝试回退到英文说明并重试..."
ENGLISH_BODY="## Release Notes\n\nThis is release $VERSION: $RELEASE_TITLE\n\nFor detailed Chinese release notes, please see release.md in the repository.\n\nQuick start:\n\n\`\`\`bash\ngit pull origin main\ncd web && npm install\nnpm run dev\n\`\`\`"
JSON_PAYLOAD_EN=$(jq -n -c --arg version "$VERSION" --arg name "$VERSION" --arg body "$ENGLISH_BODY" '{tag_name: $version, name: $name, body: $body, draft: false, prerelease: false}')
echo "🔄 正在创建 Release英文回退重试..."
en_resp=$(curl -s -w "\n%{http_code}" \
-X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
-H "Content-Type: application/json" \
-H "Authorization: token $GITEA_TOKEN" \
-d "$JSON_PAYLOAD_EN")
en_code=$(echo "$en_resp" | tail -n 1)
en_body=$(echo "$en_resp" | sed '$d')
if [ "$en_code" -eq 201 ]; then
echo "✅ Release 创建成功 (英文回退): $VERSION"
else
echo "❌ 英文回退重试失败 (HTTP $en_code)"
echo "响应: $en_body"
fi
else
echo "❌ Release 创建失败HTTP $http_code"
echo "响应: $resp_body"
fi
fi
fi
echo ""
echo "🎉 发布完成!"
echo "📦 版本:$VERSION"