118 lines
4.6 KiB
Bash
Executable File
118 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ============================================================
|
||
# RainWeb 一键打包发布脚本
|
||
# 用法:
|
||
# ./scripts/release.sh # 自动 patch 版本 +1(如 2.3.0 → 2.3.1)
|
||
# ./scripts/release.sh 2.4.0 # 指定版本号
|
||
# ./scripts/release.sh --dry-run # 只预览版本号不执行
|
||
# ./scripts/release.sh --local # 本地打包:bump+build+源码包,不推送不发布
|
||
#
|
||
# 流程:bump 版本 → build → commit+push → tag+push → 源码包 → Gitea release+附件
|
||
# --local 时:bump 版本 → build → 源码包(跳过 git push / tag / Gitea)
|
||
# 依赖:npm、git、curl;Gitea 凭据在 ~/.git-credentials(token 自动提取)
|
||
# ============================================================
|
||
set -euo pipefail
|
||
cd "$(dirname "$0")/.."
|
||
|
||
DRY=""
|
||
LOCAL=""
|
||
VERSION_ARG=""
|
||
for a in "$@"; do
|
||
case "$a" in
|
||
--dry-run) DRY="1" ;;
|
||
--local) LOCAL="1" ;;
|
||
*) VERSION_ARG="${VERSION_ARG:-$a}" ;;
|
||
esac
|
||
done
|
||
|
||
# ---------- 版本读取与计算 ----------
|
||
CURRENT=$(cat VERSION | tr -d ' \n')
|
||
if [[ -n "$VERSION_ARG" ]]; then
|
||
NEW_VERSION="$VERSION_ARG"
|
||
else
|
||
# patch +1:X.Y.Z → X.Y.(Z+1)
|
||
NEW_VERSION=$(echo "$CURRENT" | awk -F. '{print $1"."$2"."($3+1)}')
|
||
fi
|
||
|
||
echo "当前版本: $CURRENT"
|
||
echo "新版本: $NEW_VERSION"
|
||
if [[ "$DRY" == "1" ]]; then echo "(--dry-run 预览结束)"; exit 0; fi
|
||
if [[ "$CURRENT" == "$NEW_VERSION" ]]; then echo "⚠️ 版本未变化,退出"; exit 1; fi
|
||
if [[ "$LOCAL" == "1" ]]; then
|
||
echo "(本地打包模式:不推送、不建 tag、不发布 Gitea)"
|
||
else
|
||
read -p "确认发布 v$NEW_VERSION ? [y/N] " -r
|
||
if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then echo "已取消"; exit 1; fi
|
||
fi
|
||
|
||
# ---------- 1. bump 版本(三处同步) ----------
|
||
echo "==> bump 版本"
|
||
echo "$NEW_VERSION" > VERSION
|
||
sed -i "s/\"version\": \"$CURRENT\"/\"version\": \"$NEW_VERSION\"/" package.json
|
||
sed -i "s/\"version\": \"$CURRENT\"/\"version\": \"$NEW_VERSION\"/" package-lock.json
|
||
|
||
# ---------- 2. 构建 ----------
|
||
echo "==> npm run build"
|
||
npm run build
|
||
|
||
# ---------- 3. 提交 + 推送(本地模式跳过) ----------
|
||
if [[ "$LOCAL" != "1" ]]; then
|
||
echo "==> git commit + push"
|
||
git add VERSION package.json package-lock.json
|
||
git commit -m "chore: bump version $NEW_VERSION"
|
||
git push origin master
|
||
|
||
# ---------- 4. tag + 推送 ----------
|
||
echo "==> git tag v$NEW_VERSION"
|
||
git tag "v$NEW_VERSION"
|
||
git push origin "v$NEW_VERSION"
|
||
fi
|
||
|
||
# ---------- 5. 打源码包 ----------
|
||
echo "==> 打源码包"
|
||
mkdir -p releases
|
||
PKG="releases/rainweb-v$NEW_VERSION-src.tar.gz"
|
||
tar czf "$PKG" \
|
||
--exclude='.git' --exclude='releases' --exclude='data' --exclude='uploads' \
|
||
--exclude='.env.json' --exclude='backups' --exclude='public/wallpaper' \
|
||
--exclude='node_modules' --exclude='*.log' \
|
||
.
|
||
ls -lh "$PKG"
|
||
|
||
# ---------- 6. Gitea release + 上传附件(本地模式跳过) ----------
|
||
if [[ "$LOCAL" == "1" ]]; then
|
||
echo "✅ 本地打包完成: $PKG(未推送,可稍后手动发布)"
|
||
exit 0
|
||
fi
|
||
|
||
echo "==> 创建 Gitea release"
|
||
# 从 ~/.git-credentials 提取 token(支持 http/https 两种格式)
|
||
CRED=$(sed -n 's|https\?://\([^@]*\)@\(git\.rainnya\.asia\|[^/]*rainnya[^/]*\).*|\1|p' ~/.git-credentials 2>/dev/null | head -1)
|
||
TOKEN=$(echo "$CRED" | sed 's/^[^:]*://')
|
||
if [[ -z "$TOKEN" ]]; then echo "❌ 无法从 ~/.git-credentials 提取 Gitea token"; exit 1; fi
|
||
|
||
# 提交说明:最近 5 条 commit
|
||
BODY=$(git log --oneline -5 "v$CURRENT..HEAD" | sed 's/^/- /' || true)
|
||
|
||
RELEASE_JSON=$(curl -s -X POST "https://git.rainnya.asia/api/v1/repos/miaomiao/rainblogweb/releases" \
|
||
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
||
-d "{\"tag_name\":\"v$NEW_VERSION\",\"target_commitish\":\"master\",\"name\":\"v$NEW_VERSION\",\"body\":\"## v$NEW_VERSION\n\n$BODY\",\"draft\":false,\"prerelease\":false}")
|
||
RELEASE_ID=$(echo "$RELEASE_JSON" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{try{console.log(JSON.parse(d).id||'')}catch{console.log('')}})")
|
||
if [[ -z "$RELEASE_ID" ]]; then
|
||
echo "❌ release 创建失败: $(echo "$RELEASE_JSON" | head -c 200)"
|
||
exit 1
|
||
fi
|
||
echo "==> release id: $RELEASE_ID"
|
||
|
||
echo "==> 上传附件"
|
||
RESP=$(curl -s -X POST "https://git.rainnya.asia/api/v1/repos/miaomiao/rainblogweb/releases/$RELEASE_ID/assets?name=$(basename "$PKG")" \
|
||
-H "Authorization: token $TOKEN" -H "Content-Type: application/gzip" \
|
||
--data-binary "@$PKG" -w "\n%{http_code}")
|
||
HTTP=$(echo "$RESP" | tail -1)
|
||
if [[ "$HTTP" == "201" ]]; then
|
||
echo "✅ 发布完成: https://git.rainnya.asia/miaomiao/rainblogweb/releases"
|
||
else
|
||
echo "❌ 附件上传失败 (HTTP $HTTP): $(echo "$RESP" | head -c 200)"
|
||
exit 1
|
||
fi
|