Files
blog/scripts/fetch_snapshots.sh
T
zqlit 571d552c9d fix(build): 消除构建期远程拉取隐患 + 评论提交反馈 + 友链卡片移动端
构建隐患(本次丢构建的根因)
- footer.html 用 resources.GetRemote 在每个页面渲染时拉 api/links 与 api/feeds,
  构建节点连不上 Cloudflare 时重试撞穿 Hugo partial 30s 超时 → 整站构建失败
- 改为「流水线 curl 快照 + 模板读本地文件」:
  · 新增 scripts/fetch_snapshots.sh,一次拉齐 conf / friend_links / friend_feeds
    (--max-time 30 --retry 2,JSON 校验,失败一律删文件且恒 exit 0)
  · .cnb.yml Hugo 构建 stage 改为调用该脚本
  · footer.html 改读 site.Data.friend_links / site.Data.friend_feeds,缺失渲染空值
  · .gitignore 忽略 /data/friend_links.json 与 /data/friend_feeds.json
- 降级实测:删掉快照后构建仍 EXIT=0,产物 friendLinks 为空数组

评论提交反馈(artalk.js 新增 __atkSubmit 模块)
- 校验:config.beforeSubmit 拦下 内容空 / 昵称空 / 邮箱空 / 邮箱格式错(网址不校验)
- 发送中:editor-submit 常驻 loading,超 7s 补「网络较慢」
- 成功:editor-submitted 按 normal/reply/edit 分文案,is_pending 提示等待审核
- 失败:拦 POST /api/v2/comments,403/429/4xx/5xx/网络异常全部翻译成人话
- 失败时输入内容保留,并清掉 Artalk 自带的重复小字通知
- 无头浏览器实测 19/19 通过(POST 走 mock,未向线上写数据)

友链申请卡片移动端
- max-width:640px 下隐藏 .atk-fl-nick(昵称 + 博主徽章),桌面端不变

改动:6 files, +282 / -61
2026-10-04 17:38:04 +08:00

74 lines
3.4 KiB
Bash
Raw 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
# =============================================================================
# 构建期数据快照 —— 把「模板渲染时必须用、但只能从远端拿」的数据先 curl 成本地文件
# =============================================================================
# 为什么必须这么做(2026-10-04 实战教训):
# footer.html 原先用 resources.GetRemote 拉 /api/links 与 /api/feeds。Hugo 的
# GetRemote 是**在模板渲染过程中同步发请求**的,而 footer 每个页面都要走一遍。
# 构建节点(国内)到 api.200181.xyz(Cloudflare)一旦抖动:
# WARN Links API fetch failed: dial tcp 104.21.58.236:443: i/o timeout
# WARN Links API fetch failed: ... connection reset by peer
# Artalk 无关,但这两个拉取会一直重试 → 撞穿 Hugo 的 `partial` 30 秒超时 →
# ERROR render of "home" failed: partial "footer.html" timed out after 30s
# Error: error building site → exit code: 1
# 整站构建失败、站点不更新(实测白等 14.5 分钟)。
#
# 改成「stage 里 curl 一次 + 模板只读本地文件」后:
# 网络问题最多让某个快照变旧/为空(模板 with 判空 → 渲染空值),
# **永远不会再让构建挂掉**。命中失败时一律删文件,绝不留半截内容。
#
# 在流水线里由 .cnb.yml 的「Hugo 构建」stage 调用;本地预览想拿到同款数据
# 也可以直接跑:bash scripts/fetch_snapshots.sh
#
# 产物(均在 .gitignore 里,不入库):
# data/artalk_conf.json 评论 /conf(首屏省一跳跨境往返,见 partials/artalk.html)
# data/friend_links.json 友链 → window.friendLinks(评论区「友链」徽章)
# data/friend_feeds.json 友圈 → window.friendFeeds(评论区「友圈」徽章)
# =============================================================================
set -u
BASE="${RSSAPI_BASE:-https://api.200181.xyz}"
BASE="${BASE%/}"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DATA_DIR="$ROOT/data"
mkdir -p "$DATA_DIR"
# JSON 合法性校验:python3 不一定有(本机 Windows 可能没有),没有就跳过校验
validate_json() {
command -v python3 >/dev/null 2>&1 || return 0
python3 -c 'import json,sys;json.load(open(sys.argv[1],encoding="utf-8"))' "$1" 2>/dev/null
}
# snap <输出文件名> <URL>
# 成功:原子替换(先写 .tmp 再 mv),并打印字节数
# 失败:删除目标文件(含 .tmp),返回非 0 —— 但本脚本最后统一 exit 0,
# 因为「快照拿不到」是可接受的降级,不该阻断构建。
snap() {
local name="$1" url="$2" out tmp ok=1
out="$DATA_DIR/$name"
tmp="$out.tmp"
if curl -fsS --max-time 30 --retry 2 --retry-delay 2 --retry-connrefused \
-H 'User-Agent: hugo-build-snapshot' "$url" -o "$tmp" 2>/dev/null; then
if [ -s "$tmp" ] && validate_json "$tmp"; then
mv -f "$tmp" "$out"
echo "✅ $name 就绪 $(wc -c < "$out" | tr -d ' ') 字节"
return 0
fi
echo "⚠️ $name 内容校验失败(空文件或非法 JSON)"
else
echo "⚠️ $name 拉取失败:$url"
fi
rm -f "$tmp" "$out"
return 1
}
echo "── 构建期快照(源:$BASE)──"
snap artalk_conf.json "$BASE/api/v2/conf" || true
snap friend_links.json "$BASE/api/links?all=1" || true
snap friend_feeds.json "$BASE/api/feeds" || true
exit 0