GitHub Actions 排错实录:从 8 小时 Pages 卡死中提取的 3 个真实踩坑经历
📌 本文由 AI 辅助生成并经人工审核发布 | TechPassive — AI 驱动的内容测试站点,专注于效率工具与 SaaS 真实评测
2026 年 4 月 28 日,我的博客流水线遭遇了一次罕见的 GitHub 基础设施故障。从 22PM cron 触发,到最终确认问题,花了将近 8 个小时。这篇文章把完整的排查过程记录下来,包含三个我当时并不熟悉的踩坑经历:workflow_dispatch 创建后 runner 从不分配、raw.githubusercontent.com SSL 超时,以及Pages 构建永久卡在旧 commit。
踩坑一:workflow_dispatch 创建成功,runner 从不分配
第一反应是检查 GitHub Actions 的运行状态。打开仓库的 Actions 标签页,看到了这样的状态:
Workflow: GitHub Pages Deploy
Status: queued
Jobs: 0
Started: 2026-04-28 22:XX:XX UTC
Duration: running...
workflow_dispatch 本身是成功的——API 返回 200,run 被创建了。但问题是:queued 状态一直持续,runner 从不分配,jobs 始终为 0。
这是 GitHub 基础设施层面的一种卡死状态,不是我的代码问题。GitHub 的 runner 分配系统在高负载或区域性问题时可能出现这种行为——任务入队但不分配具体机器。
我尝试了三次手动重新触发 workflow_dispatch:
# 通过 GitHub CLI 手动触发
gh workflow run deploy.yml
# 结果:每次都创建了新 run,每次都卡在 queued,runner 0
三次尝试,三次相同结果。这基本排除了"单次网络抖动"的可能,确认是 GitHub 端持续的基础设施问题。
踩坑二:raw.githubusercontent.com SSL 超时
在等待 runner 分配的过程中,我开始手动验证 GitHub API 的可用性。用 curl 测试了几个关键端点:
# GitHub API - 正常
curl -s -o /dev/null -w "%{http_code}" https://api.github.com/repos/yaohehe/yaohehe.github.io
# 返回:200 ✅
# GitHub raw content - SSL 超时
curl -s -o /dev/null -w "%{http_code}" --max-time 10 https://raw.githubusercontent.com/
# 返回:timeout ❌
在约 23:14,我测试了 raw.githubusercontent.com 的 SSL handshake,结果超时。这说明 GitHub 的 CDN 层面也存在间歇性访问问题。
这个细节很关键:Pages workflow 在构建时需要从 raw.githubusercontent.com 拉取依赖资源。如果 CDN 超时,artifact 上传阶段就会失败,即使 runner 最终被分配了。
这里有一个重要的区分:GitHub API(api.github.com)和 GitHub raw CDN(raw.githubusercontent.com)是两个独立的基础设施。前者正常不代表后者也正常。
踩坑三:Pages 构建永久卡在旧 commit
我手动检查了 GitHub 上最新的 commit 历史。确认:新文章文件已经推送至 GitHub 仓库,SHA 存在,文件内容完整。
但打开网站一看,文章还是 404。
用 GitHub CLI 查看最新的 Pages deploy 状态:
gh run list --workflow=deploy.yml --limit 5
结果揭示了真相:Pages 构建最后一次成功的 commit 是 3bc9c6e,时间戳是 April 23。这意味着从 April 23 到 April 28,整整 5 天,Pages 没有重建过。所有的 commit,包括新推送的文章,都在这个旧版本之后——所以永远不会被上线。
根因链分析
把三个踩坑串联起来,完整的故障传导链是这样的:
- 22PM cron 触发:流水线生成文章,GitHub API push 成功(PUT 返回 200)
- workflow_dispatch 创建:触发 Pages rebuild,run 入队
- runner 分配卡死:GitHub 基础设施问题,queued 状态持续,runner 从不启动
- raw.githubusercontent.com 超时(~23:14):即使 runner 启动,CDN 超时也会导致 artifact 上传失败
- Pages 从不重建:Pages 构建卡在 April 23 的 3bc9c6e,新 commit 全部被忽略
- 文章 404:文件在 GitHub 仓库里,但永远上不了线
这不是单点故障,是GitHub 基础设施三层同时出现问题:runner 分配系统 + CDN 可用性 + Pages 构建队列。这超出了我的 流水线代码能处理的范围。
解决方案:API push + 等 GitHub 恢复
既然 Pages 重建是 GitHub 基础设施问题,我选择了最务实的方案:
- 确认文章已推送至 GitHub:通过 GitHub API 验证文件 SHA,文章内容完整存在
- 等待 GitHub 基础设施恢复:runner 分配和 CDN 恢复后,Pages 会自动重建
- 后续文章走备用路径:修复了 publish-articles.py 的静默失败问题,新增
push_file_with_retry(),失败时 exit 1 而不是 exit 0
第二天 Pages 恢复了自动重建,所有文章上线。这次 8 小时故障没有造成数据丢失——因为 GitHub API push 是成功的。真正的问题是 Pages 构建队列的阻塞,以及流水线没有及时发现这个问题。
三个核心教训
- workflow_dispatch 成功 ≠ Pages 重建成功:API 返回 200 只说明 GitHub 收到了请求,不代表构建流程走完了。要主动检查
gh run list的实际状态。 - GitHub API 和 GitHub CDN 是独立基础设施:api.github.com 正常不代表 raw.githubusercontent.com 正常。Pages 构建依赖 CDN,CDN 超时会导致 artifact 阶段静默失败。
- Pages 构建状态要纳入流水线可观测性:如果 Pages 连续两次 deploy 用的 commit 相同,就应该触发告警。这是流水线目前缺失的一环。
这次故障让我意识到:流水线的可观测性不只是"看日志有没有报错",还要主动验证最终结果——文章到底有没有上线。不能假设 push 成功就等于用户能访问到内容。
🔗 推荐工具
这些是我们精心挑选的工具,使用我们的 affiliate 链接支持我们持续产出优质内容: