Backport Builder 是一個發行工程(release-engineering)專案。它會將來源儲存庫視為輸入、產生的目錄樹視為輸出,並將自訂 Rector 規則視為經過測試的建置邏輯。
在維護降版規則、產生套件的中繼資料、目標執行階段檢查,或與 nextpdf/backport-builder 相關的發行自動化時,請參考本指南。
| 層級 | 負責者 | 職責 | 不應放在這裡的內容 |
|---|
| 來源儲存庫 | 產品儲存庫 | 權威的 PHP 原始碼與測試。 | 產生的降版修改。 |
| 建置指令稿 | nextpdf/backport-builder | 合併來源、執行轉換、寫入中繼資料,並驗證輸出。 | 執行階段的應用程式邏輯。 |
| Rector 設定 | nextpdf/backport-builder | 目標專屬的降版策略。 | 未經測試的跨目標假設。 |
| 自訂 Rector 規則 | nextpdf/backport-builder | 專案專屬的語法轉換。 | 未經測試的大範圍改寫。 |
| 產生的套件 | 建置輸出 | 可安裝於較舊執行階段的產物。 | 將它當成真實來源(source of truth)的手動修補。 |
| 階段 | 行為 | 開發者動作 |
|---|
| 簽出來源 | 發行工作流程會依目標標籤簽出來源儲存庫。 | 保持各套件間的來源參考一致。 |
| 契約驗證 | ValidateBuildContract::run() 會檢查建置假設。 | 將契約驗證失敗視為發行阻擋條件。 |
| 合併 | MergeSources::run() 會組裝目標套件的目錄樹。 | 先確認目標範圍,再執行 Rector。 |
| 轉換 | Rector 設定與自訂規則會將語法降版。 | 每一次規則變更都要補上 fixture 測試。 |
| Composer 調整 | AdjustComposer 會寫出產生套件的中繼資料與 replace 對應表。 | 驗證套件名稱、版本、授權與相依限制。 |
| 執行階段驗證 | 產生的輸出會在目標 PHP 版本上進行語法檢查與測試。 | 將目標執行階段失敗視為發行阻擋條件。 |
| 發行 | 壓縮檔會附加至發行項目。 | 不要將產生的輸出當成真實來源來修補。 |
| 工作項目 | 真實來源(source of truth) | 產生輸出的處理策略 |
|---|
| PHP 功能使用 | 主要來源儲存庫。 | 由 backport 規則調整該功能。 |
| 相依限制 | 來源端的 composer.json 中繼資料與調整指令稿。 | 產生的 composer.json 必須可重現。 |
| 語法降版 | Rector 設定與自訂規則。 | 產生的原始碼不應手動編輯。 |
| 執行階段支援 | 目標分支與 CI 矩陣。 | 建置必須在目標 PHP 上通過。 |
| 發行說明 | 文件與發行自動化。 | 產生的產物應能追溯到來源版本。 |
每個自訂規則都應有明確且範圍狹窄的用途、中繼資料與 fixture 覆蓋。
| 規則方法 | 用途 | 品質要求 |
|---|
getRuleDefinition() | 為 Rector 工具描述這項轉換。 | 提供一組與真實降版相符的 before/after 範例。 |
getNodeTypes() | 限制這項規則會檢查的 AST 節點。 | 讓節點清單盡可能精簡。 |
refactor() | 套用該轉換,或維持原樣回傳。 | 讓無關節點保持不變,且結果具決定性。 |
| fixture 測試 | 驗證 before/after 輸出。 | 涵蓋最小的有效輸入,以及至少一個略過(skip)的情況。 |
final class ExampleDowngradeRector extends AbstractRector
public function getNodeTypes(): array
return [SomeNode::class];
public function refactor(Node $node): ?Node
if (!$node instanceof SomeNode) {
return $this->rewriteNode($node);
開發期間與驗證發行候選版本時,請使用 dry run。只有在來源參考與目標分支都已確認時,才產生實際輸出。
php scripts/build.php --version=2.0.0 --target=php81 --dry-run
php scripts/build.php --version=2.0.0 --target=php74 --no-pro
產生套件的驗證應在目標執行階段上執行,不應只在現代化建置主機上執行。
| 擴充點 | 用途 | 限制條件 |
|---|
| Rector 設定檔 | 目標專屬的降版策略。 | 讓 PHP 8.1 與 PHP 7.4 的軌道彼此分離。 |
| 自訂 Rector 規則 | 專案專屬的語法轉換。 | 必須具備中繼資料與 fixture 測試。 |
| Composer 調整指令稿 | 產生套件的識別資訊。 | 必須維持與 SemVer 一致的版本編號。 |
| 合併指令稿 | 選取並整理來源套件的輸入。 | 必須記錄來源根目錄與輸出根目錄。 |
| 建置工作流程 | 協調發行作業。 | 必須在目標執行階段上驗證產生的輸出。 |
- 在最小的 fixture 中重現不受支援的語法。
- 新增或更新自訂 Rector 規則。
- 為該規則加上 before/after fixture。
- 執行 dry build。
- 在目標 PHP 執行階段上驗證產生的輸出。
- 必要時,將同一項邏輯變更套用到每個常駐目標分支。
- 確保發行產物可透過來源標籤與建置指令稿重現。
| 失敗情況 | 應在何處處理 | 建議的回應方式 |
|---|
| 缺少來源儲存庫 | 契約驗證或合併階段。 | 停止建置並修正簽出輸入。 |
| Rector 剖析失敗 | 轉換階段。 | 縮小為單一 fixture,並更新規則或設定。 |
產生的 composer.json 不一致 | Composer 調整階段。 | 修正產生用指令稿,而不是產生的中繼資料。 |
| 目標語法失敗 | 執行階段驗證。 | 在轉換修正完成前阻擋發行。 |
| 無法取得 Pro 來源 | 建置設定。 | 只有在公開版本確實是預期目標時,才建置公開產物。 |
| 關注項目 | 預設值 | 何時該覆寫 |
|---|
| 產生的輸出 | 唯讀產物。 | 永遠不要將它當成真實來源。 |
| 分支模型 | 各自獨立、常駐的目標分支。 | 以各自獨立的拉取請求(pull request)讓變更保持同步。 |
| 建置主機 | 現代 PHP。 | 目標執行階段驗證仍是決定能否發行的依據。 |
| 自訂規則 | 規模小,並有 fixture 支撐。 | 避免沒有明確 before/after 範例的大範圍轉換。 |
| PHP 7.4 軌道 | 除非明確支援,否則僅限 core。 | 未經目標執行階段驗證,不要納入 Pro 輸出。 |
- Rector 規則中繼資料測試會實例化每個自訂規則。
- fixture 測試會涵蓋每項轉換的前後(before/after)程式碼。
- 發行作業前會先執行 dry build。
- 目標執行階段的語法檢查與套件測試會針對產生的輸出執行。
- Composer 中繼資料測試會斷言套件名稱、版本、相依限制、replace 對應表與授權。
- 建置記錄包含來源路徑、目標路徑、目標執行階段、dry-run 狀態,以及 Pro 納入狀態。