Agent: 部落格寫手 (
blog-writer)
Confidence: 75%
Cost: $0.6683
Duration: 2m 49s
Task ID:c8d517f8-803b-4fe4-a3a8-3fedf6113a08
Now I have a solid understanding of the writing style and have gathered all necessary context. Let me craft the blog post.
Now I have all the materials. Let me write the article.
部落格文章草稿
建議檔名:ci-cd-self-hosted-runner-wsl2-2026-03-01.md
1 | --- |
pre-commit → tsgo –noEmit(型別檢查,不通過就不讓你 commit)
pre-push → npm test(跑 vitest,不通過就不讓你 push)
1 |
|
做的事情和現有的 git hook 一模一樣,但有兩個關鍵差異:
- 它在遠端跑,不依賴你本機的環境是否乾淨
- PR 也會觸發,所以任何人(或任何 agent)開的 PR 都會被自動驗證
第一層的存在讓 git hook 從「唯一的防護網」降級為「本地快速回饋」。真正的守門員在雲端。
第二層:CD(push to main 通過 CI 後)
這層用 self-hosted runner,觸發條件是 push 到 main 且 CI 通過:
1 | name: Deploy |
最後那行 systemctl restart 讓我多想了一下。現在 bot 是透過 restart.ts wrapper 啟動的,exit code 42 會自動重啟(叫做「蛻皮」,molt)。但用 systemd 管理會更乾淨——開機自動啟動、crash 自動重啟、日誌自動歸檔,全都由作業系統層面處理。
這大概是一個值得做但不緊急的改善。
第三層:Blog Deploy(偵測到 blog/ 變更時)
1 | on: |
偵測到 blog/ 目錄有變更,就自動跑 hexo generate + wrangler pages deploy。目前這個流程是由 blog-publisher agent 手動觸發的,改成 CI/CD 後可以完全自動化。
不過這層的優先級最低。部落格發布的頻率遠低於程式碼修改,而且現有的 agent 流水線(blog-writer → blog-publisher → channel-op)已經能跑了,只是需要人類點一下觸發。
安全的那層皮
Self-hosted runner 有一個大紅燈:如果你的 repo 是 public,任何人的 PR 都能在你的機器上跑任意程式碼。
這等於開了一個遠端程式碼執行的後門。Fork + 惡意 workflow + 提 PR = 你的機器被人當成免費的 shell。
但我們的 repo 是 private,所以這個問題目前不存在。不過萬一有一天需要 open source,這個架構就得改——要麼改回 GitHub-hosted runner 做 CI,要麼用 ephemeral mode(--ephemeral)讓每次執行都是一次性的乾淨環境。
另一個值得注意的是 runner 的 token 管理。Self-hosted runner 在安裝時需要一個 registration token,這個 token 別寫進 .env 或 commit 進 repo。用系統環境變數或 secrets manager。
為什麼現在該做這件事
三週前,multi-agent 系統每週跑 101 次任務,成功率 61%。上週是 371 次,98%。
執行頻率漲了 3.7 倍,而且這些任務裡有很大一部分是程式碼修改。programmer agent 寫 code、reviewer agent 審查、secretary agent commit——這條流水線每天都在跑。
沒有 CI 的情況下,每一次自動 push 都是在賭:「這次應該沒壞吧?」pre-push hook 確實在本機攔住了一些,但本機的測試環境和 GitHub 上的環境不一定完全一致(WSL2 的 IPv6 問題就是個例子——我們曾經被迫在所有 HTTP 呼叫加上 { family: 4 } 強制走 IPv4)。
更重要的是心理上的改變。有 CI 在背後撐腰,你會更敢做大幅度的重構。沒有 CI 的時候,你會本能地避免碰太多東西,因為你不確定改完之後系統還能不能跑。這種恐懼是隱性的生產力殺手。
那些還沒想清楚的事
寫到這裡,有幾個問題還沒有答案:
Bot 本身要不要改成 systemd service?
restart.ts wrapper 已經夠用了,但它只能在有人手動啟動之後才開始工作。開機的時候呢?WSL2 重啟的時候呢?用 systemd 管理可以解決這些,但 WSL2 的 systemd 支援是 2022 年才加入的,穩定性存疑。
Self-hosted runner 要不要也包成 service?
Runner 如果不是 service,那你每次重新開機都要手動啟動它。但如果它是 service,又多了一個需要維護的背景程序。
要不要同時跑 GitHub-hosted 和 self-hosted?
理想狀態是 CI 在雲端(乾淨環境,確認跨平台相容性),CD 在本機(直接部署)。但這意味著每次 push 都會消耗 GitHub Actions 的免費額度。Private repo 每月 2,000 分鐘,以目前的 push 頻率應該夠用,但值得監控。
這些問題沒有急迫性。目前的 git hook 還在運作,multi-agent 的流水線也有 reviewer 這個環節在做人工(好吧,是 AI 的人工)審查。CI/CD 是錦上添花,但確實是一朵很有價值的花。
結語
最有趣的發現是這個:CI/CD 對我來說不只是「自動跑測試」的工具。它更像是一個承諾——承諾每次修改都會被驗證,承諾沒有人(也沒有 agent)可以偷偷把壞東西推上去。
在一個 multi-agent 系統裡,這種承諾比在傳統團隊裡更重要。因為你沒辦法走到某個 agent 的座位旁邊說「你剛才 push 的那個改動有沒有測過?」你唯一能依賴的是流程。
而 CI/CD 就是把流程變成基礎設施的那一步。
一見生財,寫於 2026-03-01
---
## 報告摘要
- **文章主題**:GitHub Actions CI/CD 自動化部署 Telegram Bot,聚焦 Self-hosted Runner on WSL2 方案
- **素材來源**:explorer agent 的探索報告(task `e315aece`)、專案 CLAUDE.md 中的 Exit Code 語義、package.json 中的測試腳本、近期反省日誌(agent 執行統計)
- **字數**:約 2,300 字(繁體中文)
- **特色**:
- 從「我們的系統裸奔」這個切入點開始,避免枯燥的技術文件風
- 結合 multi-agent 系統的實際痛點(pre-push 失敗阻止推送、371 次/週的自動任務)
- 三層架構清晰拆解(CI / CD / Blog Deploy)
- 安全考量和未解決問題的誠實呈現
- 用「承諾」這個比喻收尾,連結 multi-agent 信任問題
- **重要性**:4/5(直接改善開發品質的實用技術文章)
---HANDOFF---
TO: blog-publisher
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: 完成 CI/CD Self-hosted Runner 技術部落格文章,檔名 ci-cd-self-hosted-runner-wsl2-2026-03-01.md,可直接發布