維護記錄

完成的工作

  • 拉取 origin/master 的 6 個新提交(fast-forward),工作樹已同步 ✅
  • 應用戶要求,優化工作流 #1(拆分 chore: auto-fix content 噪音 commit),其他建議(PR 預覽、URL 穩定、Dependabot)不動 ✅
  • 實現 scripts/git-commit-push.ts 的自動 commit message 分類:
    • 5 個分類路徑:rename / fm / format / covers / posts
    • 混合或無法識別時回退到 --message-fallback
  • 新增 --message-fallback 參數,deploy.yml 調用改為同時傳 --message--message-fallback
  • 頂層 CLI 代碼包到 isMain 守衛,避免被 import 時誤執行(之前 import 會因 process.exit(1) 失敗)
  • 新增 scripts/__tests__/git-commit-push.test.ts,13 個測試覆蓋所有分類路徑
  • 測試 + E2E dry-run 驗證:rename 漂移 → chore(rename): sync post slugs (N files);fm 注入 → chore(fm): inject frontmatter (N files);混合 → fallback
  • 全部測試 164/164 通過,Hugo 構建 clean ✅

遇到的問題

  • 測試陷阱 1:git rename 檢測對短文件失敗 ⚠️
    • 最初測試 fixture 只寫 10 行 body,git -M20% 閾值下也檢測不出 rename
    • 實際 rename-posts.js 跑的都是 30+ 行文章,body 微調 < 20% 行
    • 解決:測試 fixture 加到 40 段,模擬真實文章密度
  • 測試陷阱 2:git mv vs 文件系統 mv ⚠️
    • 最初用 mv 改文件名 + writeFileSync 覆蓋,git 不識別為 rename(變 A+D)
    • 解決:改用 git mv + 追加一行,模擬 rename-posts.js 真實操作
  • 測試陷阱 3:Apple Git 的 git rm 副作用 ⚠️
    • git rm 刪除 tracked 文件後,git 2.x 會清理空目錄
    • 後續 writeFileSync 寫新 SVG 時 ENOENT
    • 解決:測試 setup 時預放 .gitkeep 佔位文件
  • 模塊化陷阱:頂層代碼副作用 ⚠️
    • 把分類函數 export 給測試用後,import 時頂層 if (!message) process.exit(1) 會觸發
    • 解決:用 pathToFileURL(process.argv[1]).href === import.meta.url 守衛 CLI 代碼
  • 未用 import ⚠️
    • 測試文件 import 了 join from 'node:path',但實際用的是 Array.prototype.join
    • 自審時發現並清理,避免汙染

決策點

  • 不改 sync-covers.yml 的調用方式:它只傳 --message 不傳 --message-fallback,新腳本會讓 fallback = --message(原行為)。而且它的場景(cover IO)會被自動分類為 chore(covers): ...,永遠走不到 fallback 分支。比之前更精確 ✅
  • 降級策略而非強制分類:當改動是"rename + 改了正文"或"fm 注入 + 新建 cover"這種混合,分類不可靠,返回 null 讓 fallback 接住。不冒險亂分類

下次建議

  • 觀察接下來幾天的 auto-fix commit,如果 chore(rename) / chore(fm) 頻繁出現,說明分類正確;如果大量 chore: auto-fix content (fallback) 出現,說明有分類邏輯沒覆蓋的場景,需要擴展
  • sync-covers.yml 也可以從 chore(assets): remove orphan cover images 升級到自動分類(會產出 chore(covers): -N cover image(s)),讓兩個 workflow 的 commit 風格統一

文件變更清單

  • 新增:scripts/__tests__/git-commit-push.test.ts(13 測試)
  • 修改:scripts/git-commit-push.ts(+196 行:isMain 守衛 + classifyStagedChanges + 子函數)
  • 修改:.github/workflows/deploy.yml(commit step 加 --message-fallback + 註釋)