Files
blog/blog-admin/tools/deploy.sh
T

114 lines
4.1 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# ===========================================================================
# artalk-cf 一键部署(第 2~8 步)
#
# 前置:已经跑过 `npx wrangler login`
# 用法:
# export ADMIN_PASSWORD='你的后台密码'
# bash tools/deploy.sh
#
# 可选环境变量:
# TOKEN_SECRET 不传则自动生成随机串
# DB_NAME 默认 artalk-cf
# SKIP_IMPORT=1 跳过数据导入
# ===========================================================================
set -euo pipefail
cd "$(dirname "$0")/.."
DB_NAME="${DB_NAME:-artalk-cf}"
WR="node node_modules/wrangler/bin/wrangler.js"
if [ ! -f node_modules/wrangler/package.json ]; then
echo "缺少依赖,先跑:npm install" >&2
exit 1
fi
if [ -z "${ADMIN_PASSWORD:-}" ]; then
echo "请先设置管理员密码:export ADMIN_PASSWORD='...'" >&2
exit 1
fi
echo "==> 1/8 检查登录状态"
# 兼容三种情况:OAuth 登录、作用域 Token(cfut_)、账户 Token(cfat_)
WHOAMI=$($WR whoami 2>&1 || true)
if ! printf '%s' "$WHOAMI" | grep -qiE 'associated with the email|Account Name|Account ID|accounts'; then
echo "$WHOAMI" | tail -5
echo
echo "没检测到可用的凭据。二选一:" >&2
echo " a) 交互登录: npx wrangler login" >&2
echo " b) 用作用域 Token: export CLOUDFLARE_API_TOKEN='cfut_...'(可再加 CLOUDFLARE_ACCOUNT_ID)" >&2
exit 1
fi
echo "$WHOAMI" | grep -iE 'Account Name|Account ID|associated with' | head -4 | sed 's/^/ /'
echo "==> 2/8 创建 D1 数据库(已存在则复用)"
DB_ID=$($WR d1 list --json 2>/dev/null \
| node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{try{const a=JSON.parse(s);const m=a.find(x=>x.name===process.argv[1]);if(m)console.log(m.uuid)}catch{}})" "$DB_NAME")
if [ -z "$DB_ID" ]; then
OUT=$($WR d1 create "$DB_NAME" 2>&1)
echo "$OUT"
DB_ID=$(printf '%s' "$OUT" | grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' | head -1)
fi
if [ -z "$DB_ID" ]; then
echo "拿不到 database_id,请手动去控制台复制后填进 wrangler.toml" >&2
exit 1
fi
echo " database_id = $DB_ID"
echo "==> 3/8 写入 wrangler.toml"
node -e "
const fs=require('fs');
const p='wrangler.toml';
let s=fs.readFileSync(p,'utf8');
const before=s;
s=s.replace(/database_id\s*=\s*\"[^\"]*\"/, 'database_id = \"' + process.argv[1] + '\"');
s=s.replace(/database_name\s*=\s*\"[^\"]*\"/, 'database_name = \"' + process.argv[2] + '\"');
if(s===before){console.error('wrangler.toml 里没找到 database_id,请手动填');process.exit(1);}
fs.writeFileSync(p,s);
console.log(' ok');
" "$DB_ID" "$DB_NAME"
echo "==> 4/8 写入机密"
TOKEN_SECRET="${TOKEN_SECRET:-$(node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))")}"
printf '%s' "$TOKEN_SECRET" | $WR secret put TOKEN_SECRET
printf '%s' "$ADMIN_PASSWORD" | $WR secret put ADMIN_PASSWORD
echo "==> 5/8 建表"
$WR d1 execute "$DB_NAME" --remote -y --file=./schema.sql
echo "==> 6/8 部署"
DEPLOY_OUT=$($WR deploy 2>&1 | tee /dev/stderr)
BASE=$(printf '%s' "$DEPLOY_OUT" \
| grep -oE 'https://[A-Za-z0-9._-]+\.workers\.dev' | head -1)
if [ -z "$BASE" ]; then
read -r -p "请手动粘贴部署输出里的地址(如 https://artalk-cf.xxx.workers.dev): " BASE
fi
BASE="${BASE%/}"
echo " BASE = $BASE"
echo "==> 7/8 导入评论数据(必须在初始化管理员之前——导入会清空 users 表)"
if [ "${SKIP_IMPORT:-}" != "1" ]; then
if command -v python >/dev/null 2>&1; then
python tools/import_artrans.py
else
python3 tools/import_artrans.py
fi
bash tools/import-out/run.sh --remote
else
echo " (SKIP_IMPORT=1,跳过)"
fi
echo "==> 8/8 初始化站点与管理员"
curl -sS -X POST "$BASE/api/v2/setup" -H 'Content-Type: application/json' -d '{}'
echo
echo
echo "============================================================"
echo " 完成。接下来:"
echo " 1) 验证:bash tools/smoke.sh $BASE"
echo " 2) 域名:见 部署清单.md 第 9 步(NS 必须在 Cloudflare)"
echo " 3) 切博客:hugo.toml 的 [params.artalk] server = $BASE"
echo "============================================================"