文首判斷:先準備已簽署的發布產物
Apple 自 2023 年 11 月 1 日起,不再接受透過 altool 或 Xcode 13 及更早版本提交的公證上傳;新接入流程應以 notarytool 為基礎。Apple 的工具遷移說明 支援這項判斷。macOS 應用程式公證可以接入遠端 Mac CI:先完成 Developer ID 簽署及發布產物準備,再提交、查結果、依格式處理票據,最後驗收實際分發包。本週建議先用一條隔離的發布任務走完全程;提交獲接受,不代表終端使用者拿到的檔案已驗收。
獨立 macOS 開發者:要透過 Developer ID 向 Mac App Store 以外的渠道發行,並把手動公證改成可重現流程。
建置工程師:要釐清 Archive、匯出產物與實際發布檔案之間的輸入、輸出及追蹤關係。
DevOps 工程師:要管理簽署資產、公證憑據、CI 權限與日誌,並讓發布結果可供複核。
發行邊界:公證不是 App Review
本文討論的是 Developer ID 發行流程,不是 App Review,也不涵蓋 Mac App Store 上架。公證是發布前的檢查與票據流程,不能取代簽署、打包、下載後驗證或團隊自己的發布核准。
完整交付證據應能連起來:已簽署產物 → 公證提交紀錄 → 處理結果與日誌 → 票據處理 → 最終分發包驗收。如果 CI 只保存「提交完成」的訊息,卻無法指出送交的檔案是哪一版、最後發行的又是哪一個檔案,這條流水線還不能算完成。
提交前:固定簽署內容與產物身分
先將建置輸出分成不同階段管理。Archive 是建置與匯出流程中的來源之一;匯出後的應用程式或安裝包才可能是送交公證或製作分發包的對象;最終提供下載的檔案則要另外驗收。不要以 Archive 成功推定匯出檔或下載檔也正確。
Apple 的分發簽署說明列出 macOS 發行程式碼的相關要求;公證前要確認 Developer ID 簽署、Hardened Runtime、時間戳記,以及應用程式內嵌程式碼的簽署狀態。Apple 的 macOS 分發簽署文件與公證前檢查說明可作為核對依據。不要把其他專案的憑證名稱或設定值直接套進來;簽署選項應依實際專案、工具鏈及 Apple 文件確認。
在 CI 為每個待測產物保存追蹤資料,例如來源提交識別、建置工作紀錄、檔案雜湊、簽署檢查結果與匯出位置。帳戶、Team ID、憑證、Bundle Identifier、路徑及金鑰均以部署環境的受控值提供,不要寫死在範例或程式庫。
注意:若 Archive、匯出檔與最終下載檔沒有各自可辨識的紀錄,發生拒絕或安裝問題時,就很難確認應重跑簽署、重新提交,還是只修正分發包。
首次接入:讓 notarytool 使用受控憑據
在遠端 Mac 上先確認 CI 選用的 Xcode 或 Command Line Tools 能呼叫 notarytool,再將公證步驟加進發布工作。Apple 說明,notarytool 可用於腳本化公證工作流程;工具版本與可用選項以目前安裝環境及Apple 的自訂公證流程文件為準。
遠端 Mac CI 如何保存和使用公證憑據?先決定憑據由誰保管、如何注入,以及哪些工作有權讀取。Keychain profile 可供遠端 Mac 上的工具使用;CI 的秘密管理則負責授權範圍、注入時機與輪換。兩者是不同責任,不能因為建立了 profile,就假定 CI 秘密已妥善管理。
將帳戶資料透過受控秘密注入,避免提交到程式庫、命令列紀錄或 CI 輸出。Apple 的自訂流程文件說明如何設定憑據並搭配 notarytool 使用;實際認證參數應依該文件與團隊的憑據管理方式設定。以下命令只展示使用已設定 profile 的提交形式,不包含任何秘密:
xcrun notarytool submit "$PACKAGE_PATH" \
--keychain-profile "$NOTARY_PROFILE" \
--wait
CI 應保存工作識別與提交結果,並限制哪些人員或工作可以呼叫該步驟。不要把憑據回顯到日誌,也不要讓一般測試工作取得發布所需的秘密。
提交後:保存識別並依證據分類
notarytool 工作流程中,提交、查詢提交資訊及取得日誌,分別對應不同的操作。成功送出後,保存回傳的提交識別,供後續查詢與追查;Apple 的自訂公證工作流程及Notary API 文件說明相關操作。不要只依據 CI 結尾的一行成功訊息,就判斷最終交付已通過。
notarytool 提交成功後還要檢查哪些結果?確認處理狀態與結果;如有失敗或警告,取得該筆提交的日誌,再按實際證據定位。可以使用以下形式查詢,所有識別值均由流水線保存:
xcrun notarytool info "$SUBMISSION_ID" \
--keychain-profile "$NOTARY_PROFILE"
xcrun notarytool log "$SUBMISSION_ID" \
--keychain-profile "$NOTARY_PROFILE"
將訊息先分成簽署或 Hardened Runtime 條件、檔案或封裝格式、提交服務回應等類別,再回到對應階段檢查。Apple 的常見公證問題排查文件可協助對照錯誤證據。單一錯誤文字不能直接證明遠端節點或網路故障;應核對該次工作紀錄、實際提交檔案與服務回應。
提醒:失敗重試應保留原提交識別與日誌,再以新的建置或修正產物建立新紀錄。覆寫舊紀錄會切斷問題與修復結果的關聯。
票據處理:按實際分發格式核驗
Apple 說明公證提交、票據及分發方式時,會依交付產物與封裝方式分別處理。macOS 軟體打包文件可協助確認相應流程。不要假定每種封裝都在同一個位置處理票據,也不要把公證處理結果當成票據已附加的證明。
對支援的產物,依 Apple 文件使用 stapler 處理及核驗;例如,對已完成公證的對象執行以下命令。適用對象和格式請先按官方文件確認:
xcrun stapler staple "$NOTARIZED_ARTIFACT"
xcrun stapler validate "$NOTARIZED_ARTIFACT"
macOS 應用程式公證後怎麼驗證票據已裝訂?除了執行票據核驗,還要確認核驗對象就是準備發布的檔案;若實際交付的是壓縮檔或其他封裝,應依其內容與打包方式檢查最終下載物,而非只檢查封裝前的應用程式。
也要分開核對簽署有效性、票據可用性與使用者實際取得的分發檔。完成處理後,從最終下載物還原或安裝應用程式,再依目標情境測試啟動。Apple 的打包說明可用於確認封裝流程,但團隊仍須自行驗收實際提供的檔案。
發布驗收:用隔離任務跑完整條證據鏈
正式開啟自動發布前,先用隔離的發布任務執行一次完整流程,並確認每個階段都能回溯到同一份來源與預定交付物。以下條件分支可用來決定是否開放自動發布:
- 若簽署檢查、提交紀錄、處理結果、票據核驗及下載後測試都能關聯到預定產物,則可依團隊核准規則開放自動發布。
- 若處理結果合格,但下載物測試或紀錄鏈尚未完成,則保留人工確認,不要把提交完成視為自動放行條件。
- 若簽署或產物身分無法確認,則暫停發布,回到建置或匯出階段修正;不要靠重送同一個不明檔案來掩蓋問題。
驗收紀錄應關聯來源提交、建置工作、簽署檢查、提交識別、處理日誌及最終分發檔。把憑據輪換、失敗重試、日誌保存與復原責任寫入團隊流程;當操作人員更換或發布節點重建時,仍要能判斷下一步由誰執行。
如果目前依賴 Linux CI,限制在於它不能代替 macOS 專屬工具鏈;若只靠開發者本機 Mac,建置環境和發布紀錄也可能綁在單一工作站。若工作需要長期穩定重負載,或必須直接連接實體裝置,租用未必合適;若缺的是一個可用於驗證簽署、公證及流水線控制的 Mac 執行環境,可先用真實發布任務評估 NodeMini 的遠端 Mac 租用方案。從NodeMini 的 Mac 服務入口查看方案資訊前,先確認所需工具鏈、簽署資產及團隊控制方式能否在目標節點上完成驗收。