Skip to content

Commit ad8ca71

Browse files
authored
ci: wire existing check scripts and add published-site health probe (#132)
新增 ci.yml,在 push / PR 时运行 tests/ 下已有的两个校验脚本。 新增 site-health.yml,每 6 小时探测已发布站点的 8 个 URL(含一条 404 反向断言)。 修正 site_static_smoke.test.sh:rg 改为 grep -qF,resources.json 条数下限 120 改为 100。
1 parent 9b2a1b5 commit ad8ca71

3 files changed

Lines changed: 130 additions & 9 deletions

File tree

.github/workflows/ci.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: CI
2+
3+
# 运行仓库内已有的校验脚本(tests/)。
4+
# 这些脚本在 2026-03 修复 /interview/ 404 时写下,用于锁住当时的修复,
5+
# 但此前没有任何工作流引用它们。
6+
7+
on:
8+
push:
9+
branches: ["main"]
10+
pull_request:
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
16+
concurrency:
17+
group: ci-${{ github.ref }}
18+
cancel-in-progress: true
19+
20+
jobs:
21+
checks:
22+
name: Static checks
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v7
26+
27+
# tests/site_static_smoke.test.sh 需要 node --check 校验 assets/site.js
28+
- uses: actions/setup-node@v7
29+
with:
30+
node-version: '22'
31+
32+
- name: Static site smoke checks
33+
run: bash tests/site_static_smoke.test.sh
34+
35+
- name: InterviewGuide / research integration checks
36+
run: bash tests/interviewguide_external_integration.test.sh

.github/workflows/site-health.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: Site health
2+
3+
# 定期访问已发布站点的关键 URL,确认它们仍然可达。
4+
#
5+
# 背景:/AgentGuide/interview/ 曾在 2026-02-26 上线后 404,直到 2026-03-09
6+
# 才由外部贡献者提 PR #36 修复,暴露窗口约 11 天。仓库内的其它校验都是对
7+
# 源文件做断言,没有任何东西会去访问真实站点。
8+
#
9+
# 说明:
10+
# - 只检查 HTTP 状态码。页面返回 200 但内容损坏,这里检测不到。
11+
# - GitHub 的定时任务不保证准时,高峰期会延迟甚至跳过;6 小时是名义间隔。
12+
# - 定时工作流的失败通知发给最后修改过下方 cron 表达式的用户。
13+
14+
on:
15+
schedule:
16+
- cron: '0 */6 * * *'
17+
workflow_dispatch:
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
probe:
24+
name: Probe published URLs
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Probe published site
28+
run: |
29+
set -uo pipefail
30+
BASE="https://adongwanai.github.io/AgentGuide"
31+
failed=0
32+
33+
{
34+
echo "### 站点探测结果"
35+
echo
36+
echo "| 结果 | 状态码 | 路径 | 覆盖 |"
37+
echo "|:---:|:---:|:---|:---|"
38+
} >> "$GITHUB_STEP_SUMMARY"
39+
40+
probe() {
41+
path="$1"; expected="$2"; label="$3"
42+
# --retry 只对网络错误和 5xx/408/429 生效,404 不会被重试
43+
# curl 在连接失败时自身会输出 000,因此这里不再追加,只兜底空值
44+
code="$(curl -sS -I -o /dev/null -w '%{http_code}' \
45+
--retry 2 --retry-delay 5 --max-time 30 \
46+
"$BASE$path" 2>/dev/null)" || true
47+
code="${code:-000}"
48+
if [ "$code" = "$expected" ]; then
49+
printf ' ok %-4s %-38s %s\n' "$code" "$path" "$label"
50+
printf '| ✅ | %s | `%s` | %s |\n' "$code" "$path" "$label" >> "$GITHUB_STEP_SUMMARY"
51+
else
52+
printf ' FAIL %-4s %-38s %s (期望 %s)\n' "$code" "$path" "$label" "$expected"
53+
printf '| ❌ | %s(期望 %s) | `%s` | %s |\n' "$code" "$expected" "$path" "$label" >> "$GITHUB_STEP_SUMMARY"
54+
failed=1
55+
fi
56+
}
57+
58+
echo "探测 $BASE"
59+
echo
60+
61+
# 每个探测点对应 deploy-pages.yml 中一个独立的产物拷贝步骤,
62+
# 任一步骤失败时其余步骤仍会成功,所以必须逐个覆盖。
63+
probe "/" 200 "首页 / Pages 服务本身"
64+
probe "/assets/site.js" 200 "cp -r assets/."
65+
probe "/data/resources.json" 200 "cp data/resources.json(首页筛选数据源)"
66+
probe "/research/" 200 "ai-research-ebook 构建与拷贝"
67+
probe "/research/docs/intro/01-overview/" 200 "research 的 BASE_PATH 与深层路由"
68+
probe "/interview/" 200 "InterviewGuide 构建与拷贝"
69+
probe "/interview/questions/q-1/" 200 "interview 的 BASE_PATH 与深层路由"
70+
71+
# 反向断言:确认不存在的路径确实返回 404。
72+
# 若某天引入了 catch-all 兜底规则导致所有路径都返回 200,
73+
# 上面全部探测会集体失去意义,这一条用于兜底自检。
74+
probe "/__nonexistent-health-probe__/" 404 "404 仍能正确返回(探测器自检)"
75+
76+
echo
77+
if [ "$failed" -ne 0 ]; then
78+
echo "站点探测失败:上面标记 FAIL 的 URL 未返回期望状态码。"
79+
exit 1
80+
fi
81+
echo "全部探测点正常。"

tests/site_static_smoke.test.sh

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
55

66
node --check "$ROOT_DIR/assets/site.js"
77

8-
rg -q '<link rel="canonical" href="https://adongwanai.github.io/AgentGuide/">' "$ROOT_DIR/index.html"
9-
rg -q '<meta property="og:image" content="https://adongwanai.github.io/AgentGuide/assets/agentguide-social.png">' "$ROOT_DIR/index.html"
10-
rg -q 'application/ld\+json' "$ROOT_DIR/index.html"
11-
rg -q 'data/resources.json' "$ROOT_DIR/assets/site.js"
12-
rg -q 'data-github-forks' "$ROOT_DIR/index.html"
8+
# 使用 grep -qF(固定字符串)而非 rg:ripgrep 未必存在于 CI runner 镜像中,
9+
# 而这些断言全部是字面量匹配,不需要正则。
10+
grep -qF '<link rel="canonical" href="https://adongwanai.github.io/AgentGuide/">' "$ROOT_DIR/index.html"
11+
grep -qF '<meta property="og:image" content="https://adongwanai.github.io/AgentGuide/assets/agentguide-social.png">' "$ROOT_DIR/index.html"
12+
grep -qF 'application/ld+json' "$ROOT_DIR/index.html"
13+
grep -qF 'data/resources.json' "$ROOT_DIR/assets/site.js"
14+
grep -qF 'data-github-forks' "$ROOT_DIR/index.html"
1315

1416
python3 - "$ROOT_DIR/data/resources.json" <<'PY'
1517
import json
@@ -18,12 +20,14 @@ from pathlib import Path
1820
1921
resources = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
2022
ids = [item["id"] for item in resources]
21-
assert len(resources) >= 120
23+
# 下限用于捕捉「生成器产出为空或严重损坏」,不用于统计内容数量。
24+
# 原值 120 贴着当时的实际条数(121),删除任意一篇文档都会误报。
25+
assert len(resources) >= 100, f"resources.json only has {len(resources)} items"
2226
assert len(ids) == len(set(ids))
2327
assert all(item["category"] and item["type"] and item["level"] for item in resources)
2428
assert any(item["id"] == "external-learn-workbuddy" for item in resources)
2529
PY
2630

27-
rg -q '<loc>https://adongwanai.github.io/AgentGuide/</loc>' "$ROOT_DIR/sitemap.xml"
28-
rg -q '<loc>https://adongwanai.github.io/AgentGuide/research/</loc>' "$ROOT_DIR/sitemap.xml"
29-
rg -q '<loc>https://adongwanai.github.io/AgentGuide/interview/questions/q-1/</loc>' "$ROOT_DIR/sitemap.xml"
31+
grep -qF '<loc>https://adongwanai.github.io/AgentGuide/</loc>' "$ROOT_DIR/sitemap.xml"
32+
grep -qF '<loc>https://adongwanai.github.io/AgentGuide/research/</loc>' "$ROOT_DIR/sitemap.xml"
33+
grep -qF '<loc>https://adongwanai.github.io/AgentGuide/interview/questions/q-1/</loc>' "$ROOT_DIR/sitemap.xml"

0 commit comments

Comments
 (0)