iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0
Vibe Coding

讓 AI Agent 維護一個 Open Source Project系列 第 2

Day 02:專案背景——一個 VS Code 測試擴充套件,維護者的日常長什麼樣

  • 分享至 

  • xImage
  •  

前言:「不就是一個小外掛嗎,能有多少維護工作?」

昨天介紹完 vscode-phpunit 這個專案,我猜有讀者心裡冒出這個疑問:一個讓 PHPUnit/Pest 測試在 VS Code 裡跑起來的擴充套件,功能聽起來單純——找到測試、執行、把結果畫回 Test Explorer,這能有多複雜?

答案是:複雜的從來不是「功能」本身,而是這個功能要在多少種環境組合下都成立。同一段「執行測試、回報結果」的邏輯,遇到本機執行是一種寫法,遇到 Docker 容器是另一種路徑映射問題,遇到 SSH 遠端主機又是一種,遇到 Laravel Sail 包一層 sail artisan test 又是一種。使用者的專案結構、PHP 版本、PHPUnit 版本、Pest 版本、VS Code 版本、作業系統,任何一個維度變了,原本沒事的邏輯都可能壞掉。

今天要具體拆這個「相容性矩陣」對維護者意味著什麼,以及維護者每天實際在處理的工作,哪些看起來瑣碎、哪些其實需要判斷力。

今日目標

  • 理解「相容性矩陣很大」這句話對一個 OSS 專案維護者具體是什麼負擔
  • 用這個專案真實的 open issue,看同一類 bug 怎麼在不同環境組合下反覆出現
  • 拆解維護者每天實際要處理的四類工作:bug 回報、功能請求、PR 審查、CI 維護
  • 建立一個判斷框架:這些日常工作裡,哪些部分機械性夠高、適合先讓 AI 介入

相容性矩陣:這個專案要同時裝下幾個維度

vscode-phpunit 要同時處理的變數,粗略列出來就有這幾層:

  • 測試框架:PHPUnit、Pest(Pest 又分 v3、v4,語法跟事件輸出格式不完全一樣)
  • 執行環境:本機直接跑、Docker(docker compose exec)、SSH 遠端、Laravel Sail(sail artisan test 包了一層 Sail 自己的路徑映射)
  • 測試方式:一般同步執行、ParaTest 平行執行、Pest 內建的 --parallel
  • 除錯:Xdebug step-debugging 要能接上,而且要在上面每一種環境組合下都要能接上
  • VS Code 原生 API:所有結果最終都要回填進 VS Code 的 Test Explorer API,這層 API 本身也會隨版本演進

單獨看每一個維度都不難處理,難的是這些維度會兩兩甚至三三組合出現。「Pest + Docker + --parallel」是一種組合、「PHPUnit + SSH + Xdebug」是另一種組合、「Pest v4 + Laravel Sail + dataset」又是一種。維護者沒辦法窮舉所有組合去手動測,大部分時候是等使用者在某個特定組合下踩到 bug,才知道這個交集原來有問題。

這不是空談,這個專案現在(2026-08-30 這幾天)掛著的 open issue 剛好可以拿來當活教材。

案例:同一類 bug 在特定環境組合下反覆出現

先看 #416「Failed to run docker compose command」。回報者的執行環境是 Docker + frankenphp + Symfony,phpunit.command 設定裡用 docker compose -f docker-compose-test.yml up -d php-e2e 先把容器啟起來,再用 exec 執行測試。結果套件在組指令時把 -f 這個 flag 位置解析錯了,噴出 unknown shorthand flag: 'f' in -f

再看 #417「Impossible to run individual test」。同一位回報者、同一組 Docker 設定,這次踩到的是另一個問題:套件在 Docker 環境下「執行單一測試」(右鍵 Run test)時,沒有把測試檔案的路徑做容器內外的映射轉換,導致送進容器的是宿主機的絕對路徑,容器裡當然找不到這個檔案。回報者甚至在 #417 的內容裡直接留言註記「這裡先繞開,等 #416 修好」——兩個 issue 是同一個人、同一個 Docker 專案結構,卡在同一層「路徑到底該用宿主機視角還是容器視角」的問題上,只是分別在「啟動指令」跟「單一測試路徑映射」這兩個不同的程式碼路徑上各爆一次。

再看 #415「Not evaluating test results when running pest in parallel」。這是 Pest v4 + Laravel Sail + --parallel 的組合:使用者一加上 --parallel 這個參數,測試結果就全部被標成 skipped,而拿掉 --parallel 就一切正常。有意思的是,回報者自己在 issue 內文就先做了功課,寫了「這個看起來跟 #402、#408 有關」——這兩個是更早之前、關於 Pest dataset 測試結果解析的 issue。換句話說,「Pest 特有的輸出格式在某些執行模式下解析不完整」這個問題根源,已經不是第一次冒出來,只是這次換了一個新的觸發組合(--parallel)。

這三個 issue 放在一起看,會發現一個維護者每天真實面對的模式:bug 很少是全新的邏輯錯誤,更常是「某個既有邏輯,換一種環境組合排列,原本沒被考慮到的分支被踩到了」。這正是相容性矩陣龐大的專案特有的負擔——不是修一次就永遠修好,而是同一類根因會用不同的排列組合反覆回來敲門。

維護者的日常:四類工作,四種不同的判斷成本

把最近的 issue 跟 PR 攤開來看,維護者的日常大致落在四類工作,但每一類需要的判斷力差很多。

第一類,bug 回報。像上面 #416、#417、#415 這樣,使用者附上環境設定、錯誤訊息、重現步驟。維護者要做的第一步往往不是馬上動手修,而是先判斷這是不是已知問題的新變種(像 #415 那樣要意識到跟 #402、#408 是同一個根因家族),還是真的獨立的新 bug。這一步判斷做錯,後面的修法方向就會偏。

第二類,功能請求。例如 PR #428「Pest todo() assignee/issue and skipOnCi()/skipLocally() detection」,這是把 Pest 較新版本才有的測試狀態語法(todo() 附加 assignee/issue、條件式跳過)接進套件既有的狀態判讀邏輯。這類工作的判斷成本在於:要跟著上游框架(Pest)的版本演進調整,但不能為了追新語法而破壞舊版本的相容性——這個套件同時要服務還在用 Pest v3 的使用者跟已經升到 v4 的使用者。

第三類,PR 審查。這個專案有不少外部貢獻者送 PR,例如 #413、#412、#411 都是圍繞 workspaceFolder 路徑解析一致性的修正,由外部貢獻者陸續送出(其中兩份出自同一位貢獻者,另一份來自另一位)。審查這類 PR 要判斷的不只是「這段程式碼有沒有語法錯誤」,而是這個修法會不會在某個貢獻者沒測過的環境組合下引入新的回歸——正是因為前面提到的相容性矩陣太大,外部貢獻者往往只驗證了自己遇到問題的那一種組合,維護者要腦補「這個改動會不會影響到 Docker?SSH?Sail?」。

第四類,CI 維護。例如 PR #424「fold e2e tests into the tests.yml matrix instead of a separate workflow」跟 #423「use short --user-data-dir to avoid macOS AF_UNIX socket path limit in e2e」。後者是一個很典型的「CI 環境雜訊」案例——e2e 測試在 macOS runner 上失敗,根因不是程式邏輯錯,是 macOS 對 Unix domain socket 路徑長度有限制,VS Code 測試用的臨時 --user-data-dir 路徑太長就會爆掉。這類問題的判斷成本在於要先分辨「這是我的程式碼壞了」還是「這是這台 CI runner 本身的環境限制」,方向抓錯,會浪費大量時間在錯的地方找 bug。

❌ 把「相容性矩陣大」直接丟給 AI 全權處理

維護者角色:把 #416、#417、#415 三個 issue 都丟給 AI,
下一句指令是「幫我全部修好」。

AI 的處理方式:
- 各自獨立修,沒有意識到 #416 跟 #417
  是同一組 Docker 路徑問題的兩個切面
- 為了讓 #415 的測試通過,加了一個
  只在「有 --parallel」時生效的特殊分支,
  沒有回頭檢查 #402、#408 的根因是否被一併處理
- 結果:三個 issue 表面上都關閉了,
  但 Docker 路徑映射的邏輯变成兩套互不相干的實作,
  Pest 平行執行的解析邏輯多了一層局部補丁,
  技術債比修之前更重

✅ AI 先做關聯分析,人來判斷根因與修法方向

維護者角色:先讓 AI 針對這批 open issue 做關聯分析——
「找出這幾個 issue 裡,哪些回報者/環境設定/
程式碼路徑有重疊,列出可能同根因的分組」。

AI 產出:
- #416、#417 同一位回報者、同一份 Docker 設定,
  都卡在「路徑該用宿主機視角還是容器視角」,
  建議合併看,先修路徑映射這一層共用邏輯
- #415 內文已經自己連結 #402、#408,
  建議一併回顧這三個 issue 涉及的
  Pest 輸出格式解析程式碼是否同一段

維護者角色:確認 AI 的分組合理後,
自己決定修法要往「補一個路徑轉換函式」
還是「重構整個路徑映射層」的方向走——
這個技術方向的判斷,AI 不做決定,人來拍板。

AI 適合做的是「把散落的線索攤開、標出可能的關聯」,真正決定要往哪個方向修、值不值得為此重構一整層邏輯,還是人的工作。 這也是為什麼「相容性矩陣很大」對維護者是負擔而不只是工作量——負擔的核心不是「事情很多」,是「每一件事都可能跟另一件事共享一個看不見的根因,漏看這層關聯,修了等於白修」。

今日思考題

如果你維護過任何一個要同時支援多種執行環境的專案(不限 VS Code 擴充套件,CLI 工具、SDK、CI plugin 都算),回想一下:你手上是不是也有幾個「表面上是不同 bug,其實同一個根因換了個環境組合又冒出來」的案例?你是怎麼發現這層關聯的——是自己看出來的,還是像 #415 那樣,靠回報者自己先做了功課?

今日重點回顧

  • 「相容性矩陣很大」對維護者的負擔,核心不是工作量大,而是同一個根因會用不同環境組合反覆出現,稍不注意就會被當成獨立 bug 各自修一次
  • 用這個專案真實的 open issue(#416、#417 的 Docker 路徑問題,#415 跟 #402、#408 的 Pest 解析問題)具體示範了這個模式
  • 維護者的日常工作分四類:bug 回報(要先判斷是不是已知問題的變種)、功能請求(要跟上游框架版本演進但不破壞舊相容性)、PR 審查(要腦補貢獻者沒測過的環境組合)、CI 維護(要分辨是程式碼壞了還是 CI 環境本身的限制)
  • AI 適合先做「關聯分析、攤開線索」,但修法方向跟技術債的取捨,仍要人拍板

明日預告

明天要具體講 Issue 分類這件事——怎麼讓 AI 先做第一輪 triage,把回報分類、標記優先序、抓出可能重複的回報,人只需要在 AI 的判斷之上做最終確認。


上一篇
Day 01:系列介紹——為什麼挑 vscode-phpunit 這個專案做實驗
系列文
讓 AI Agent 維護一個 Open Source Project2
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言