Files
wangjia 2b4350cfc4 feat(server): 装配 notices(路由替换空壳+reward/pay 注入)+ 发版联动插 version 公告
main.go 挂载 notices.Store/Handler:注入 rewardSvc/payWebhook 到账通知钩子,
/v1/notices 路由由 accountAPI 空壳换成真实 List/MarkRead,删除 account.go
的 TODO 空壳方法。补齐 pangolin-nodectl 到编译/部署产物链
(compile-backend.sh + deploy-server.sh),release-client.sh 在
version.yaml 推送成功后追加一步用 nodectl 插入 version 类型站内公告
(失败不阻断发版)。
2026-07-13 14:09:54 +08:00

125 lines
5.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# release-client.sh <tag> — ensure the Forgejo release for a client-v* tag
# exists, upload whichever client artifacts are present in dist/, and roll
# the auto-update manifest (deploy/single-node/version.yaml) forward.
#
# Mirrors ~/code/jiu/scripts/ci/release-client.sh's asset-guarding pattern,
# but uses pangolin's own lib-forgejo.sh API (forgejo_release_ensure /
# forgejo_upload_asset — different names/signature than jiu's create_release/
# upload_asset).
#
# Manifest handling differs from jiu on purpose: jiu's backend reads
# backend/config/version.yaml straight out of its own working directory, so
# rewriting that file in the repo checkout is enough. Pangolin's server reads
# VERSION_MANIFEST from /etc/pangolin (see server/internal/httpapi/version.go
# + deploy/single-node/deploy.sh), a path that lives on pangolin1, not in any
# git checkout — so getting the new version/build_number onto the live host
# needs an SSH push, the same DEPLOY_SSH_KEY / lib-ssh.sh path
# deploy-client.sh already uses for the downloads/ dir (see
# .gitea/workflows/deploy-client.yml, which now passes DEPLOY_SSH_KEY into
# this step too). Also unlike jiu, download_urls are fixed "latest" stable
# URLs (deploy-client.sh keeps only one file per platform) and changelog[]
# isn't populated yet (no CHANGELOG-client.md in this repo) — so only
# version/build_number are rewritten here, everything else in the manifest
# template is passed through unchanged.
#
# Multiple platform build jobs (android/windows/...) all upload into the SAME
# release, guarded by `[ -f ... ]` since a given CI run may only have built a
# subset (e.g. a partial manual re-dispatch, or before macOS/iOS land).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
# shellcheck source=scripts/ci/_env.sh
. "${SCRIPT_DIR}/_env.sh"
# shellcheck source=scripts/ci/lib-forgejo.sh
. "${SCRIPT_DIR}/lib-forgejo.sh"
# shellcheck source=scripts/ci/lib-ssh.sh
. "${SCRIPT_DIR}/lib-ssh.sh"
TAG="${1:?usage: release-client.sh <tag>}"
ver_file="/tmp/release_client_ver.$$"
ver_from_tag client "$TAG" > "$ver_file"
VER=""
read -r VER < "$ver_file" || true # 无结尾换行的 read 退出码,见 release-server.sh 同注释
rm -f "$ver_file"
echo "==> release-client: tag=${TAG} ver=${VER}"
forgejo_release_ensure "$TAG" "client ${VER}"
if [ -f dist/pangolin-android.apk ]; then
forgejo_upload_asset "$TAG" dist/pangolin-android.apk
fi
if [ -f dist/pangolin-windows-x64-setup.exe ]; then
forgejo_upload_asset "$TAG" dist/pangolin-windows-x64-setup.exe
fi
if [ -f dist/pangolin-macos-x64.zip ]; then
forgejo_upload_asset "$TAG" dist/pangolin-macos-x64.zip
fi
# iOS has no dist/ artifact — compile-ios.sh uploads straight to TestFlight
# via altool (matches jiu), nothing to attach to the Forgejo release here.
# ── Auto-update manifest: bump version/build_number, stage + push to pangolin1 ──
# BUILD is derived the exact same way compile-android.sh derives the APK's
# Android versionCode (major*10000 + minor*100 + patch) so the manifest's
# build_number stays consistent with the shipped APK for a given tag, rather
# than being an independently-incremented counter like jiu's.
MAJOR="${VER%%.*}"
_REST="${VER#*.}"
MINOR="${_REST%%.*}"
PATCH="${_REST#*.}"
PATCH="${PATCH%%-*}"
BUILD=$(( MAJOR * 10000 + MINOR * 100 + PATCH ))
MANIFEST_TMPL="${REPO_ROOT}/deploy/single-node/version.yaml"
MANIFEST_OUT="/tmp/pangolin_version_manifest.$$.yaml"
if [ -f "$MANIFEST_TMPL" ]; then
: > "$MANIFEST_OUT"
while IFS= read -r line || [ -n "$line" ]; do
case "$line" in
version:*) printf 'version: "%s"\n' "$VER" >> "$MANIFEST_OUT" ;;
build_number:*) printf 'build_number: %d\n' "$BUILD" >> "$MANIFEST_OUT" ;;
*) printf '%s\n' "$line" >> "$MANIFEST_OUT" ;;
esac
done < "$MANIFEST_TMPL"
mkdir -p dist
cp "$MANIFEST_OUT" dist/version.yaml
# Stage as a release asset too, so a manual rollback can re-fetch the exact
# manifest that shipped alongside this tag (mirrors jiu's rationale).
forgejo_upload_asset "$TAG" dist/version.yaml
if [ -n "${DEPLOY_SSH_KEY:-}" ]; then
echo "==> release-client: pushing version.yaml (version=${VER} build_number=${BUILD}) to pangolin1"
setup_ssh
SCP="scp -i ${SSH_KEY_FILE} -P ${DEPLOY_PORT} -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=${SSH_KNOWN_HOSTS_FILE}"
$SSH "root@${DEPLOY_HOST}" "mkdir -p /etc/pangolin"
$SCP "$MANIFEST_OUT" "root@${DEPLOY_HOST}:/tmp/pangolin_version.yaml.new"
$SSH "root@${DEPLOY_HOST}" "mv /tmp/pangolin_version.yaml.new /etc/pangolin/version.yaml && chown pangolin:pangolin /etc/pangolin/version.yaml && chmod 644 /etc/pangolin/version.yaml"
echo "==> release-client: version.yaml deployed to pangolin1 (/etc/pangolin/version.yaml)"
# 站内通知:插一条 version 类型公告,提示用户有新版可更新。失败不阻断发版
# (公告只是锦上添花,manifest 已经推送成功才是自动更新真正生效的部分)。
echo "==> release-client: inserting version notice via pangolin-nodectl"
$SSH "root@${DEPLOY_HOST}" "DB_DSN=/var/lib/pangolin/pangolin.db DB_DRIVER=sqlite \
/usr/local/bin/pangolin-nodectl notice add --type version \
--title-zh \"v${VER} 已发布\" --title-en \"v${VER} released\" \
--body-zh \"新版本已可更新,打开设置检查更新。\" --body-en \"A new version is available — check for updates in Settings.\"" \
|| echo "==> release-client: version notice 插入失败(不阻断发版)"
else
echo "==> release-client: DEPLOY_SSH_KEY not set — skipping live manifest push (dist/version.yaml still staged + uploaded as a release asset)"
fi
rm -f "$MANIFEST_OUT"
else
echo "==> release-client: WARN manifest template ${MANIFEST_TMPL} not found — skipping version.yaml update" >&2
fi
echo "==> release-client: done — Release ${TAG} updated. dist/ contents:"
ls -lh dist/ 2>/dev/null || true