TeamCity 2026.1 的 Agent 執行環境要求 Java 21,但控制台顯示「Connected」並不代表它能執行生產 Xcode 流水線;你應先完成 Java 21、非 root 專用帳號、獨立 Agent Pool、Xcode 路由、工作區隔離與重啟恢復驗收,再決定是否准入。TeamCity 2026.1 的系統要求可參考 JetBrains 官方版本要求。
正在為 TeamCity 增加 iOS 或 macOS 建置能力的平台工程負責人,適合看這篇。
如果你要把本地 Mac mini 改成共享建置節點,或準備採購、租用多台遠端 Mac,本文會把「能連線」與「可上生產」分開判斷。
最後更新於 2026 年 8 月 30 日;版本與啟動機制資料核實自 TeamCity On-Premises 2026.1、TeamCity Cloud 2026.2 及 Apple Developer 官方文件。Cloud 文件只用來說明 Cloud Agent 的啟動機制,不直接推導 On-Premises 功能。
先判斷:你要上線的是 Agent,還是可承擔生產工作的節點?
TeamCity 2026.1 macOS Build Agent 部署最常見的誤判,是把「服務程序已啟動」當成「節點已經可用」。實際上,至少有五個獨立阻斷域:執行時版本、授權與網路、Xcode 路由、專案隔離、故障恢復。
先用下面的條件分支決定投入方式:
- 若主機能以 Java 21 啟動 Agent,且專用帳號、serverUrl、授權狀態都能留下記錄,才進入 Xcode 驗收。
- 若 Agent 已連線,但 Xcode 路徑或版本無法由節點參數證明,回退為測試節點,不加入正式發布 Pool。
- 若節點需要互動式登入才能啟動,或重啟後無法自動接單,不要放入無人值守的生產 Pool。
- 若正式簽名與非可信任 Pull Request 共用工作區或 Keychain,改用專用 Agent Pool 或獨立 Mac。
- 若沒有固定 Mac 容量或替代節點,先用一台隔離的遠端 Mac 做試點;真實專案通過後,再按排隊與故障資料擴容。
運行時與連線問題是註冊前的阻斷點
第一步:分清 Agent JDK 與專案 JDK
TeamCity 2026.1 的 Agent 執行要求是 Java 21。這是 Agent 能否啟動與註冊的基線,不等於你的 Android、Java 或其他專案一定要以 Java 21 編譯。平台工程團隊應把兩者分開記錄:
| 核查項目 | Agent 上線要求 | 驗收證據 |
|---|---|---|
| Agent 執行 JDK | Java 21 | java -version、Agent 啟動日誌 |
| 專案編譯 JDK | 依專案工具鏈決定 | 建置設定、實際編譯日誌 |
| 主機架構 | 記錄 Apple Silicon 或其他架構 | 主機資產記錄、uname -m |
| 環境變數 | JAVA_HOME 指向預期 JDK |
啟動環境與程序環境輸出 |
| 執行身份 | 專用非 root 帳號 | 程序擁有者、檔案所有權 |
最小核實可以先執行:
java -version
echo "$JAVA_HOME"
uname -m
生產 Agent 不應長期以 root 執行。root 會令 checkout 檔案、快取、臨時 Keychain 與建置產物更難追蹤,也會放大腳本誤操作的影響。需要安裝 Xcode、建立 launchd 設定或調整系統權限時,可由管理員短暫處理;Agent 本身則交回專用帳號。
第二步:不要只用 Connected 判斷註冊成功
Agent 需要主動連線到 TeamCity Server。反向代理、HTTPS 憑證、出站防火牆或錯誤的 serverUrl,都可能造成「看似連線、實際不能穩定接單」的情況。官方快速設定流程也要求核對 Agent 設定與伺服器連線,而不是只看介面上的單一狀態。
| 觀察位置 | 必須確認的內容 | 常見錯誤 |
|---|---|---|
| Agent 設定檔 | serverUrl、授權資料、固定 Agent 名稱 |
URL 指向錯誤路徑或環境 |
| Agent 日誌 | 啟動、註冊、重新連線與錯誤時間 | 只截取控制台畫面 |
| TeamCity Server | Agent 授權狀態與所屬 Pool | 已連線但尚未授權 |
| 反向代理 | HTTPS、標頭、WebSocket 或長連線政策 | 代理逾時、憑證不完整 |
| 網路出口 | Mac 能否持續連到 Server | 只測試一次 ping |
不要把 authorizationToken 直接散落在 Shell history 或共享文件中。應使用受控設定檔與權限限制,並在交接時記錄誰負責輪換。TeamCity 的 Agent 安裝與設定欄位可對照官方 Agent 配置文件。
Xcode 路由錯誤,為甚麼會讓在線節點接不到正確工作?
Apple Silicon 主機只代表硬體架構合適,並不代表它已具備可執行 iOS 建置的完整工具鏈。只安裝 Command Line Tools 的 Mac,不能被企業流程誤判為已安裝完整 Xcode 的發布節點。Apple 對 Command Line Tools 的用途與元件有獨立說明,應以Apple 官方命令列工具文件核對。
單版本 Xcode 與多版本 Xcode 的取捨
單版本節點較容易管理。你可以固定 xcode-select 指向完整 Xcode,並在建置日誌中確認 xcodebuild -version。多版本節點則需要更嚴格的路由,不能只用「macos-agent-01」這類名稱作判斷。
Xcode 路由應由三層共同完成:
- 工作流程要求:任務明確要求某個 Xcode 或 SDK 能力。
- Agent Parameters:節點暴露可供 TeamCity 辨識的版本與路徑。
- 實際工具鏈輸出:建置日誌記錄
xcodebuild使用的版本與路徑。
TeamCity 的 Xcode Runner、建置參數與 Agent Requirements 各自負責不同層面。可參考官方 Xcode 建置說明、預定義建置參數文件與Agent Requirements 說明。
如果任務要求 Xcode 版本 A,節點參數卻回報版本 B,應讓它無法匹配,而不是靠工程師記住哪一台 Mac 裝了甚麼。這是路由設計,也是避免錯誤簽名與 SDK 差異的基本控制。
工作區與簽名資料怎樣避免跨專案殘留?
TeamCity Agent 上的建置不會天然提供完整安全邊界。共享工作區可能留下未追蹤檔案、產物、快取或腳本建立的暫存資料;共享登入 Keychain 則可能讓下一個任務看見不應取得的簽名身份。
你應把任務分成三類:
- 非可信任 Pull Request:使用隔離節點,不接觸正式簽名憑證。
- 一般測試與模擬器建置:可使用測試 Pool,但仍要清理 checkout directory。
- 正式 Archive 與簽名發布:使用專用 Mac、專用 Pool、臨時 Keychain,完成後清除憑證與 profile。
驗收時保留四類證據:
- 不同專案的 checkout directory 路徑與目錄差異。
- clean checkout 前後的檔案清單。
- 臨時 Keychain 建立、使用與刪除記錄。
- 建置日誌中簽名身份、Archive 結果與清理步驟。
你可以再參考這份企業遠端 Mac 方案,把主機交付、帳號權限與節點用途納入同一份資產記錄。TeamCity 的 Agent Pool 應按信任邊界與工作負載拆分,而不是只按部門名稱分組;官方的 Agent Pool 配置文件可作為權限與分派設計的基礎。
重啟後仍不能接單,問題通常在哪裡?
第三步:建立 launchd 的無人值守恢復鏈路
TeamCity Agent 要作為生產節點,必須測試主機重啟後能否自行恢復。你需要核對:
- launchd 設定是由正確帳號載入,且設定檔所有權正確。
JAVA_HOME、Agent 工作目錄與設定檔路徑在非互動式環境仍然存在。- Mac 重啟後不依賴人工登入即可啟動 Agent。
- Agent 能重新連線、通過授權並重新接單。
- 第一個 Xcode 任務能找到工具鏈,臨時 Keychain 也能按預定方式使用。
官方 Cloud Agent 啟動文件可用來理解啟動屬性與自動啟動概念,但不要把 Cloud 2026.2 的行為直接當作 On-Premises 2026.1 的保證;兩者必須按各自版本文件與你的主機實測驗收。
可以用以下命令查看服務狀態,實際 label 和路徑按你的設定替換:
launchctl print gui/$(id -u)/com.example.teamcity-agent
若流程依賴使用者登入、手動解鎖 Keychain 或遠端桌面操作,這不是完整的無人值守方案。把測試結果記為「暫緩生產准入」,並配置替代節點或改造憑證流程,而不是用人工補救掩蓋故障。
真實流水線與容量決定生產准入
空專案只能證明工具可以被呼叫,不能證明你的 iOS CI/CD 可承擔生產工作。准入測試至少應包含代表性 Pull Request、模擬器測試、Archive,以及受控的簽名任務。每項測試都要關聯提交紀錄、節點名稱、Xcode 輸出與建置日誌。
建議你把驗收結果整理成以下表格:
| 驗收域 | 通過證據 | 未通過時的回退 |
|---|---|---|
| Agent 註冊 | 日誌、授權狀態、固定名稱 | 暫停加入生產 Pool |
| Xcode 路由 | 任務要求、Agent Parameters、xcodebuild 輸出一致 |
指向專用版本節點 |
| 簽名隔離 | 臨時 Keychain 與清理記錄 | 改用獨立 Mac |
| 重啟恢復 | 重啟時間、重新連線、成功接單記錄 | 保留主機為試點 |
| 容量與替代 | 排隊記錄、故障接管演練 | 增加主備或彈性節點 |
第四步:用容量證據決定單節點或節點池
不要先買滿硬體,再等待實際需求出現。先從代表性建置記錄排隊、失敗原因、工作區清理與重啟後接單結果。若正式簽名任務與一般測試在同一時段互相阻塞,應優先拆分 Pool;若單節點故障時沒有替代接管,則應建立主備或彈性遠端 Mac 池。
TeamCity 的 Agent Pool 分組、Xcode 路由與憑證隔離,三者需要一起設計。只增加 Agent 數量而不調整信任邊界,不能解決錯誤簽名或資料殘留問題。
常見問題
TeamCity macOS Build Agent 要怎樣設定開機後自動啟動?
先以專用非 root 帳號確認 Java、工作目錄與設定檔,再建立 launchd 啟動項目。驗收不能停在「程序存在」;要重啟主機,確認 Agent 重新連線、通過授權、找到 Xcode,並完成一個實際建置。若必須人工登入,便不符合無人值守生產節點的要求。
Agent 顯示已連線,為甚麼仍然不能執行 Xcode 建置?
Connected 只描述 Agent 與 Server 的連線,不代表 Xcode、SDK 或簽名環境符合任務要求。你需要檢查完整 Xcode、xcode-select、Agent Parameters 與 Agent Requirements,並從實際建置日誌確認工具鏈版本。若三方資料不一致,應先修正路由,不要強制執行任務。
TeamCity 可以按照不同 Xcode 版本分派到不同 Mac 嗎?
可以使用 Agent Parameters 與 Agent Requirements 形成條件匹配。每台 Mac 應固定可辨識的 Xcode 路徑,工作流程則明確寫出所需版本。節點名稱只能協助人工識別,不能取代條件分派;最終仍要以 xcodebuild 輸出證明任務真的在預期工具鏈上執行。
Mac Agent 如何隔離簽名憑證與專案工作區?
非可信任程式碼、一般測試與正式發布應分到不同 Agent Pool,必要時使用不同實體 Mac。正式任務使用臨時 Keychain,完成後刪除簽名身份、profile 與暫存資料;同時執行 clean checkout,保留目錄差異和清理日誌。共享 Agent 不會自動提供專案級安全隔離。
遠端 Mac 適合用作 TeamCity 的生產建置節點嗎?
可以,但要先通過真實流水線、Xcode 路由、簽名清理、重啟恢復與故障接管測試。遠端節點若只有互動式登入、沒有替代容量,應先作為隔離試點。你可先查看 KVMNODE 的遠端 Mac 選項,再按實際排隊資料決定租用週期與節點數量。
企業 IT 應保留完整准入記錄
生產准入表不應只寫「成功」或「失敗」。每個結論都要能追溯到主機資產、Agent 日誌、Server 授權畫面、Xcode 輸出、Keychain 清理記錄與重啟時間戳。
如果你正整理團隊的 iOS CI/CD 容量規劃,可把以下欄位加入平台維運資料庫:
- Agent 名稱、Apple Silicon 架構與 macOS 版本。
- Agent JDK 與專案編譯 JDK 的分別。
- Xcode 路徑、版本參數與實際建置輸出。
- 所屬 Agent Pool、可執行的專案類型與簽名邊界。
- 重啟後恢復結果、最後一次成功接單時間與失敗告警。
- 單節點故障時的回退節點與人工介入步驟。
相較於直接把本地 Mac mini 暴露給整個團隊,遠端 Mac 的優勢是可以先用獨立節點驗證權限、網路與恢復流程;但它仍不會自動替你解決 Xcode 版本漂移、憑證管理或容量不足。你必須把這些控制項寫進准入標準。
如果目前方案是共享本地 Mac mini,常見缺點是硬體位置受限、重啟與故障需要現場處理,而且簽名資料容易與日常測試混在同一台主機;若改用自行購置多台 Mac,則還要承擔資產折舊、維修替換與閒置容量。對需要先驗證 TeamCity 路由、Xcode 與簽名流程的團隊,先租用 KVMNODE 的獨立遠端 Mac 作試點通常更容易控制風險;待准入證據和隊列容量明確後,再決定按週、按月或更長週期配置節點。