iOS 與 Xcode 服務器的持續集成解釋
已發表: 2022-03-11介紹
在 Xcode 9 之前,使用 Apple 持續集成工具是一個繁瑣而復雜的過程,需要購買和安裝額外的 macOS 服務器應用程序。 這導致許多開發人員放棄了為他們的 iOS 項目進行持續集成的想法,或者求助於第三方解決方案,取得了不同程度的成功。
不過,在 2017 年 9 月 Xcode 9.0 發布後,流程大大簡化,包括自動代碼簽名的選項,現在完全集成到 Xcode 中。 因此,它不需要任何額外的應用程序或工具。
雖然 Fastlane、Bluepill 等第三方解決方案有很大幫助,並且可以為您完成很多繁重的工作,但本文將探討單獨使用 Xcode 和 Apple 工具來滿足您的持續集成需求的功能。 我們還將使用手動代碼簽名,因為這對很多人來說似乎是個問題,而且當涉及到多個構建配置時,自動簽名也往往不是最佳解決方案。
注意:本文基於 Xcode 9.4.1 並側重於 iOS 應用程序開發,但其中很多內容適用於 Xcode 10(目前作為 beta 5 構建)和 macOS 應用程序開發。
設置 Xcode 服務器
除了簡化實際的集成過程之外,Xcode 9 還簡化了 Xcode Server 設置過程。
在已指定為 CI 服務器的 macOS 機器上啟動 Xcode 應用程序並打開 Preferences。
導航到最後一個選項卡,名為Server & Bots 。
通過單擊右上角的開關打開 Xcode Server 功能。 然後,您將被要求選擇一個用戶來在這台機器上運行和執行構建腳本。 為此目的擁有一個專門的用戶可能是個好主意,而不是使用預先存在的用戶。
請注意,此用戶必須登錄到系統才能運行任何 Xcode 機器人。 登錄後,您應該會在用戶名旁邊看到一個綠色圓圈。
而已! 讓我們仔細看看 Xcode 機器人。
如何配置 Xcode 機器人
現在您已準備好開始配置 Xcode 機器人以在此服務器上運行。 這可以在與服務器連接到同一網絡的任何開發機器上完成。
在您的開發機器上打開 Xcode,然後從頂部菜單中單擊Xcode > Preferences 。 然後,轉到“帳戶”選項卡並單擊左下角的+圖標。 從出現的對話框中選擇 Xcode Server。
要創建機器人,只需在 Xcode 中打開您的項目,然後從頂部菜單中選擇Product > Create Bot…選項。 機器人設置有許多步驟,我們將在接下來的部分中探討它們。
自動化應用程序分發
iOS 應用程序構建自動化最常見的應用之一是配置機器人以將應用程序上傳到 iOS 分發平台,例如 TestFlight、Fabric 等。
正如我之前解釋的,本文將只探討上傳到 App Store Connect 和直接從 Xcode 服務器下載,因為這些是 Apple 用於 iOS 應用程序分發的原生工具。
使用 Xcode 的 App Store Connect 分發
在配置機器人之前,請確保您擁有與您的應用開發項目的捆綁 ID 匹配的 App Store Connect 應用記錄。 還值得注意的是,每個構建都需要有一個由構建版本和構建號組成的唯一標識符。 當我們稍後討論 Xcode 機器人設置時,我們將探討如何確保滿足這些條件。
第 1 步:設置正確的構建配置是獲得所需內容的關鍵步驟。 確保選擇生成要上傳到 App Store Connect 的應用程序的方案和配置。 這包括確保構建配置使用在您團隊的 Apple Developer 門戶(用於代碼簽名)以及 App Store Connect 門戶(用於自動上傳應用程序)中註冊的適當捆綁包 ID .
第 2 步:雖然仍在“配置”選項卡上,但我們需要指定導出選項。 我們將探索導出選項屬性列表,因此請確保選中“使用自定義導出選項列表”。
第 3 步:現在是我們製作導出選項屬性列表的時候了。 如果您輸入xcodebuild --help
,則可以在此文件中使用完整的密鑰列表,但我們將在此處探索此機器人配置中使用的密鑰:
-
compileBitcode
– Bitcode 是 Apple 用於應用程序源代碼的臨時輸出格式。 換句話說,它是您的源代碼在編譯為特定架構的機器代碼之前轉換的格式。 它的目標是擁有一個單一的代碼容器,如果在指令集中進行優化,則可以進一步優化,並且還能夠將其編譯為相同格式的未來架構。 但是,這對您的應用程序沒有任何影響。 由您決定是否要啟用它。 -
method
– 此參數指定您要導出的產品類型。 蘋果通過指定的受眾來區分產品——開發只允許你將它安裝在配置文件中指定的設備上,企業允許每個人都安裝它,但他們需要在運行應用程序之前明確信任這個開發配置文件,而應用商店是將其分發到 App Store 或 App Store Connect,因此我們將使用此值。 -
provisioningProfiles
– 這是不言自明的。 但是這裡有幾件事需要注意:導出選項屬性列表中的配置文件是一個字典,其中鍵對應於產品的捆綁 ID,值對應於用於對其進行代碼簽名的配置文件的名稱。 -
signingCertificate
——另一個不言自明的論點。 此字段的值可以是完整的證書名稱或 SHA-1 哈希。 -
teamID
– 另一個不言自明的論點。 這是在您註冊 Apple Developer 計劃時 Apple 向您的組織頒發的 10 個字符長的標識符。 -
uploadBitcode
– 是否上傳 bitcode(如果您選擇編譯成它),以便它可以在 AppStore Connect 中用於生成新的優化構建或用於未來架構的構建。 -
uploadSymbols
– 上傳您的調試符號,以便您可以獲得有意義的崩潰報告,而不僅僅是內存轉儲和程序集堆棧。
所以現在,您的導出選項屬性列表可能如下所示:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>compileBitcode</key> <false/> <key>method</key> <string>app-store</string> <key>provisioningProfiles</key> <dict> <key>com.bundle.id</key> <string>ProvisioningProfileName</string> </dict> <key>signingCertificate</key> <string>Signing Certificate Exact Name or SHA-1 hash value</string> <key>teamID</key> <string>??????????</string> <key>uploadBitcode</key> <false/> <key>uploadSymbols</key> <true/> </dict> </plist>
第 4 步:選擇您創建的 .plist 作為導出選項屬性列表。
第 5 步:接下來是“計劃”選項卡——根據您的喜好進行設置。
第 6 步:在“簽名”選項卡上,確保取消選中“允許 Xcode 服務器管理我的證書和配置文件”選項,並在“證書和配置文件”頁面上自行上傳匹配的簽名證書和配置文件。
第 7 步:設備選項卡應保持原樣,因為我們正在上傳應用程序而不是對其進行測試。
第 8 步: Arguments選項卡允許您顯式設置 xcodebuild 參數或環境變量,這些參數或環境變量可用於您的構建或集成前和集成後腳本。
第 9 步:最後,我們到達Triggers選項卡,這也是配置 Xcode 持續集成機器人的最後一個選項卡。 這是 Xcode Server 武器庫中最強大的工具。 對於初學者,我喜歡添加以下兩個命令作為預集成腳本:

#!/bin/sh set printenv
第一個打印 Xcode Server 在當前集成運行中使用的所有變量及其值。 第二個打印所有環境變量及其值。 正如預期的那樣,這有助於調試您的腳本,因此我恰當地將其命名為“調試信息”。
請記住,我們提到我們需要確保上傳到 App Store Connect 的每個構建都需要具有唯一的構建版本和內部版本號對。 我們可以使用內置的 PlistBuddy 工具,但我們還需要一種方法來擁有唯一的內部版本號。 在 Xcode Server 集成期間始終存在的一件事——並且也是方便地唯一的——是集成編號,因為它是自動遞增的。 我們將創建另一個預集成腳本,名為“set build number”,內容如下,以確保我們每次都有一個唯一的 build number:
#!/bin/sh buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}") buildNumber=$XCS_INTEGRATION_NUMBER /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
如果您正在使用 CocoaPods 並選擇不將 Pods 目錄提交到您的 DVCS,您還應該包含一個包含以下內容的預集成腳本:
#!/bin/sh cd $XCS_PRIMARY_REPO_DIR pod install
第 10 步:我們幾乎完成了,但我們尚未指定要將構建上傳到 AppStore Connect 的任何地方或哪個帳戶。 為此,我們將添加後集成腳本和另一個內置工具,稱為 Application Loader。 將以下內容放入腳本中:
#!/bin/sh /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --upload-app -f $XCS_PRODUCT -u $TESTFLIGHT_USERNAME -p $TESTFLIGHT_PASSWORD
$XCS_PRODUCT
是一個 Xcode 服務器變量,它包含在當前集成運行中創建的應用程序的路徑。 但是, $TESTFLIGHT_USERNAME
和$TESTFLIGHT_PASSWORD
既不是系統變量,也不是 Xcode 服務器變量。 這些必須由您設置並具有您的 Apple ID 和密碼的值。 不幸的是,Apple 已停止支持為 AppStore Connect 構建上傳生成 API 密鑰。 由於這是機密信息,因此最佳做法是直接在 Mac 服務器上(假設它是您自己的)將其設置為環境變量,而不是在 Xcode Server 機器人配置中。
Xcode 服務器分發
Xcode Server 分發機器人實際上使用與 App Store Connect 分發相同的配置,但集成後腳本除外。 但是,下載應用程序並安裝它仍然很棘手。 您仍然必須確保您為應用程序簽名的配置文件允許該應用程序安裝在您使用的設備上。
準備好之後,您需要在 iOS 設備上打開 Safari 並導航到服務器的 Xcode Server Web 儀表板。 例如,如果您的服務器名稱是“Mac 服務器”,如果您與服務器位於同一網絡上,您可以在“mac-server-name.local/xcode”中找到它。 在那裡,您會找到所有 Xcode 機器人的列表以及它們最近集成的統計信息。
選擇已構建您要下載的應用程序的應用程序。 在接下來的屏幕上,您將有兩個按鈕 - Install和Profile 。 如果這是您第一次從該服務器下載,您必須單擊配置文件以將其證書添加到受信任來源列表中。 之後,單擊同一頁面上的安裝按鈕,您將看到 iOS 確認對話框“您確定要在您的設備上安裝 * 嗎?” 單擊Yes進行確認,您的應用程序將被安裝並可以從主屏幕運行。
對於iOS 10.3 及更高版本,它可能因“無法連接到 *.local”而失敗的一個原因是,必須在測試設備的設置中手動信任自簽名證書。
按著這些次序:
第 1 步:從 iPhone 上的 Xcode 服務器的機器人頁面安裝自簽名證書。
第 2 步:轉到 iPhone 的設置 > 通用 > 關於 > 證書信任設置。
第 3 步:在ENABLE FULL TRUST FOR ROOT CERTIFICATES部分下找到您服務器的自簽名證書,然後打開開關。
第 4 步:返回 Xcode Server 上的 bot 集成頁面,單擊Install 。
Xcode 服務器自動應用程序測試
Xcode Server 的另一個重要用途是自動應用程序測試,無論是單元測試還是 UI 測試。 為此,您需要為您的項目設置適當的目標。 也就是說,您需要有一個運行單元或 UI 測試的目標,具體取決於您的目標。
設置過程與上一個相同,但我們將選擇不同的選項。 第一個主要區別在於配置選項卡。 顯然,我們將選中“分析”和“測試”框,因為這是我們的主要目標。 我還建議不要使用此機器人存檔或導出產品。 可以使用相同的機器人配置同時實現測試和分發。 但是,這兩種情況的輸出和時間表不同。 分發通常在周期結束時運行。
無論您是在 Scrum 還是看板或其他框架中工作,都應該有一個預定義的時間驅動或事件驅動的周期,在該週期結束時,您應該有導出和可用的產品。 另一方面,您應該在每次提交時運行您的測試機器人,因為它是您抵禦回歸的第一道防線。 由於測試機器人顯然運行得更頻繁,將這兩個機器人合併為一個可能會很快耗盡服務器上的磁盤空間。 而且每次集成還需要更多時間才能完成。
有了這個,我們將轉到“計劃”選項卡,我們已經在上一段中解決了這個問題。 因此,下一個感興趣的主題是代碼簽名。 請注意,即使您的測試目標可能在您的項目設置頁面中聲明它不需要配置文件,您也應該將其設置為使用與主機應用程序相同的團隊和簽名證書。 如果您想在 iOS 設備上而不是在模擬器上測試您的應用程序,這是必需的。 如果是這種情況,您還需要確保用於測試的 iOS 設備不會因為不活動而被鎖定,因為這可能會導致您的集成運行無限期掛起而不通知您。
現在我們在不需要具體解釋的“設備”選項卡上。 只需選擇一個、多個或所有要測試代碼的設備(iOS 和模擬器)。 您還可以檢查是否在多個設備上並行或按順序運行測試。 要進行設置,您應該考慮您的項目需求(無論您是針對一組特定設備還是所有受支持的 iOS 設備)以及服務器的硬件資源。
在參數選項卡上。 無需明確指定任何內容,因為我們只會使用內置環境變量。
最後,在Triggers選項卡上,我們將介紹一個預集成和一個集成後腳本。 第一個只是為了幫助我們調試,以防我們遇到一些問題。 它實際上是我們已經使用過的:
#!/bin/sh set printenv
第二個是在我們的一個或多個測試在當前集成中失敗的情況下通知我們的。 確保將其設置為僅在測試失敗時運行。 並輸入以下內容:
#!/bin/sh echo "$XCS_TEST_FAILURE_COUNT test(s) failed for $XCS_BOT_NAME bot on build $XCS_INTEGRATION_NUMBER" echo "You can see bot integration at:" echo "https://$HOSTNAME/xcode/bots/$XCS_BOT_TINY_ID/integrations/$XCS_INTEGRATION_TINY_ID"
這裡有幾件事需要解釋。 首先,$HOSTNAME 變量存儲以下格式的值:computer-name.local。 顯然,只有當您可以通過本地網絡訪問該服務器時,該鏈接才會起作用。 此外,當您訪問此鏈接時,您很可能會從瀏覽器收到安全警告,因為它是到無法信任的目的地的 https 連接。 最後,這只是您的“測試失敗”腳本的起點。 您可以向整個開發團隊發送電子郵件,或通過 API 請求或您認為最合適和最有效的任何其他方式打開 JIRA 問題。
包起來
希望本文能鼓勵您花時間探索 Xcode Server 的功能,而不僅僅是構建一個應用程序。 雖然這篇文章可能無法完全按照您想要或期望的方式幫助您,但其目的是向您介紹一種使用內置環境和 Xcode Server 變量實現更高級別自動化的開放方式。
有很多第三方服務支持更多功能,可以為你做更多的工作,包括 Fabric、Bluepill 和 Fastlane。 但是,不可避免地,依賴第三方會為您的項目引入新的依賴關係,並且有時需要簡單、有時復雜的設置和配置。 此處描述的技術只需要每台 Mac 上已經安裝的工具,因此除了配置將運行您的自動構建的機器人之外,它不需要設置時間!