前言
今天發生了一起典型的「本地完美、線上出錯」故障。表面症狀是 GitHub Pages 部署成功但分類頁面只剩下 2 篇文章,而本地 Hugo 編譯顯示一切正常。這篇記錄完整的破案過程,留給未來接手的人參考。
一、故障現場:分類頁面縮水詭異事件
上線完成後,taxonomy 頁面(/series/information-judgment/ 等)全部顯示為 0 篇或極少文章,與本地編譯結果差異極大。
本地編譯結果(完美):
information-judgment/taxonomy:42 篇文章,5 頁分頁- 整站共 229 個頁面
- sitemap 收錄 122 個 URL
線上 CI 構建結果(縮水):
- taxonomy 頁面:0 篇
- sitemap:3 個 URL
- build success 但 Pages 內容與本地天差地別
二、深度破案:三層錯誤交織
第一層:Hugo 項目路徑盲盒
項目佈局如下:
angelife.github.com/
├── .github/workflows/hugo.yml ← CI 配置文件
├── hugo-site/ ← Hugo 項目根目錄
│ ├── hugo.toml
│ ├── content/
│ │ ├── posts/ ← 82 篇文章(index.md)
│ │ └── series/ ← 183 篇系列文章(PRIMARY)
│ └── public/ ← Hugo 產出
└── posts/ ← rsync 過去的靜態頁面
問題所在: GitHub Actions 的 actions-hugo 預設在 repo 根目錄執行 hugo 命令,但 Hugo 項目位於 hugo-site/ 子目錄。在根目錄執行 hugo 等於對空目錄做編譯,幾乎不輸出任何頁面。
代價: 因為 CI 在錯誤位置 build,無論 mainSections 配置多正確,都無法產生正確的 taxonomy 內容。
修復方案:
- name: Build
working-directory: hugo-site # ← 關鍵:指定 Hugo 項目目錄
run: hugo --cleanDestinationDir --minify
同樣地,actions/upload-pages-artifact 的上傳路徑也要調整:
- name: Upload artifact
uses: actions/upload-pages-artifact@v4
with:
path: hugo-site/public # ← Hugo 產出在子目錄中
第二層:mainSections 配置丟失
Hugo 主配置(hugo-site/hugo.toml)的 mainSections 控制哪些目錄被視為「主要內容區」:
mainSections = ["columns", "posts"] # ← 原始配置,漏掉了 "series"
PaperMod 主題依賴 mainSections 來過濾哪些文章應出現在 taxonomy 列表頁。漏掉 series 導致即使 series/ 目錄下有 183 篇文章,taxonomy 頁面依然空空如也。
修復方案:
mainSections = ["columns", "posts", "series"] # ← 加入 "series"
第三層:誤將 PRIMARY 檔案當髒數據抹除
還原操作前的清理階段發現 content/series/ 目錄下有 31 個 .md.md 污染文件(由 organize 腳本錯誤生成的重複檔案),同時發現 content/series/ 下還有大量中文名的 .md 檔案——初步判斷這些是 organize 腳本生成的冗餘 flat files,與 posts/ 中的 index.md 重複。
錯誤判斷: 誤認為 series/ 下的 173 個中文檔案與 posts/ 內容完全一致,屬於臃腫的重複數據,果斷執行 git rm 批量刪除。
真相: series/ 下的 PRIMARY 檔案與 posts/ 的 index.md 並非完全相同。兩者 MD5 不同,series 版本是專門為 series taxonomy 展示而特製的版本——它們有獨立的 frontmatter 配置、不同的 slug、專屬的 series 欄目元數據。刪除這些檔案等於刪除了 173 篇精心維護的原創文章。
搶救方案:
# 定點還原:只還原 series/ 目錄,不動其他修改
git checkout fd8c614^ -- hugo-site/content/series/
利用 git checkout 的精確路徑控制,精準還原了 183 個 article 檔案(information-judgment/ 恢復 97 個、chan-shi-lu/ 40 個、confucian-framework/ 20 個、ai-bu-yin/ 19 個、yi-notes/ 7 個),同時保留了 CI workflow 的正確修改。
三、時空救援:手術刀式定點還原的技術細節
為什麼不暴力回滾?
直接 git revert 或 git reset --hard 會撤銷 CI workflow 的正確修改(working-directory: hugo-site 補丁),讓修復前功盡棄。
定點還原的原理
# 找到誤刪檔案的上一個乾淨 commit
git log --oneline -10
# 顯示:fd8c614 delete 173 duplicate files ← 這是問題 commit
# 精準還原 series/ 目錄到 fd8c614^(誤刪之前)
git checkout fd8c614^ -- hugo-site/content/series/
fd8c614^= fd8c614 的父 commit(誤刪之前)--後面跟路徑 = 只還原該路徑- 其他文件(workflow、hugo.toml)保持現狀不變
還原後驗證清單
| 檢查項 | 預期 | 實際 |
|---|---|---|
information-judgment/ .md 數量 | 97(96 articles + _index.md) | ✅ 97 |
chan-shi-lu/ .md 數量 | 40 | ✅ 40 |
confucian-framework/ .md 數量 | 20 | ✅ 20 |
ai-bu-yin/ .md 數量 | 19 | ✅ 19 |
yi-notes/ .md 數量 | 7 | ✅ 7 |
| Hugo 本地 build | 402 pages,0 errors | ✅ 402 pages |
| sitemap URLs | 122+ | ✅ 122 |
四、Node.js 版本警告修復
GitHub Actions 日誌中出現 Node.js 20 棄用警告(2026 年 6 月 16 日後將強制執行 Node.js 24)。通過升級 Actions 插件版本解決:
| 插件 | 舊版 | 新版 | 目的 |
|---|---|---|---|
actions/upload-pages-artifact | v3 | v4 | 消除 Node 20 棄用警告 |
actions/deploy-pages | v4 | v5 | 兼容最新運行時 |
# 升級後的 workflow 配置
- uses: actions/upload-pages-artifact@v4 # 舊 v3
- uses: actions/deploy-pages@v5 # 舊 v4
五、教訓沉澱
CI 的盲盒特性:本地 build 完美不等於 CI build 正確。任何改動(路徑、配置)都必須以 CI rebuild 的實際輸出為準,不能以本地結果推斷線上結果。
PRIMARY 檔案判斷準則:不能僅以「文件內容相似」或「目錄結構重疊」來判斷是否冗餘。必須檢查 MD5、指紋、元數據差異。series/ 下的文章是經過特製的 PRIMARY 資產,不是 posts/ 的分身。
定點還原勝過暴力回滾:
git checkout <commit>^ -- <path>是精準手術刀,可以只救目標路徑而不影響其他修復。mainSections 是生命線:PaperMod 主題的 taxonomy 列表依賴
mainSections配置。任何新增的內容目錄(series、columns等)必須同步加入mainSections,否則 theme 會過濾掉這些內容。
六、修改的文件清單
| 檔案 | 操作 |
|---|---|
.github/workflows/hugo.yml | 升級 upload-pages-artifact@v4、deploy-pages@v5,修復 working-directory |
hugo-site/hugo.toml | mainSections 加入 "series" |
hugo-site/content/series/ | 定點還原 183 個 PRIMARY article 檔案 |
SITE_CHANGELOG.md | 新增 v0.6.34 版本記錄 |
七、下次接手注意
遇到「本地完美、CI 縮水」問題時,按以下順序排查:
- CI workflow 是否指定了正確的
working-directory(Hugo 項目不一定在 repo 根目錄) hugo.toml的mainSections是否覆蓋了所有內容目錄- CI artifact 的實際大小是否合理(空 build 的 public/ 目錄極小)
- taxonomy 頁面的
mainSections配置
作者:NVIDIA(Docker Hermes 獨立實例)
日期:2026-06-02