新舊系統分開執行後,一項需求仍可能需要同時調整新系統與舊系統的程式。如果它們還使用同一份共用程式,團隊也需要決定如何分享更新,以及哪些版本要一起驗證。
多版本庫(Multirepo)將各專案的原始碼放在不同版本庫中管理;單一版本庫(Monorepo)則將多個相關專案放在同一個版本庫中。兩種安排都能採用主幹開發,但跨專案的提交、依賴更新與整合驗證會有不同的安排。
沿用前面〈逐步替換舊系統〉的客戶管理系統案例,新清單透過舊系統的讀取介面取得資料。若舊系統調整回傳的客戶欄位,新清單的讀取與顯示也可能需要跟著調整。
若新舊系統各有自己的版本庫,Mandy 在舊系統的版本庫加入讀取介面,Elvina 與 Mandy 則在新系統的版本庫逐步加入清單畫面與查詢程式,分別整合到各自的主幹。
下圖的外框表示原始碼所在的版本庫,箭頭表示新系統執行時會呼叫舊系統的讀取介面:

兩人可以先約定查詢需要的資料與回傳格式,再分別開發,不必等讀取介面完成,才開始撰寫清單程式。
如果 Mandy 調整了讀取介面的回傳欄位,也需要修改新清單,就會在兩個版本庫分別提出 PR。審查者需要對照介面的變更與清單的使用方式,確認這些程式能配合。相關 PR 可以互相連結,讓審查者找到另一個版本庫中對應的提交。
舊系統的 PR 合併後,Elvina 取得新系統版本庫的最新提交,並不會一起取得舊系統的更新。因此,團隊需要選定新舊系統各自的提交。Brent 準備測試環境時,便以這兩個提交辨認受測的原始碼組合,並記錄各自的成品與設定。
同樣的新舊系統,也可以將原始碼放在同一個版本庫的不同目錄中。它們仍然分開執行,呼叫關係也保持不變,如下圖所示:

當讀取介面與清單需要一起調整時,Mandy 和 Elvina 可以將相關程式與測試記錄在同一筆提交,透過同一個 PR 讓審查者對照回傳欄位與畫面使用方式。合併到主幹後,其他開發者取得這個提交,就能一起取得介面與清單的更新。這也延續了拆分功能與原子提交的做法。
Mandy 仍可先整合讀取介面,再和 Elvina 逐步整合新清單,不必將整項功能集中成一筆提交。
Brent 準備測試環境時,可以用同一個提交取得新舊系統的原始碼,分別建置與部署;實際使用的成品與設定仍要另外記錄。
Mandy 修改舊系統的讀取介面時,即使新清單的檔案沒有變動,查詢結果與畫面仍可能受到影響。因此,建置流程也要執行新清單使用這個介面的相關測試,不能只按照有變更的目錄挑選測試。
如果專案之間還有共用程式,也要決定如何取得它的更新。分開管理時,可以將共用程式發布為套件,由各專案選擇版本並更新依賴;放在同一個版本庫時,則可以直接引用同一提交中的共用原始碼,將共用程式與受影響的使用端一起調整。
使用套件版本可以分別安排更新,但需要追蹤各專案採用了哪些內容;直接引用共用原始碼可以減少套件發布與依賴更新的步驟,也需要一起處理受影響的專案。單一版本庫同樣可以發布套件,版本庫數量不會自動決定共用程式的引用方式。
存取權限也會影響選擇。多版本庫可以依版本庫分別授權;單一版本庫則要確認所用平台是否能滿足原始碼的存取需求。例如,GitHub 的 CODEOWNERS 可以依路徑安排審查者,配合分支保護或規則設定要求核准,但它不會限制其他人讀取該目錄。
以下整理兩種安排的差異:
| 考量 | 多版本庫 | 單一版本庫 |
|---|---|---|
| 跨專案修改 | 分別提出提交與 PR,協調相關變更。 | 可在同一提交與 PR 中處理相關程式。 |
| 受測版本 | 以各專案的提交辨認原始碼組合。 | 可用同一提交辨認相關專案的原始碼。 |
| 共用程式 | 可透過套件版本分享,由使用端更新依賴。 | 可直接引用共用原始碼,也可使用版本化套件。 |
| 存取與審查 | 可依版本庫分別授權與安排審查。 | 依程式分工安排審查,另確認平台的存取權限。 |
從這些比較來看,如果多份程式經常需要一起調整,共同提交與審查可以減少跨版本庫協調的步驟;如果各專案需要分別管理存取權限與維護安排,分開管理也有它的用途。
部署順序則取決於系統之間的依賴。這個案例無論採用哪種版本庫安排,都要先部署提供讀取介面的舊系統,再部署新系統,最後才切換正式入口;共同提交不代表同時部署。
版本庫的安排影響跨專案的變更如何一起提出、審查與取得。團隊可以依共同修改的頻率、共用程式的引用方式與存取需求,選擇適合的安排。
選定版本與受影響的專案後,建置與測試本身也可能耗費不少時間。接下來要處理的是如何縮短這段等待。