play.wenpai.net/scripts/play-deploy
elementary-qa 472f131e4e feat: 标准化产品截图第二批 — WPMind 2 张 + manifest 补齐 5 插件
- 新增 wpmind 主面板 + 插件列表截图 (PNG+WebP)
- manifest.json 补齐 wpslug/wpavatar/wpdate/wpfonts/wpmind 共 11 场景
- play-deploy 同步目标增加 screenshots 目录
- 新增 play-capture 自动截图脚本

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 19:40:23 +08:00

258 lines
10 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

#!/usr/bin/env bash
# play-deploy — play.wenpai.net 标准化部署工具
# 用法: play-deploy [command]
# deploy 从 git 拉取最新代码并部署到生产 (默认)
# status 对比 git 与生产环境差异
# rollback 回滚到上一个备份版本
# verify 验证线上站点可用性
# backup 仅备份当前生产文件
# upgrade 升级 Playground 引擎 (从 GitHub Release)
set -euo pipefail
# ── 配置 ──────────────────────────────────────────
REPO_URL="ssh://git@feicode.com:2222/WenPai-org/play.wenpai.net.git"
REPO_BRANCH="main"
LOCAL_CACHE="/tmp/play.wenpai.net-deploy"
REMOTE_HOST="feicode-prod"
REMOTE_ROOT="/www/wwwroot/play.wenpai.net"
REMOTE_OWNER="www:www"
SITE_URL="https://play.wenpai.net"
# repo 中 play/ 目录映射到生产站点根目录
PLAY_DIR="play"
# 需要同步的文件/目录(相对于 play/
SYNC_TARGETS=(index.html plugins.json blueprints plugins screenshots)
DATE=$(date +%Y-%m-%d-%H%M)
# ── 颜色 ──────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info() { echo -e "${GREEN}[✓]${NC} $*"; }
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
error() { echo -e "${RED}[✗]${NC} $*"; }
# ── 函数 ──────────────────────────────────────────
git_pull() {
if [ -d "$LOCAL_CACHE/.git" ]; then
info "更新本地缓存..."
cd "$LOCAL_CACHE"
git fetch origin "$REPO_BRANCH" --quiet
git checkout "$REPO_BRANCH" --quiet 2>/dev/null || git checkout -b "$REPO_BRANCH" "origin/$REPO_BRANCH" --quiet
git reset --hard "origin/$REPO_BRANCH" --quiet
else
info "克隆仓库..."
rm -rf "$LOCAL_CACHE"
git clone --depth 20 --branch "$REPO_BRANCH" "$REPO_URL" "$LOCAL_CACHE" 2>&1 | tail -1
fi
cd "$LOCAL_CACHE"
COMMIT=$(git log --oneline -1)
info "当前版本: $COMMIT"
}
do_backup() {
info "备份生产文件..."
local backup_dir="$REMOTE_ROOT/backups/$DATE"
ssh "$REMOTE_HOST" "mkdir -p $backup_dir"
for target in "${SYNC_TARGETS[@]}"; do
ssh "$REMOTE_HOST" "[ -e $REMOTE_ROOT/$target ] && cp -r $REMOTE_ROOT/$target $backup_dir/ || true" 2>/dev/null
done
info "备份完成: $backup_dir"
}
do_deploy() {
git_pull
do_backup
info "部署文件到生产..."
for target in "${SYNC_TARGETS[@]}"; do
local src="$LOCAL_CACHE/$PLAY_DIR/$target"
if [ ! -e "$src" ]; then
warn "跳过不存在的文件: $target"
continue
fi
if [ -d "$src" ]; then
# 目录: rsync 同步(不删除生产端多余文件,如 plugin-check.json
rsync -az --no-perms "$src/" "$REMOTE_HOST:$REMOTE_ROOT/$target/"
else
scp -q "$src" "$REMOTE_HOST:$REMOTE_ROOT/$target"
fi
done
# 修复权限
ssh "$REMOTE_HOST" "chown -R $REMOTE_OWNER $REMOTE_ROOT/index.html $REMOTE_ROOT/plugins.json $REMOTE_ROOT/blueprints/ $REMOTE_ROOT/plugins/ 2>/dev/null || true"
local commit_hash
commit_hash=$(cd "$LOCAL_CACHE" && git rev-parse --short HEAD)
info "部署完成: $commit_hash"
do_verify
}
do_status() {
git_pull
info "对比 git 与生产环境..."
local tmpdir
tmpdir=$(mktemp -d)
for target in "${SYNC_TARGETS[@]}"; do
if [ -f "$LOCAL_CACHE/$PLAY_DIR/$target" ]; then
scp -q "$REMOTE_HOST:$REMOTE_ROOT/$target" "$tmpdir/$target" 2>/dev/null || true
if [ -f "$tmpdir/$target" ]; then
if diff -q "$LOCAL_CACHE/$PLAY_DIR/$target" "$tmpdir/$target" >/dev/null 2>&1; then
info "$target: 一致"
else
warn "$target: 有差异"
diff --color=auto "$LOCAL_CACHE/$PLAY_DIR/$target" "$tmpdir/$target" | head -20 || true
fi
else
warn "$target: 生产端不存在"
fi
fi
done
rm -rf "$tmpdir"
}
do_rollback() {
info "查找可用备份..."
local backups
backups=$(ssh "$REMOTE_HOST" "ls -d $REMOTE_ROOT/backups/*/ 2>/dev/null | sort -r | head -5")
if [ -z "$backups" ]; then
error "没有找到备份"
exit 1
fi
echo "可用备份:"
echo "$backups" | nl
read -rp "选择备份编号 (1-5): " choice
local selected
selected=$(echo "$backups" | sed -n "${choice}p")
if [ -z "$selected" ]; then
error "无效选择"
exit 1
fi
info "$selected 回滚..."
for target in "${SYNC_TARGETS[@]}"; do
ssh "$REMOTE_HOST" "[ -e ${selected}${target} ] && cp -r ${selected}${target} $REMOTE_ROOT/ || true" 2>/dev/null
done
ssh "$REMOTE_HOST" "chown -R $REMOTE_OWNER $REMOTE_ROOT/index.html $REMOTE_ROOT/plugins.json $REMOTE_ROOT/blueprints/ $REMOTE_ROOT/plugins/ 2>/dev/null || true"
info "回滚完成"
do_verify
}
do_verify() {
info "验证站点..."
local status
status=$(curl -sI -o /dev/null -w "%{http_code}" "$SITE_URL/" 2>/dev/null)
if [ "$status" = "200" ]; then
info "HTTP $status — 站点正常"
else
error "HTTP $status — 站点异常!"
return 1
fi
# 检查关键内容
local content
content=$(curl -s "$SITE_URL/" 2>/dev/null)
local checks=0
echo "$content" | grep -q "文派" && ((checks++)) || warn "未找到「文派」关键词"
echo "$content" | grep -q "playground" && ((checks++)) || warn "未找到 playground 引用"
info "内容检查通过: $checks/2"
}
do_localize() {
local script_path
# 优先用仓库里的 localize 脚本
if [ -f "$LOCAL_CACHE/scripts/play-localize" ]; then
script_path="$LOCAL_CACHE/scripts/play-localize"
elif [ -f "$(dirname "$0")/play-localize" ]; then
script_path="$(dirname "$0")/play-localize"
else
error "找不到 play-localize 脚本"
exit 1
fi
local extra_args=""
[[ "${1:-}" == "--dry-run" ]] && extra_args="--dry-run"
bash "$script_path" --remote $extra_args
}
do_mirror() {
info "镜像 GitHub 资源到生产服务器..."
local data_dir="$REMOTE_ROOT/data"
ssh "$REMOTE_HOST" "mkdir -p $data_dir"
# 蓝图库:从 feicode 镜像克隆,同步文件 + 索引到本地
info "同步蓝图库..."
ssh "$REMOTE_HOST" "cd /tmp && rm -rf wp-blueprints 2>/dev/null \
&& git clone --depth 1 https://feicode.com/WenPai-org/blueprints.git wp-blueprints 2>/dev/null \
&& rsync -a /tmp/wp-blueprints/blueprints/ $REMOTE_ROOT/community-blueprints/ \
&& cp /tmp/wp-blueprints/index.json $REMOTE_ROOT/blueprints-index.json \
&& chown -R $REMOTE_OWNER $REMOTE_ROOT/community-blueprints/ $REMOTE_ROOT/blueprints-index.json \
&& rm -rf /tmp/wp-blueprints" && {
# 替换截图 URL → 本地路径
ssh "$REMOTE_HOST" "cd $REMOTE_ROOT && python3 -c \"
import json, re
with open('blueprints-index.json') as f:
data = json.load(f)
for key, val in data.items():
url = val.get('screenshot_url', '')
m = re.search(r'/([0-9a-f]{40})/(blueprints/.+)', url)
if m:
path = m.group(2)
val['screenshot_url'] = '/community-' + path
with open('blueprints-index.json', 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
\""
info "蓝图库已同步($(ssh "$REMOTE_HOST" "ls $REMOTE_ROOT/community-blueprints/ | wc -l") 个蓝图)"
} || warn "蓝图库同步失败"
# 主题测试数据
info "下载主题测试数据..."
ssh "$REMOTE_HOST" "curl -sL --connect-timeout 15 --max-time 60 \
'https://gh.wpcy.net/https://raw.githubusercontent.com/WordPress/theme-test-data/master/themeunittestdata.wordpress.xml' \
-o $data_dir/themeunittestdata.wordpress.xml 2>/dev/null" && info "themeunittestdata.wordpress.xml 已更新" || warn "主题测试数据下载失败"
# wp-cli.phar
if ssh "$REMOTE_HOST" "[ -f $REMOTE_ROOT/wp-cli.phar ]"; then
info "wp-cli.phar 已存在,跳过"
else
info "下载 wp-cli.phar..."
ssh "$REMOTE_HOST" "curl -sL --connect-timeout 15 --max-time 120 \
'https://gh.wpcy.net/https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar' \
-o $REMOTE_ROOT/wp-cli.phar 2>/dev/null" && info "wp-cli.phar 已下载" || warn "wp-cli.phar 下载失败"
fi
ssh "$REMOTE_HOST" "chown -R $REMOTE_OWNER $REMOTE_ROOT/blueprints-index.json $data_dir $REMOTE_ROOT/wp-cli.phar 2>/dev/null || true"
info "镜像完成"
}
do_upgrade() {
echo "Playground 引擎升级流程:"
echo " 1. play-deploy backup"
echo " 2. 从 GitHub Releases 下载最新构建,上传到 $REMOTE_ROOT"
echo " (保留 blueprints/ plugins/ index.html plugins.json data/"
echo " 3. play-deploy localize # 自动应用所有本地化补丁"
echo " 4. play-deploy mirror # 镜像 GitHub 资源"
echo " 5. play-deploy verify # 验证站点"
echo ""
echo "完整命令:"
echo " play-deploy backup && play-deploy localize && play-deploy mirror && play-deploy verify"
}
# ── 主入口 ─────────────────────────────────────────
cmd="${1:-deploy}"
case "$cmd" in
deploy) do_deploy ;;
status) do_status ;;
rollback) do_rollback ;;
verify) do_verify ;;
backup) do_backup ;;
localize) do_localize "${2:-}" ;;
mirror) do_mirror ;;
upgrade) do_upgrade ;;
*)
echo "play-deploy — play.wenpai.net 部署工具"
echo ""
echo "用法: play-deploy [command]"
echo " deploy 拉取最新代码并部署到生产 (默认)"
echo " status 对比 git 与生产环境差异"
echo " rollback 回滚到上一个备份版本"
echo " verify 验证线上站点可用性"
echo " backup 仅备份当前生产文件"
echo " localize 应用中国本地化补丁 (--dry-run 预览)"
echo " mirror 镜像 GitHub 资源到生产服务器"
echo " upgrade Playground 引擎升级指南"
;;
esac