堆疊 PR (Stacked PRs)
大小預算
目標是每個 PR 約 300 行變更,上限為 500 行。 在此大小下,人類可以在快速瀏覽時掌握整個變更,而審查代理也能給出清晰、具體的發現,而非粗略略讀。
計入項目: 手寫程式碼與測試。
不計入項目: 鎖定檔、產生的程式碼(遷移腳本、程式碼生成、OpenAPI 輸出)、快照、固定檔案與供應商檔案。這些會被略讀而非仔細審閱。請在 PR 本體中列出哪些檔案是產生的,以便審查者知道要跳過。
在撰寫程式碼之前就進行分割,而非之後。 分割的決定在規劃階段(請參閱 coding-process)就已確定。如果某個規劃階段的變更數會超過 500 行,請重新規劃。常見的分割方式:
- 測試可以獨立成一個階段。 例如,邏輯搭配單元測試與整合測試,然後 UI 搭配端對端測試。
- 資料模型或資料庫 schema,接著是使用該模型的服務,然後是 API 層,最後是 UI。
- 先進行重構讓變更容易,再進行實際變更。
- 如果文件同步太大無法附帶,則在上面新增一個僅含文件的階段。
真正無法分割 的變更,例如一個連貫的遷移或跨 80 個檔案的重新命名,可以超過預算。PR 本體需說明原因,並指引審查者到真正需要仔細閱讀的部分。
原子提交仍然適用於每個 PR 內部。預算是針對每個 PR,並非取代提交的整潔性。
堆疊
多階段的任務應以 PR 堆疊 的形式運送,絕非只用一個分支承載整個規劃。每個 PR 是一個階段,目標指向 上一階段的分支,而非 main。如此一來,審查者看到的差異就只是該階段的變更,而風險較高的階段(如遷移腳本、認證變更)可以獨立審查並安全還原。
- 每個階段從前一階段的頭部分支出來。只有最底層的 PR 目標是
main:gh pr create --base <previous-stage-branch> - 在每個 PR 本體中註明其位置(
堆疊於 #123),以便打開順序錯誤的審查者知道他們在看什麼。 - 由下往上合併。 當基礎分支變更時(例如審查修正或基礎分支被合併),重新變基上層的分支並強制推送 那些分支。強制推送自己尚未合併的堆疊分支是常規操作。強制推送
main或共享分支則絕對不行。 - 堆疊中的任何 PR 合併後,在開始下一階段之前,請將其他 PR 同步到新的基礎分支上。
- 來自審查或驗證階段的修正(例如 UI 層的修正)會作為新的階段放置在頂層,這樣建置與修正可以分開審查。
- 堆疊工具如
gh stack、Graphite 或 git-town 是可選的。純 Git 搭配gh就已足夠。
循序審查
一次一個階段地審查堆疊。 僅向專案的審查者(請參閱 AGENTS.md 中的專案門檻)請求審查最底層的 PR,然後:
- 請求審查該一個階段。
- 處理所有發現(見下文)。
- 重新請求審查,並重複直到該階段 獲得核准。
- 只有這樣,才能請求審查下一個階段。
不要一次性請求審查整個堆疊。階段 1 的發現可能會使已經對階段 2 到 5 撰寫的評論失效,而循序審查可以將審查者的工作量控制在合理範圍內。
如果某個階段停滯(沒有審查回饋,或是有需要產品決策的發現),請標記該情況,並繼續在本地開發其上層階段,因為這些階段不依賴該問題的答案。
處理審查結果(任何 PR,不論是否堆疊)
- 在採取行動前,先從技術上驗證每個發現。 閱讀發現所指的程式碼,如果可能,重現問題。
- 修正它,或提出理由反駁。 審查者(無論是人類或機器人)正常情況下也可能自信地犯錯。為了顯得同意而做出糟糕的變更,比與審查者爭論更糟糕。不要有表演性的同意。
- 根據實際發生機率判斷發現。 對實際上不可能發生的場景的修正,以及增加複雜度但沒有實際好處的建議,應予以反駁。
- 不要新增無法失敗的測試。 無論 bug 是否存在都會通過的測試是雜訊。請先針對有問題的程式碼執行測試(請參閱
testing)。 - 回覆每個發現,以便審查者了解其處理結果:在哪個提交中修正了,或為何不修正。