搭配 Xamarin 使用 TeamCity
本指南將討論使用TeamCity編譯行動應用程式,然後將其提交至App Center測試相關的步驟。
如持續整合簡介指南所述 ,開發品質行動應用程式時,持續整合 (CI)是實用的做法。 持續整合伺服器軟體有許多可行的選項;本指南將著重於 JetBrains 的 TeamCity 。
TeamCity 安裝有數個不同的排列。 下列清單描述其中一些排列:
Windows 服務 – 在此案例中,TeamCity 會在 Windows 開機為 Windows 服務時啟動。 它必須與 Mac 組建主機配對,才能編譯任何 iOS 應用程式。
在OS X 上啟動精靈 – 在概念上,這類似於以上一個步驟中所述的 Windows 服務執行。 根據預設,組建將會在根帳戶下執行。
OS X 上的用戶帳戶 – 可以在每次使用者登入時啟動的使用者帳戶下執行 TeamCity。
在先前的案例中,在OS X上的用戶帳戶下執行TeamCity是最簡單的設定方式。
設定 TeamCity 涉及幾個步驟:
安裝 TeamCity – 本指南未涵蓋 TeamCity 的安裝。 本指南假設 TeamCity 已安裝並在用戶帳戶下執行。 如需安裝TeamCity的指示,請參閱 JetBrains 的TeamCity 8 檔。
準備組建伺服器 – 此步驟牽涉到安裝建置行動應用程式所需的必要軟體、工具和憑證,並準備它們以供散發。
建立建置腳本 – 此步驟並非絕對必要,但建置腳本是自動建置應用程式的實用協助。 使用組建腳本有助於針對可能發生的建置問題進行疑難解答,並提供一致且可重複的方式來建立散發的二進制檔,即使不練習持續整合也一樣。
建立 TeamCity 專案 – 完成上述三個步驟之後,我們必須建立 TeamCity 專案,其中包含擷取原始程式碼、編譯專案,以及將測試提交至 App Center 測試所需的所有元數據。
需求
需要 App Center 測試的體驗。
需要熟悉TeamCity 8.1。 TeamCity 的安裝超出本文件的範圍。 假設 TeamCity 已安裝在 OS X Mavericks 上,並且是在一般使用者帳戶下執行,而不是根帳戶。
建置伺服器應該是獨立計算機,執行OS X,專用於持續整合。 在理想情況下,組建伺服器不會負責任何其他角色,例如資料庫伺服器、Web 伺服器或開發人員工作站。
重要
本指南未涵蓋 Xamarin 的「無頭部」安裝。
防火牆組態
為了讓測試提交至 Xamarin Test Cloud,提交測試的計算機必須能夠與測試雲端伺服器通訊。 防火牆必須設定為允許埠 80 和 443 上位於 testcloud.xamarin.com 的伺服器之間的網路流量。 此端點由 DNS 管理,IP 位址可能會變更。
在某些情況下,測試(或執行測試的裝置)必須與受防火牆保護的網頁伺服器通訊。 在此案例中,防火牆必須設定為允許來自下列IP位址的流量:
- 195.249.159.238
- 195.249.159.239
準備組建伺服器
設定組建伺服器的關鍵步驟是安裝所有必要的工具、軟體和憑證,以建置行動應用程式。 建置伺服器必須編譯行動解決方案並執行任何測試。 若要將設定問題降到最低,軟體和工具應該安裝在裝載TeamCity的相同用戶帳戶中。 下列清單詳述必要專案:
- Visual Studio for Mac – 這包括 Xamarin.iOS 和 Xamarin.Android。
- 登入 Xamarin 元件存放區 – 此步驟是選擇性的,只有在您的應用程式使用來自 Xamarin 元件存放區的元件時才需要。 此時主動登入元件存放區時,當 TeamCity 組建嘗試編譯應用程式時,將防止任何問題。
- Xcode – 編譯和簽署 iOS 應用程式需要 Xcode 。
- Xcode 命令行工具 – 這是使用 rbenv 更新 Ruby 指南之安裝一節的步驟 1 中所述。
- 簽署身分識別與布建配置檔 – 透過 XCode 匯入憑證和布建配置檔。 如需詳細資訊,請參閱Apple關於 匯出簽署身分識別和布建配置檔 的指南。
- Android Keystores – 將必要的 Android 金鑰存放區複製到 TeamCity 使用者可存取的目錄,也就是
~/Documents/keystores/MyAndroidApp1
。 - Calabash – 如果您的應用程式已使用 Calabash 撰寫測試,這是選擇性步驟。 如需詳細資訊,請參閱在OS X Mavericks上安裝 Calabash 指南和使用 rbenv 更新 Ruby 指南。
下圖說明所有這些元件:
安裝所有軟體之後,請登入用戶帳戶,並確認所有軟體都已正確安裝並運作。 這應該涉及編譯解決方案,並將應用程式提交至 App Center 測試。 執行組建腳本可以簡化此動作,如下一節所述。
建立組建腳本
雖然 TeamCity 可以自行處理編譯和提交行動應用程式到 App Center 測試的所有層面:建議您建立組建腳本。 組建腳本提供下列優點:
- 檔 – 組建文本可作為軟體建置方式的檔形式。 這會移除與部署應用程式相關聯的一些「魔術」,並讓開發人員專注於功能。
- 可重複性 – 建置腳本可確保每次編譯和部署應用程式時,都會以相同方式發生,無論誰或做什麼工作。 這個可重複的一致性會移除因執行不正確組建或人為錯誤而出現的任何問題或錯誤。
- 版本控制 – 組建文本可以包含在原始檔控制系統中。 這表示如果找到錯誤或錯誤,則可以追蹤、監視及更正組建腳本的變更。
- 準備環境 – 組建腳本可以包含邏輯來安裝任何必要的第三方相依性。 這可確保應用程式是使用適當的元件所建置。
組建腳本可以像 PowerShell 檔案(在 Windows 上)或 Bash 腳本(在 OS X 上)一樣簡單。 建立組建腳本時,腳本語言有數個選項:
Rake – 這是以 Ruby 為基礎的建置專案之領域特定語言 (DSL)。 Rake 具有熱門度和豐富的連結庫生態系統的優點。
psake – 這是用於建置軟體的 Windows PowerShell 連結庫
FAKE – 這是以 F# 為基礎的 DSL,可在必要時使用現有的 .NET 連結庫。
使用哪一種腳本語言取決於您的喜好設定和需求。
注意
您可以使用 MSBuild 或 NAnt 等 XML 型建置系統,但這些建置系統缺乏專用於建置軟體的 DSL 表達性和可維護性。
參數化建置腳本
建置和測試軟體的程式需要應保密的資訊。 建立 APK 可能需要金鑰存放區的密碼和/或金鑰存放區中的密鑰別名。 同樣地,App Center 測試需要開發人員唯一 的 API 金鑰 。 這些類型的值不應該在組建腳本中硬式編碼。 相反地,它們應該以變數的形式傳遞至建置腳本。
較不敏感的值,例如 iOS 裝置識別碼或 Android 裝置識別碼,可識別 App Center 應該用於測試回合的裝置。 這些不是需要保護的值,但它們可能會從組建變更為組建。
將這些類型的變數儲存在建置腳本之外,也可讓您更輕鬆地在組織內共用組建腳本,例如開發人員。 開發人員可以使用與建置伺服器完全相同的腳本,但可以使用自己的密鑰存放區和 API 金鑰。
儲存這些敏感性值有兩個可能的選項:
組態檔 – 若要保護 API 金鑰,這個值不應該簽入版本控制。 您可以為每個電腦建立檔案。 從這個檔案讀取值的方式取決於所使用的腳本語言。
環境變數 – 這些變數 可在每部機器上輕鬆設定,而且與基礎腳本語言無關。
這些選擇都有其優點和缺點。 TeamCity 與環境變數搭配運作良好,因此本指南會在建立組建腳本時建議這項技術。
建置步驟
建置文稿必須執行下列步驟:
編譯應用程式 – 這包括使用正確的布建配置檔簽署應用程式。
將應用程式提交至 Xamarin Test Cloud – 這包括簽署和壓縮 APK 與適當的金鑰存放區。
以下將詳細說明這兩個步驟。
編譯 Xamarin.iOS 應用程式
下列命令行會指定 i 電話 解決方案的發行組建SOLUTION_FILE.sln。 您可以在命令列上指定 IpaPackageDir
屬性來設定 IPA 的位置:
在 Mac 上使用 xbuild:
xbuild /p:Configuration="Release" \ /p:Platform="iPhone" \ /p:IpaPackageDir="$HOME/Builds" \ /t:Build MyProject.sln
xbuild 命令通常位於 /Library/Frameworks/Mono.framework/Commands 目錄中。
在 Windows 上使用 msbuild:
msbuild /p:Configuration="Release" /p:Platform="iPhone" /p:IpaPackageDir="%USERPROFILE%\Builds" /p:ServerAddress="192.168.1.3" /p:ServerUser="macuser" /t:Build MyProject.sln
msbuild 不會自動展開 $( )
命令行傳入的表達式。 基於這個理由,建議您在命令行設定 IpaPackageDir
時使用完整路徑。
如需屬性的詳細資訊IpaPackageDir
,請參閱 iOS 9.8 的版本資訊。
編譯 Xamarin.Android 應用程式
若要編譯 Android 應用程式,請使用 xbuild (或 Windows 上的 msbuild):
/Library/Frameworks/Mono.framework/Commands/xbuild /t:SignAndroidPackage /p:Configuration=Release /path/to/android.csproj
編譯 Android 應用程式 xbuild 會使用專案,而 iOS 應用程式 xbuild 則使用方案。
將 Xamarin.UITests 提交至 App Center
UITest 會使用 App Center CLI 提交,如下列代碼段所示:
appcenter test run uitest --app <TEAM-NAME/APP-NAME> --devices <DEVICE_SET> --token <API_KEY> --app-path <appname.APK-or-appname.IPA> --merge-nunit-xml report.xml --build-dir pathToUITestBuildDir
執行測試時,測試結果會以名為 report.xml的 NUnit 樣式 XML 檔案形式傳回。 TeamCity 會在組建記錄檔中顯示資訊。
如需如何將 UITest 提交至 App Center 的詳細資訊,請參閱 準備 Xamarin.Android 應用程式 或 準備 Xamarin.iOS 應用程式。
將 Calabash 測試提交至 App Center
Calabash 測試是使用 App Center CLI 提交,如下列代碼段所示:
appcenter test run calabash --app <TEAM-NAME/APP-NAME> --devices <DEVICE_SET> --token <API_KEY> --app-path <appname.APK-or-appname.IPA> --project-dir pathToProjectDir
若要將Android應用程式提交至App Center測試,必須先使用calabash-android重建 APK 測試伺服器:
$ calabash-android build </path/to/signed/APK>
$ appcenter test run calabash --app <TEAM-NAME/APP-NAME> --devices <DEVICE_SET> --token <API_KEY> --app-path <appname.APK> --project-dir pathToProjectDir
如需提交 Calabash 測試的詳細資訊,請參閱 Xamarin 關於將 Calabash 測試提交至測試雲端的指南。
建立 TeamCity 專案
安裝 TeamCity 且 Visual Studio for Mac 可以建置您的項目之後,就可以在 TeamCity 中建立專案,以建置專案並將其提交至 App Center。
首先,透過網頁瀏覽器登入 TeamCity。 瀏覽至根專案:
在根專案底下,建立新的子專案:
建立子項目之後,請新增組建組態:
將 VCS 專案附加至組建組態。 這是透過 [版本控制設定] 畫面來完成:
如果沒有建立 VCS 專案,您可以從如下所示的新 VCS 根頁面建立一個專案:
附加 VCS 根目錄之後,TeamCity 會簽出專案,並嘗試自動偵測建置步驟。 如果您熟悉 TeamCity,則可以選取其中一個偵測到的建置步驟。 目前可以放心地忽略偵測到的建置步驟。
接下來,設定組建觸發程式。 這會在符合特定條件時將組建排入佇列,例如當使用者將程式代碼認可至存放庫時。 下列螢幕快照顯示如何新增組建觸發程式:
您可以在下列螢幕快照中看到設定組建觸發程式的範例:
上一節將建置腳本參數化,建議將一些值儲存為環境變數。 這些變數可以透過 [參數] 畫面新增至組建組態。 新增 App Center API 金鑰、iOS 裝置識別碼和 Android 裝置識別碼的變數,如下列螢幕快照所示:
最後一個步驟是新增建置步驟,以叫用建置腳本來編譯應用程式,並將應用程式加入App Center測試。 下列螢幕快照是使用 Rakefile 建置應用程式的建置步驟範例:
此時,組建組態已完成。 建議您觸發組建以確認專案已正確設定。 若要這樣做,最好是將小型、微不足道的變更認可至存放庫。 TeamCity 應該偵測認可並啟動組建。
建置完成後,請檢查組建記錄檔,並查看組建是否有任何問題或警告需要注意。
摘要
本指南涵蓋如何使用TeamCity建置 Xamarin Mobile 應用程式,然後將應用程式提交至 App Center 測試。 我們已討論如何建立組建腳本,以自動化建置程式。 建置腳本會負責編譯應用程式、提交至 App Center 測試,以及等候結果。
然後,我們討論如何在 TeamCity 中建立專案,在每次開發人員認可程式代碼並呼叫建置腳本時,都會將組建排入佇列。