首頁 / 部落格 / Swift Package Ma
ENGINEERING_BLOG · 2026.09.13

Swift Package Manager 私有依賴拉取失敗?2026 企業 CI 修復

Apple 的 CI 建置文件 明確把 Package.resolved 與自動依賴解析視為可控制的建置行為。你的本週動作不應是先刪除快取或開放共享金鑰,而是依時間表完成三件事:先固定並驗證依賴圖,再用實際 CI 服務帳號測試 SSH,最後才處理快取與節點替換。私有依賴解析節點也應與生產簽名節點分離;共享遠端 Mac 只有在帳號、憑證和工作區都隔離後才適合使用。

這篇文章適合三類人:維護含私有 Swift Package、目前遇到 CI 拉取失敗的研發負責人;管理 Jenkins、GitHub Actions、GitLab 或其他自託管 Mac Agent 的平台工程團隊;以及需要審查程式碼憑證、Apple 簽名資產和遠端 Mac 隔離能力的安全與 IT 負責人。

SECTION 01 先按時間表劃定故障邊界

里程碑一:先判斷失敗位於哪一層

「開發者本機可以拉取、CI 卻失敗」通常不是單一網路問題,而是執行身份不同。請把同一次建置拆成四個觀察階段,分別保存原始輸出:

  • 依賴解析:確認 Package.swiftPackage.resolved 和目前提交是否一致。
  • Git 連線:確認實際服務帳號能否連至私有倉庫,以及主機指紋是否已被信任。
  • 二進位依賴下載:若依賴包含 binary target,必須另外核對其下載端點與授權。
  • 編譯:解析和下載已成功後,才檢查 Xcode、SDK 或原始碼編譯錯誤。

Apple 對 Package.Dependency 的官方說明可用來核對依賴是以 Git URL、版本、分支或本地路徑宣告;不要只查看頂層套件,還要盤點傳遞依賴實際引用的所有端點。Apple 的 Package.Dependency 文件 是責任交接時應附上的依據。

平台團隊應在故障紀錄中固定保存四項資料:重現命令、執行帳號、失敗端點和退出狀態。若只貼一段「authentication failed」,應退回給提交者補證據,而不是直接要求清空整個工作區。

里程碑二:建立最小重現

在乾淨工作區以同一提交執行最小解析任務,例如:

xcodebuild -resolvePackageDependencies \
  -workspace App.xcworkspace \
  -scheme App
echo $?

實際工作區和 Scheme 名稱必須以你的專案為準。這個步驟的目的不是完成完整建置,而是把「解析失敗」與「編譯失敗」分開。若服務帳號在此處已失敗,先不要碰簽名設定;若解析成功、編譯才失敗,則應把交接對象轉給應用團隊。

SECTION 02 為什麼本機可拉取、CI 卻失敗?

應用團隊:先固定 Package.resolved

企業 CI 是否應提交 Package.resolved,答案取決於你要的是可重現的生產建置,還是主動更新依賴的維護工作流。對生產 CI,應確認該檔案位於實際 App 專案或工作區所使用的正確路徑,並已進入版本控制;Apple 的 Swift Package CI 建置說明 支援這個控制方向。

請讓程式碼審查明確區分兩種工作流:

  • 依賴更新工作流:允許開發者或自動化任務更新解析結果,審查變更後才合併。
  • 生產建置工作流:使用提交內既有的解析結果,避免無人值守建置在不同時間得到不同依賴版本。

Package.resolved 不在版本控制,或其位置與實際建置入口不一致,CI 可能重新解析依賴。Swift Package Manager 對解析版本的說明指出,解析結果會受套件需求與既有解析資料影響;因此應先確認版本鎖定,再討論快取。官方版本解析文件 可作為審查依據。

元件負責人:收斂所有倉庫與授權範圍

私有元件負責人需要列出直接依賴、傳遞依賴及二進位 Target 的實際存取端點。只檢查頂層私有倉庫,會漏掉子依賴改名、URL 重寫、鏡像或另一個信任域造成的身份錯配。

建議逐項核對:

  • Package.swift 中的 URL 是否與現行倉庫地址一致。
  • 倉庫重命名後,SSH URL、HTTPS URL 和鏡像設定是否仍指向同一信任域。
  • CI 是否將多個 Git 主機錯誤地映射到同一個金鑰。
  • 服務帳號是否只具備所需倉庫的唯讀權限。
  • 金鑰建立、輪換和撤銷是否都有記錄。

若團隊採用套件註冊表而非 Git 來源,應另外確認註冊表憑證和套件識別方式;不要把 Git 的 SSH 測試結果當成註冊表授權已成功。Swift Package Manager 的 Registry 使用文件 說明了另一種依賴取得路徑。

SECTION 03 xcodebuild 如何在實際服務帳號下使用 SSH?

CI 平台團隊:重建完整 SSH 上下文

xcodebuild 應在真正執行建置的 macOS 帳號下測試。管理員在互動式 Terminal 成功,不代表 Jenkins、GitHub Actions、GitLab Runner 或其他 Agent 的服務帳號也能成功。至少要核對:

  • HOME 是否指向服務帳號的家目錄。
  • ~/.ssh/configknown_hosts 是否位於該帳號可讀取的位置。
  • 私鑰檔案權限是否符合企業安全政策。
  • ssh-agent 是否真的在無人值守工作中提供金鑰。
  • 系統 Git 設定、代理或 URL 映射是否只存在於管理員環境。
  • SCM Provider 是否與你的實際 Git 來源一致,而不是假設 CI 會繼承互動式設定。

可先使用以下命令查看 SSH 將採用的有效設定,再進行最小連線測試:

id
printf '%s\n' "$HOME"
ssh -G git@your-git-host.example
ssh -T git@your-git-host.example
echo $?

請把主機名稱、使用者和命令輸出納入受控故障紀錄,不要把私鑰內容或完整秘密環境變數貼入工單。Apple 的 CI 文件同樣把實際 CI 使用者的 SSH 設定列為私有套件存取的一部分,而不是把它視為開發者本機設定的自然延伸。

修復後的驗收順序

修復後不要只重跑原本失敗的完整工作。依下列順序執行,並在每一階段保存證據:

  • 以服務帳號執行依賴解析,確認 Package.resolved 沒有被非預期修改。
  • 在同一工作區執行最小編譯,確認解析成功後沒有新的來源或二進位下載問題。
  • 重啟 Mac Agent 或重新建立服務程序,再重做解析測試。
  • 以乾淨工作區重做一次,排除原節點殘留的 Git 或 SPM 快取。
  • 將成功條件、執行身份、工作區清理方式和失敗回退方法交給下一個責任團隊。

SECTION 04 快取應保留還是每次清理?

快取不是憑證修復工具,也不是依賴版本鎖定的替代品。若解析階段在乾淨工作區仍因 SSH 授權失敗,清理快取只會增加診斷雜訊;若解析和授權已通過、問題只在疑似損壞的下載內容,才應針對該工作區或該依賴做受控清理。

注意:不要把「清理後成功」直接解讀為根因已消失。你必須在沒有長期節點殘留狀態的環境中重做解析、最小編譯和重啟復測,否則下一次換機仍可能失敗。

平台工程團隊應把快取政策寫成可審查的規則:生產建置使用固定解析結果;快取可作為效能最佳化,但不能提供跨專案共享的私有憑證;故障排查要能指定清理範圍、記錄執行者,並保留清理前後的解析輸出。對套件來源、版本需求和解析行為的定義,可再參照 Swift Package Manager 的依賴加入文件

SECTION 05 憑證、簽名與共享遠端 Mac 的隔離條件

安全與發布團隊必須把私有原始碼讀取憑證、Apple 簽名私鑰、發布 API 憑證和共享管理員帳號拆開。非可信分支、外部貢獻程式碼或一般 Pull Request 任務,不應同時取得生產私有依賴和正式簽名節點的完整權限。

可採取以下邊界:

  • 依賴解析使用獨立服務帳號與唯讀 SSH 身份。
  • 生產簽名使用不同節點、不同帳號及臨時 Keychain。
  • 工作結束後清理工作區、代理程序和短期憑證。
  • 依倉庫或信任域分配金鑰,不讓所有私有倉庫共用同一身份。
  • 保留建立、注入、輪換、撤銷和任務結束清理的審計記錄。

決策條件:修復現有節點,還是拆分資源池?

  • 同一 Mac 能以不同服務帳號分隔依賴讀取、正式簽名和工作區,可先修復現有節點,並以重啟後的乾淨工作區驗收。
  • 共享節點無法限制非可信分支讀取私有依賴,回退到獨立的依賴解析節點。
  • 正式簽名私鑰必須長時間留在同一個共享帳號,不要把該節點當作一般團隊 CI Agent,應拆出專用簽名資源池。
  • 每次換機都需要手動複製 SSH 設定或 Keychain,先修正節點交付流程,再擴大容量。
  • 只有固定專案、固定服務帳號和受控分支能使用該環境,可評估共享遠端 Mac;否則應選擇具備帳號、憑證與工作區隔離的配置。

這個條件清單也適用於你評估遠端 Mac 的企業方案:先用安全邊界判斷是否適合租用,再比較容量,而不是先以節點數量決定架構。

SECTION 06 交付驗收與團隊交接

基礎設施負責人應在全新或重新交付的遠端 Mac 上重現依賴解析與首次建置,並分別記錄長期節點、臨時節點和專用簽名節點的交付證據。驗收內容至少包括:

  • 實際服務帳號是否與文件一致。
  • HOME、SSH 設定、主機指紋和工作區路徑是否可重建。
  • 憑證注入是否限定在指定任務,任務結束後是否清理。
  • 重啟後服務是否仍能在無互動狀態完成解析。
  • 節點替換後,沒有依賴舊快取也能完成最小建置。
  • 失敗時是否能撤銷該身份,而不牽連生產簽名資產。

如果你要把這些項目交給 IT 或採購團隊,可先參考VPSNIX 的支援與服務說明,再把自己的服務帳號、倉庫授權和驗收紀錄附在內部採購文件中。這比只寫「需要一台 Mac 打包機」更能驗證交付品質。

當前直接維護一台共享 Mac,常見缺點是服務帳號容易被管理員環境污染、私有依賴憑證可能與簽名資產混放,而且節點更換後常因殘留快取或手動設定失效。若你選擇按需租用 VPSNIX 的遠端 Mac,可先以隔離節點完成乾淨解析、重啟恢復和換機復測,再決定是否擴大到正式 CI;這種方式特別適合短期試點、臨時容量或現有共享節點無法建立權限邊界的團隊,但長期固定重負載、必須接入專用實體周邊或受內部機房政策限制時,自購硬體仍可能更合適。

本週建議動作:先提交並校驗 Package.resolved,在實際 CI 服務帳號下完成 SSH 最小重現,禁止共享私有金鑰;完成後再用一台隔離的遠端 Mac 做乾淨環境驗收,將結果交給平台、安全與基礎設施團隊共同簽核。

延伸閱讀