如果您經常發佈 Android 應用,您可能已經瞭解定義明確的構建、測試和部署工作流的價值。如果沒有靈活的自動化 DevOps 工作流,就很難維持高速發佈。通過持續集成和持續部署 (CI/CD) 自動執行這些工作流可以讓您的工作變得更加輕鬆,讓您更早地發現 bug,更快地發佈產品。
JetBrains TeamCity 是一個用於構建可靠管道的 CI/CD 平台。它可與流行的 Android 開發工具無縫集成,並具有人性化界面來配置構建和測試的各個階段。
本文將向您介紹如何使用 JetBrains TeamCity 為您的 Android 項目設置 CI/CD 管道。您將探索 Android CI/CD 管道的關鍵組件,並深入瞭解如何使用 TeamCity 配置一些示例管道。
瞭解 Android CI/CD 管道
Android 開發的有效 CI/CD 管道包含標準 DevOps 管道中的所有步驟,並通過附加流程(如工件簽名和自動部署到 Google Play 商店的內部軌道)對其進行了增強。下面是典型 Android CI/CD 管道中涉及的所有步驟的快速概覽:
- 代碼簽出和版本控制集成:管道會先從您的版本控制系統(VCS,如 Git)獲取最新的代碼更改。如果您在使用 TeamCity,您將受益於它與流行的版本控制工具的集成以及在代碼提交或合併時自動觸發管道的功能。
- 使用 Gradle 實現構建自動化:Android 項目的標準構建工具 Gradle 是這一步的核心。TeamCity 會執行 Gradle 命令來編譯您的代碼、彙集資源並生成構建工件。TeamCity 的構建運行程序提供了與不同 Gradle 版本的兼容性和可自定義的構建配置環境。
- 針對多個 Android 版本/平台的單元和集成測試:下一步包括運行驗證個別代碼模塊的單元測試和檢查不同組件如何交互的集成測試(包括 UI 測試)。TeamCity 允許您配置多個測試運行程序和框架(例如 JUnit、Espresso),並使用模擬器或設備實驗室針對各種 Android 版本和平台執行測試。
- 靜態代碼分析(以 JetBrains Qodana 為特色)和代碼覆蓋率報告:靜態代碼分析有助於儘早識別潛在的 bug、安全漏洞和代碼樣式不一致。TeamCity 與 JetBrains Qodana 集成,後者是一款靜態代碼分析工具,具有代碼異味檢測、複雜代碼分析以及與各種編程語言集成等功能,可以確保全面的代碼質量檢查。此外,TeamCity 可以生成代碼覆蓋率報告,指示單元測試執行了代碼的哪些部分。這有助於開發者重點關注覆蓋率較弱的區域。
- 工件生成和簽名(APK 和 AAB):成功構建和測試後,下一步涉及創建可部署工件。對於 Android 應用,這通常涉及生成已簽名的 Android Package Kits (APK) 或 Android App Bundles (AAB)。TeamCity 允許您使用構建步驟在管道內自動執行簽名流程。
- 部署到內部測試和生產環境(Google Play,Beta 渠道):CI/CD 管道可以將應用自動部署到各種環境。TeamCity 允許配置部署到內部測試平台或直接部署到 Google Play 上的生產渠道。
- 持續監控和反饋循環:可靠的 CI/CD 管道不會隨着部署而結束。TeamCity 集成了監控工具,使您能夠跟蹤應用性能、識別崩潰,以及收集用户反饋。此反饋循環使開發者能夠對問題做出快速反應,並持續提高應用質量。
使用 TeamCity 構建管道
現在,您已經瞭解一般的 CI/CD 管道結構,我們來使用 TeamCity 構建一個管道。以下各部分將指導您設置 TeamCity、創建針對您的 Android 項目量身定製的構建配置、運行集成自動化測試,以及最後配置應用的打包和部署。
為了簡單起見,本教程使用雲託管版本的 TeamCity,該版本提供 14 天的免費試用。您可以使用 GitHub、GitLab、Bitbucket 或 Google 賬號註冊,也可以使用老式的電子郵件地址和密碼組合註冊。在進入下一步之前,請務必激活試用版或訂閲。(如需進一步支持,請諮詢JetBrains授權代理-龍智)
不過,您也可以使用 TeamCity Cloud 和自託管構建代理,甚至 TeamCity On-Premises 來實現本教程的目的。請記住,使用自託管構建代理或 TeamCity On-Premises 需要您在代理上單獨安裝 Android SDK。
設置 TeamCity:
訪問 TeamCity Cloud 實例後,您看到的初始視圖將如下所示:
TeamCity Cloud 儀表板
要開始處理 Android 項目,請點擊頁面中間的 Create project…(創建項目…)。然後,系統會要求您提供項目源代碼的鏈接。如果您使用 Git 託管服務提供商(如 GitHub 或 Bitbucket Cloud)註冊,請隨時查看其相應部分,並使用專門的項目創建流程。
不過,如果您有倉庫 URL,可以直接在 From a repository URL(從倉庫 URL)標籤頁中使用。TeamCity 會自動檢測 Git 託管服務提供商,並從中拉取項目。
Create Project(創建項目)頁面
如果您手頭沒有 Android 項目,可以使用以下倉庫學習本教程:
bash
https://github.com/krharsh17/android-app-teamcity
如果您要訪問的倉庫是私有倉庫,或使用用户名和密碼組合進行了加密,您可以在此處提供相應的用户名和密碼組合,以便 TeamCity 能夠訪問該倉庫。輸入倉庫 URL(以及所需的其他詳細信息)後,點擊 Proceed(繼續)。
在下一頁上,TeamCity Cloud 將驗證與 VCS 倉庫的連接。驗證成功後,TeamCity 將拉取一些與項目相關的元數據,例如名稱、默認分支等。您可以在將這些值存儲到 TeamCity 項目之前對其進行修改。
創建項目時驗證連接
確認此頁面上的信息正確無誤後,點擊 Proceed(繼續)按鈕。然後,TeamCity 將開始根據倉庫中的可用配置文件自動檢測適用於該倉庫的任何構建步驟。由於此倉庫中具有基於 Gradle 的配置文件,TeamCity 會自動建議一組 Gradle 任務(在本例中為 clean 和 build)。
選中 Gradle 構建步驟旁邊的複選框,然後點擊 Use selected(使用所選):
選擇自動建議的構建步驟
完成後,會出現一個小橫幅,上面寫着您現在可以運行項目中的第一個構建。點擊右上角的 Run(運行)開始第一個構建:
開始您的第一個構建
點擊按鈕後,構建將加入隊列,等待構建代理變得可用。您可以點擊頂部導航窗格中的 Projects(項目),然後選擇正在運行的構建,以查看其屬性和狀態:
正在運行的構建的詳細信息
構建大約 5-6 分鐘即可完成。恭喜!您已使用 TeamCity 設置了第一個 Android CI/CD 管道。此外,由於您使用了 VCS 倉庫 URL 來設置此管道,它已被配置為以固定的時間間隔自動輪詢倉庫 URL,以查看是否有新的更改被推送到倉庫。如果發現新的更改,管道會自動拉取最新的提交,並再次運行構建。
您還可以通過設置針對特定平台的 Web 掛鈎來進一步增強此功能。例如,您剛剛設置的倉庫託管在 GitHub 上。TeamCity 允許您方便地安裝 GitHub Web 掛鈎,這樣每次倉庫有活動時,GitHub 就會自動向 TeamCity 發送通知:
安裝 GitHub Web 掛鈎
如果願意,您可以進行以上操作。不過,在本教程中並不需要這樣做。
配置構建工件:
您設置的倉庫包括兩種版本(Free 和 Paid)。這兩種版本各有兩種構建變體(debug 和 release)。這意味着 build 任務的結果將包括四個二進制文件,每種可能的版本和變體組合對應一個文件。我們來配置管道,以便在管道運行結束後提取這些工件並使其可供訪問。
為此,請點擊頂部導航窗格中的 Projects(項目),然後點擊 Android App Teamcity (Android 應用 Teamcity)下的 Build(構建),打開標題為Build(構建)的構建配置的詳細信息頁面:
導航到構建配置頁面
在這裏,點擊屏幕右上角的 Edit configuration(編輯配置)按鈕:
編輯構建配置
您可以在這裏配置構建配置的常規設置。您會注意到在列表的底部有一個標題為 Artifact paths(工件路徑)的字段。您需要在這裏定義希望在構建完成運行後提取和保留工件的路徑:
設置工件路徑
運行 Gradle build 任務時,Gradle 生成的工件會存儲在 app/build/outputs/apk 中。因此,您需要在 Artifact paths(工件路徑)下輸入以下內容:
app/build/outputs/apk/*/*/* => output
在 app/build/outputs/apk 後添加 ///* 是因為構建後生成的 APK 二進制文件的完整路徑如下所示:app/build/outputs/apk/<flavor>/<variant>/app-<flavor>-<variant>-unsigned.apk.
為了表示 <variant>、<flavor> 和二進制文件名的所有可能值,我們使用了通配符 *。
=> 是 Ant 樣式路徑的一個特徵,用於分隔輸出和輸入目錄。output 是存儲最終二進制文件的文件夾名稱。
添加完成後,點擊頁面底部的 Save(保存)按鈕。您將看到一個黃色橫幅,顯示您的更改已保存:
保存對構建配置所做的更改
現在,您可以使用頁面右上角的 Run(運行)按鈕再次嘗試運行管道,以查看構建完成後生成的工件:
查看生成的工件
現在,您已經設置一個管道,每次有提交推送到倉庫的 main 分支時,管道就會被觸發。此管道會為項目中的所有版本-變體組合生成未簽名的構建工件,運行單元測試,並使構建工件可供查看。
接下來,您將學習如何自定義測試。
查看生成的工件
現在,您已經設置一個管道,每次有提交推送到倉庫的 main 分支時,管道就會被觸發。此管道會為項目中的所有版本-變體組合生成未簽名的構建工件,運行單元測試,並使構建工件可供查看。
接下來,您將學習如何自定義測試。
導航到構建設置
這將打開 Build Steps(構建步驟)頁面,您可以在該頁面中修改此構建配置的構建步驟。點擊第一個構建步驟(標題為 Gradle)右側的 Edit(編輯):
編輯 Gradle 構建步驟
現在,您可以更新 Gradle tasks(Gradle 任務)字段,以更改將作為此構建的一部分執行的任務。將 clean build 替換為 assembleFreeRelease testFreeReleaseUnitTest:
更新 Gradle 任務
現在,點擊底部的 Save(保存)。保存更改後,點擊右上角的 Run(運行)按鈕。這將觸發此構建配置的另一次運行。
構建運行完成後,您可以在構建運行詳細信息頁面的 Tests(測試)標籤頁中查看 TeamCity 生成的報告:
查看測試結果
您可以查看每個單元測試的運行時間,以及測試完成後是否留下了任何堆棧跟蹤。您還可以點擊測試最右側的三個點,然後選擇 Show test history(顯示測試歷史記錄),將當前測試運行的性能與過去的運行進行比較:
比較測試運行歷史記錄
您可以將測試的調查指派給團隊成員,並通過 TeamCity 本身跟蹤其調查歷史記錄。如果願意,您還可以點擊測試概覽頁面上的 Download(下載)鏈接下載測試結果。
此倉庫中的測試數量很少,因此幾分鐘內就完成了構建運行。不過,在實際項目中,通常會有成百上千個單元測試。在這種情況下,在同一個運行程序代理上一個接一個地運行所有這些測試將耗費大量時間。要解決這個問題,您可以使用 TeamCity 的並行測試構建功能。
TeamCity 能夠通過將測試運行拆分到多個構建代理來並行處理,從而幫助您最大限度地減少運行所有測試所需的總時間。要進行設置,請點擊構建運行詳細信息頁面上的 Edit configuration(編輯配置)按鈕,然後點擊左側導航窗格上的 Build Features(構建功能):
導航到 Build Features(構建功能)頁面
在 Build Features(構建功能)頁面上,點擊 + Add build feature(+ 添加構建功能)按鈕。在打開的對話框中,從下拉菜單中選擇 Parallel tests(並行測試):
搜索並行測試
您需要輸入並行執行測試的最大批次數。輸入介於 4 和 8 之間的值可從並行化中獲得最大收益。
設置並行構建批次
完成後,點擊 Save(保存)按鈕。現在,您可以嘗試為具有大量測試用例的倉庫運行測試,親眼看看性能上的差異!
管理多個構建:
由於此應用有多種版本和變體,有必要利用 TeamCity 提供的矩陣構建功能,將每種變體-版本組合拆分為其自己的運行實例,從而加快管道構建速度。此外,這還允許您構建應用程序的特定組合,而不必構建所有或單個變體-版本組合。
為此,您需要創建一個新的構建配置。點擊頂部導航窗格中的 Projects(項目),然後點擊 Android App Teamcity(Android 應用 Teamcity)。在項目詳細信息頁面上,點擊右上角的 Edit project…(編輯項目…)按鈕:
導航到項目配置
在 General Settings(常規設置)頁面上,點擊 Build Configurations(構建配置)部分下方的 + Create build configuration(+ 創建構建配置)按鈕:
創建新構建配置
這將帶您進入 Create Build Configuration(創建構建配置)嚮導。在 Repository URL(倉庫 URL)字段中輸入與之前相同的倉庫 URL (https://github.com/krharsh17/android-app-teamcity),然後點擊 Proceed(繼續):
輸入倉庫 URL
將下一頁上的 Build configuration name(構建配置名稱)設置為 Matrix Builds(矩陣構建),並在所有其他字段中保留默認值。然後,點擊 Proceed(繼續)按鈕:
設置構建配置詳細信息
TeamCity 將通知您已找到類似的 VCS 根。點擊以下對話框中的 Use this(使用)按鈕:
選擇現有 VCS 根
這將確保 TeamCity 對這兩種構建配置只輪詢一次 VCS URL,以避免額外的性能開銷。
構建配置完成後,您應該會收到確認其已創建的通知:
新構建配置已創建
這一次,不需要設置 clean build Gradle 任務,因此不要勾選此頁面上的任何複選框。點擊表上方的 configure build steps manually(手動配置構建步驟)鏈接。
您將進入 New Build Step(新建構建步驟)頁面,您可以在該頁面上為構建步驟選擇首選運行程序:
選擇構建運行程序
從此列表中選擇 Gradle。在打開的下一個頁面上,在 Gradle tasks(Gradle 任務)字段中輸入 clean test%env.FLAVOR%%env.VARIANT%:
輸入 Gradle 任務
這將確保運行程序首先清理構建文件夾,然後為環境變量提供的版本和變體運行測試任務。例如,對於免費應用的 release 變體,任務將被稱為 clean testFreeRelease。
向下滾動並點擊 Save(保存)按鈕。然後,您將返回 Build Steps(構建步驟)頁面:
新構建步驟已添加
點擊 + Add build step(+ 添加構建步驟)按鈕,添加另一個 Gradle 構建步驟,任務為 assemble%env.FLAVOR%%env.VARIANT%。此步驟將為應用的給定版本和變體生成構建工件。
完成後,您的 Build Steps(構建步驟)頁面應該會列出您創建的兩個基於 Gradle 的構建步驟,以及將作為其中一部分運行的 Gradle 任務的快速摘要:
構建步驟已更新
接下來,您還需要做兩件事:定義您使用過的兩個環境變量的值,以及配置工件路徑。
您已經知道如何為構建配置設置工件路徑。對於此構建配置,將 Artifact paths(工件路徑)字段設置為 app/build/outputs/apk///* => output,與上一個配置相同。
要為版本和變體字段設置矩陣值,請點擊左側導航窗格中的 Build Features(構建功能)。在 Build Features(構建功能)頁面上,點擊 + Add build feature(+ 添加構建功能)按鈕,並在對話框的下拉菜單中搜索 Matrix Build(矩陣構建):
在 Build Features(構建功能)頁面上搜索 Matrix Build(矩陣構建)
從下拉列表中選擇 Matrix Build(矩陣構建)選項後,系統將要求您提供矩陣構建的形參及其值。提供形參名稱 env.FLAVOR,值為 Free。添加另一個形參 env.VARIANT,它的兩個值為 Release 和 Debug。
配置矩陣構建
接下來,點擊 Save(保存)按鈕。至此,此管道上的矩陣構建設置完畢。您可以點擊頁面右上角的 Run(運行)按鈕進行測試。
現在,您可以分別查看每次運行的結果,以及單獨的構建工件和測試結果。
矩陣構建結果
您可以點擊 Dependencies(依賴項)標籤頁,查看每個運行的構建運行詳細信息:
查看個別構建運行詳細信息
正如您之前看到的,您可以將每個條目作為獨立的完整構建運行來探索。
打包和部署:
Android CI/CD 管道的一個關鍵部分是向 Google Play 推送發行版二進制文件,以便向用户發佈。您也可以使用 TeamCity 和 Gradle Play Publisher (GPP) 自動執行此操作。
在開始此流程之前,有一些先決條件:
- 確保您已將 Android 項目的第一個 APK/AAB 手動上傳到 Google Play 管理中心。
- 您必須擁有有效的簽名配置。
- 您需要在 Google Cloud Platform 上創建一個服務賬號,以便能夠使用 Google Play Developer API 並檢索其 JSON 憑據文件。為此,請按照以下步驟操作,然後再進行下一步。
完成上述鏈接中的詳細步驟後,您需要在 Android 項目中安裝和配置 GPP。為此,請將以下代碼行添加到應用級 build.gradle.kts 文件中的插件塊中:
kt
id("com.github.triplet.play") version "3.9.1"
然後,在此文件的根級添加一個 play {} 塊,內容如下:
kt
play {
serviceAccountCredentials.set(file("play_config.json"))
track.set("internal")
releaseStatus.set(ReleaseStatus.DRAFT)
defaultToAppBundles.set(true)
}
這會將 GPP 配置為使用名為 play_config.json 的文件中的服務賬號憑據,在將二進制文件推送到 Play 管理中心時將軌道設置為 internal,並將發佈狀態設置為 DRAFT,並默認使用應用捆綁包代替 APK。
您的 Android 項目的必要配置步驟到此完成。在繼續之前,將這些更改提交併推送到 GitHub 倉庫。
現在,您將在 TeamCity 中創建一個新的構建配置,用於將二進制文件推送到 Google Play。按照與之前相同的步驟創建新的構建配置。將第一個構建步驟設置為使用 Gradle 作為運行程序,並將 bundleFreeRelease 作為要運行的 Gradle 任務:
構建步驟
在此構建配置中添加另一個步驟,但這次要選擇 Command Line(命令行)作為構建運行程序:
配置新的命令行構建步驟
命令行運行程序的新構建步驟頁面將會打開。您需要提供自定義腳本,用於簽署應用捆綁包並將其發佈到 Google Play。在 Custom script(自定義腳本)字段中輸入以下代碼:
# Create the keystore file from the environment variables
echo %env.ANDROID_KEYSTORE_FILE% > keystore.jks.b64
base64 -d -i keystore.jks.b64 > app/keystore.jks
# Sign the AAB using the keystore and credentials retrieved from the environment variables
jarsigner
-keystore app/keystore.jks
-storepass %env.KEYSTORE_STORE_PASSWORD%
-keypass %env.KEYSTORE_KEY_PASSWORD%
-signedjar release.aab
app/build/outputs/bundle/freeRelease/app-free-release.aab
%env.KEYSTORE_KEY_ALIAS%
# Create the GCP service account credentials file from the environment variables
echo %env.PLAY_CONFIG_JSON% > play_config.json.b64
base64 -d -i play_config.json.b64 > app/play_config.json
# Use GPP to publish the app bundle
./gradlew publishFreeBundle --artifact-dir release.aab
代碼中的內聯評論解釋了每一行的作用。完成後,點擊頁面底部的 Save(保存)按鈕:
配置您的命令行腳本
您還需要定義以下環境變量,以便為腳本提供正確的憑據來簽署和發佈應用:
bash
ANDROID_KEYSTORE_FILE
KEYSTORE_KEY_ALIAS
KEYSTORE_KEY_PASSWORD
KEYSTORE_STORE_PASSWORD
PLAY_CONFIG_JSON
點擊左側導航窗格中的 Parameters(形參),轉到可以定義這些環境變量的頁面。您會看到 TeamCity 已經在此頁面上為您填充了所需變量的列表:
查看新識別的環境變量
對於 KEYSTORE_KEY_ALIAS、KEYSTORE_KEY_PASSWORD 和 KEYSTORE_STORE_PASSWORD,請隨意點擊 Edit(編輯)並在相應的對話框中提供它們的值:
配置環境變量
對於 ANDROID_KEYSTORE_FILE 和 PLAY_CONFIG_JSON,您首先需要使用 openssl 等工具將文件轉換為 Base64,然後將 Base64 編碼的內容粘貼到這些變量的值字段中。
這將設置管道來構建和發佈應用程序的免費版本的簽名發佈版。您可以嘗試點擊頁面右上角的 Run(運行)按鈕,觸發運行並查看運行情況。
運行成功後,您將在日誌中看到 BUILD SUCCESSFUL 消息:
成功構建結果日誌
以下是您的應用的最新版本,可在Google Play 管理中心的內部軌道上查看,並隨時供您編輯和推廣:
Play 管理中心內部測試頁面
您會注意到,新版本的名稱 (“2.0”) 與上一版本面向開發者的名稱相同。這是因為沒有在 GPP 配置中指定名稱。您可以查看 GPP 文檔,瞭解如何自行完成該操作。
最佳做法和提示
現在,您可以使用 TeamCity 為 Android 設置自己的管道,以下是您可以考慮實施的一些關鍵最佳做法,以確保您的管道高效快速:
- 版本控制和版本管理做法:高效的 CI/CD 管道在很大程度上依賴於強大的版本控制系統 (VCS),如 Git。確保您的團隊堅持明確的版本管理做法,並實施一致的分支策略(如功能分支)。例如,為不同的分支開發自定義的管道,確保不會在 WIP 代碼上運行不必要的步驟。
- 明確的通過/失敗標準和閾值:明確定義什麼是成功的構建和測試運行。這可能涉及為單元測試覆蓋率設置閾值,為其他代碼檢查亮起綠燈等。您應該針對管道的每個階段為 TeamCity 配置通過/失敗標準,以確保構建的可靠性,並鼓勵開發者編寫更好的代碼。
- 利用 TeamCity 通知和警報:TeamCity 提供了詳細的通知系統,可以幫助通知用户跨 Web 瀏覽器、電子郵件、Slack 和 IDE 的管道事件。確保為構建失敗和關鍵測試失敗設置警報,以便讓開發團隊及時瞭解情況並迅速解決問題。
- 協作和反饋循環:高效的 CI/CD 管道可以促進開發團隊內部的協作。您應該在 TeamCity 中使用構建管道可視化,為開發者提供整個構建和測試流程的清晰概況。您還可以直接在 TeamCity 內使用測試和構建調查來指派調查和協作處理調查,以瞭解構建或測試失敗的原因。同時,鼓勵團隊成員審查構建失敗和代碼覆蓋率報告,以確定需要改進的地方。這有助於培養代碼質量和持續改進的文化。
- 安全措施(代碼簽名和訪問控制):確保為 TeamCity 實例配置適當的訪問控制,限制只有需要訪問信息的用户才能訪問簽名密鑰等敏感信息。您應該考慮使用類似 HashiCorp Vault 的工具來管理和輪換您在構建過程中可能使用的所有敏感憑據。
結論
在本文中,您瞭解瞭如何使用 JetBrains TeamCity 為 Android 開發項目構建和管理詳細的 CI/CD 管道。您探索了 Android CI/CD 管道從代碼遷出和版本控制集成到簽名、部署和監控等各個關鍵階段。您瞭解了 TeamCity 如何促進每個階段並簡化開發工作流。最後,您還將學習一些關鍵的最佳做法,以確保您的管道高效運行。
通過使用 TeamCity 來設置 Android 管道,您可以大大提高工作流效率。這直接帶來更快的發佈週期、更少的 bug,最終高效交付高質量的 Android 應用。因此,請邁出更簡化開發流程的第一步,立即開始構建您的 CI/CD 管道吧!
本博文英文原作者:Olga Bedrina
關於 TeamCity
TeamCity 是一款強大的持續集成和部署服務器,面向以 DevOps 為中心的團隊提供開箱即用的測試智能、構建問題的實時報告以及無與倫比的可擴展性。安裝和部署 TeamCity,幾分鐘之內即可開始構建您的 DevOps 管道。TeamCity 提供本地部署和基於雲的版本。
進一步瞭解 TeamCity,歡迎諮詢JetBrains授權代理-龍智:
官網:www.shdsd.com
電話:400-666-7732
郵箱:marketing@shdsd.com