ci(windows): GitHub 云构建 Windows 安装器暂存 NAS + 发版可选来源(home/github)

家里 Windows runner 关机时的备用构建源。
- windows.yml: 构建 Inno 安装器(复用 compile-windows.sh)→ 暂存 NAS gitea winstage-v<版本>
- deploy-client.yml: build-windows 加 home/github 开关(参数 windows_source 优先,变量 WINDOWS_SOURCE 兜底),新增 build-windows-ci 从 NAS 按版本拉取
- stage/fetch 脚本: 版本强匹配,拉不到硬失败

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9G7E3wmAYL9KeYCVZVsqu
This commit is contained in:
wangjia
2026-07-18 07:08:48 +08:00
parent fd654f21ac
commit 0a54ded445
4 changed files with 189 additions and 22 deletions
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# fetch-windows-staged.sh <tag> — 发版时从 NAS gitea 暂存 Release 拉 Windows 安装器。
#
# 用途:deploy-client.yml 的 build-windows-ci job(仅当 WINDOWS_SOURCE=github 时启用)
# 调用此脚本,按发版 tag(client-vX.Y.Z) 的**同一版本号**去找 `winstage-vX.Y.Z`
# 把 jiu-windows-x64-setup.exe 下到 dist/,供后续 upload-artifact → release/deploy 使用。
#
# **版本强匹配**:找不到对应版本的暂存包 → 硬失败并提示先在 GitHub 构建该版本,
# 绝不静默发出旧版/错版 Windows 包。
#
# 需要 envFORGEJO_URL、FORGEJO_TOKEN、GITEA_REPOSITORY。
set -euo pipefail
. "$(dirname "$0")/lib-forgejo.sh"
TAG="$1"
VER="$(ver_from_tag "$TAG")"
STAGE_TAG="winstage-v${VER}"
NAME="jiu-windows-x64-setup.exe"
echo "==> fetch-windows-staged: 发版版本=${VER},找暂存 ${STAGE_TAG}"
base="${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}"
mkdir -p dist
if ! info=$(curl -kfsS -H "Authorization: token ${FORGEJO_TOKEN}" "${base}/releases/tags/${STAGE_TAG}" 2>/dev/null); then
cat >&2 <<MSG
ERROR: NAS 上找不到暂存 Release ${STAGE_TAG}。
WINDOWS_SOURCE=github 需要先在 GitHub 构建**版本 ${VER}** 的 Windows 包:
gh workflow run windows.yml -f ver=${VER} (仓库 bj-wangjia/jiu)
构建完成会把安装器暂存到 NAS,再重跑本次发版即可。
MSG
exit 1
fi
# 找到同名资产 id 并下载(版本已由 STAGE_TAG 精确锁定)。JSON 经 stdin 传入避免转义问题。
aid=$(printf '%s' "$info" | python3 -c "import sys,json; print(next((a['id'] for a in json.load(sys.stdin).get('assets',[]) if a['name']=='${NAME}'), ''))")
rid=$(printf '%s' "$info" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
if [ -z "$aid" ]; then
echo "ERROR: ${STAGE_TAG} 存在但缺少 ${NAME} 资产(GitHub 构建可能失败)。" >&2
exit 1
fi
echo "==> fetch-windows-staged: 下载 asset id=${aid} → dist/${NAME}"
curl -kfsS -H "Authorization: token ${FORGEJO_TOKEN}" \
"${base}/releases/${rid}/assets/${aid}" -o "dist/${NAME}"
ls -lh "dist/${NAME}"
echo "==> fetch-windows-staged: done(版本 ${VER} 匹配)"
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# stage-windows-forgejo.sh <tag> — 把 GitHub 构建出的 Windows 安装器暂存到 NAS gitea。
#
# 用途:GitHub Actions(云) 构建 dist/jiu-windows-x64-setup.exe 后调用此脚本,
# 经 https://git.51yanmei.com Forgejo API 上传到一个**暂存 Release** `winstage-v<版本>`。
# 之后 gitea 发版流水线(deploy-client.yml 的 build-windows-ci job,当
# WINDOWS_SOURCE=github)按同一版本号从这里拉回,实现「家里 Windows 关机时用云构建」。
#
# 暂存 tag 用 `winstage-` 前缀(**不是** `winbuild-`)以免误触发 gitea 的
# build-windows.yml(on: push tags winbuild*)。
#
# 需要 envFORGEJO_URL(=https://git.51yanmei.com)、FORGEJO_TOKEN、GITEA_REPOSITORY(=wangjia/jiu)。
# <tag> 接受 client-vX.Y.Z / vX.Y.Z / X.Y.Z,统一归一到裸版本号。
set -euo pipefail
. "$(dirname "$0")/lib-forgejo.sh"
TAG="$1"
VER="$(ver_from_tag "$TAG")"
STAGE_TAG="winstage-v${VER}"
ASSET="dist/jiu-windows-x64-setup.exe"
echo "==> stage-windows: version=${VER} stage_tag=${STAGE_TAG}"
[ -f "$ASSET" ] || { echo "ERROR: ${ASSET} 不存在,先跑 compile-windows.sh" >&2; exit 1; }
api() { curl -kfsS -H "Authorization: token ${FORGEJO_TOKEN}" "$@"; }
base="${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}"
# --- upsert: 若 winstage-v<版本> 已存在则复用其 id 并清掉同名旧资产,否则新建 ---
name="$(basename "$ASSET")"
if info=$(api "${base}/releases/tags/${STAGE_TAG}" 2>/dev/null); then
RELEASE_ID=$(printf '%s' "$info" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "==> stage-windows: 复用已有暂存 Release id=${RELEASE_ID},清理同名旧资产"
# 列出同名旧资产 id(JSON 经 stdin 传入,避免嵌字符串的转义问题),逐个删除以便重传。
printf '%s' "$info" | python3 -c "import sys,json; [print(a['id']) for a in json.load(sys.stdin).get('assets',[]) if a['name']=='${name}']" |
while read -r aid; do
[ -n "$aid" ] && api -X DELETE "${base}/releases/${RELEASE_ID}/assets/${aid}" >/dev/null && echo " 删除旧资产 id=${aid}"
done
else
echo "==> stage-windows: 新建暂存 Release ${STAGE_TAG}"
body=$(python3 -c "import json; print(json.dumps('GitHub 云构建的 Windows 安装器暂存(供 deploy-client 在家里 Windows 不可用时拉取)'))")
create_release "$STAGE_TAG" "$body" # 设置 RELEASE_ID
fi
upload_asset "$ASSET"
echo "==> stage-windows: done — ${STAGE_TAG} 已带 jiu-windows-x64-setup.exe(版本 ${VER}"