b9f89f6526
新增 Gitea Actions 流水线,复刻本地 deploy.sh 到 CI,打 v* tag 即自动发版: - .gitea/workflows/deploy.yml:v*.*.* tag 触发 → go test → 交叉编译 linux/amd64 → 传 ali → 备份 payd.bak → 切换 → systemctl restart pay → 探活(失败自动回滚) - .gitea/workflows/checks.yml:PR/合并 main 跑 go vet+build+test 静态闸 - scripts/ci/deploy.sh:本地 deploy.sh 的 CI 版(从 secret 注入部署私钥 + 主机, 不用 ~/.ssh 的 ali 别名);notify.sh:Telegram 通知(secrets 未配则静默跳过) - runs-on mac,复用 jiu 的自建 runner;业务密钥仍走 ali /etc/pay/pay.env - README 部署段补 CI 路径 + 所需 secrets(ALI_SSH_KEY/ALI_HOST/ALI_USER) 首次需在 pay 仓 Gitea → Settings → Actions → Secrets 配 3 个 ALI_* secret。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UQmqWmV67sXGLrb3U1XXn
61 lines
2.5 KiB
Bash
Executable File
61 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# scripts/ci/deploy.sh <tag> — CI 发布:交叉编译 linux/amd64 → 传 ali → 备份 →
|
||
# 切换 → 重启 pay → 探活(失败自动回滚)。本地 ./deploy.sh 的 CI 版:不用
|
||
# ~/.ssh 里的 `ali` 别名,而是从 secret 注入部署私钥、从 secret 取主机。
|
||
#
|
||
# 由 .gitea/workflows/deploy.yml 在打 v* tag 时触发(runs-on: mac,复用 jiu
|
||
# 的自建 mac runner)。业务密钥不在此处理——运行时由 ali 上 /etc/pay/pay.env
|
||
# 提供(Bitwarden 灌)。
|
||
#
|
||
# 需要的 secrets(pay 仓 Gitea → Settings → Actions → Secrets):
|
||
# ALI_SSH_KEY 已授权 ali root 的部署私钥(整段,OpenSSH 或 PEM)
|
||
# ALI_HOST ali 可达地址
|
||
# ALI_USER 部署用户(默认 root)
|
||
set -euo pipefail
|
||
|
||
# shellcheck source=scripts/ci/_env.sh
|
||
. "$(dirname "$0")/_env.sh"
|
||
|
||
TAG="${1:-manual}"
|
||
TARGET_HOST="${DEPLOY_HOST:?ALI_HOST secret 未设}"
|
||
TARGET_USER="${DEPLOY_USER:-root}"
|
||
DIR=/opt/pay
|
||
BIN=dist/payd
|
||
KEY="${HOME}/.ssh/pay_deploy.key"
|
||
|
||
echo "==> deploy: tag=${TAG} host=${TARGET_HOST}"
|
||
|
||
echo "[1/4] 交叉编译 linux/amd64 …"
|
||
mkdir -p dist
|
||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o "$BIN" .
|
||
|
||
echo "[2/4] 写部署 key + 上传到 ${TARGET_HOST}:${DIR}/payd-new …"
|
||
mkdir -p "${HOME}/.ssh"
|
||
# printf '%s\n' 末尾补换行:Gitea 存 secret 会去掉结尾换行,而 OpenSSH 格式
|
||
# 私钥缺结尾换行会被判 "invalid format" 拒绝加载 → 退化成无密钥 Permission denied。
|
||
printf '%s\n' "${DEPLOY_SSH_KEY:?ALI_SSH_KEY secret 未设}" > "$KEY"
|
||
chmod 600 "$KEY"
|
||
ssh-keyscan -H "$TARGET_HOST" >> "${HOME}/.ssh/known_hosts" 2>/dev/null || true
|
||
SSH="ssh -i $KEY -o StrictHostKeyChecking=no"
|
||
SCP="scp -O -i $KEY -o StrictHostKeyChecking=no"
|
||
|
||
cleanup() { rm -f "$KEY"; }
|
||
trap cleanup EXIT
|
||
|
||
$SCP "$BIN" "${TARGET_USER}@${TARGET_HOST}:${DIR}/payd-new"
|
||
|
||
echo "[3/4] 备份旧版 + 切换 + 重启 …"
|
||
$SSH "${TARGET_USER}@${TARGET_HOST}" \
|
||
"cp ${DIR}/payd ${DIR}/payd.bak && mv ${DIR}/payd-new ${DIR}/payd && chmod +x ${DIR}/payd && systemctl restart pay"
|
||
|
||
echo "[4/4] 探活 …"
|
||
if $SSH "${TARGET_USER}@${TARGET_HOST}" \
|
||
"curl -fsS --retry 8 --retry-delay 1 --retry-connrefused -o /dev/null -w 'health %{http_code}\n' http://127.0.0.1:8080/health"; then
|
||
echo "✅ 发布完成(上一版已备份在 ${DIR}/payd.bak)"
|
||
else
|
||
echo "❌ 探活失败,自动回滚到上一版 …"
|
||
$SSH "${TARGET_USER}@${TARGET_HOST}" "cp ${DIR}/payd.bak ${DIR}/payd && systemctl restart pay"
|
||
echo "↩️ 已回滚。请检查本次改动后重试。"
|
||
exit 1
|
||
fi
|