如何搭建安卓开发持续化集成环境(Ubuntu + Jenkins + SonarQube)
我最近換了一臺新的 MacBook Pro 作為我的 Android 開發機。舊的 Mac BookPro (13英寸,2011款,16GB 內存,500G SSD,i5 內核 2.4GHz,64位)我并沒有賣掉或丟掉,而是裝了 MacOS-Ubuntu 雙系統作為持續化集成環境服務器。
本文目標是總結安裝步驟,以便廣大開發者朋友和我自己將來在搭建自己的 CI 時參考,主要內容如下:
-
在全新的 Ubuntu 環境下安裝 Android SDK。
-
搭建 Jenkins CI 服務,在其基礎上從 GitHub 上獲取代碼、編譯一個多模塊的 Android 項目,并對其進行測試。
-
安裝 Docker 容器,并在其上安裝 MySQL 服務和 SonarQube,以實現 Jenkins 觸發的靜態代碼分析。
-
Android App 配置需求。
第 1 步 —— 安裝 Ubuntu:
我之所以選擇 Ubuntu 作為 CI 的操作系統,是因為它有著強大的社區,方便對可能遇到的問題尋求幫助,我個人建議使用最新的 LTS 版本,目前是 16.04 LTS。因為有許多 Ubuntu 安裝教程(虛擬機和真機),所以這里我只提供下載鏈接。
安裝 Ubuntu 16.04 LTS 桌面版
你可能會對我選擇桌面版而不是選擇服務器版而感到疑惑,這只是個人的偏好,我并不介意因為有界面交互而帶來的性能和可用內存的少量損失,因為我認為 GUI 對提高工作效率的幫助大過消耗。
第 2 步 —— 遠程訪問管理:
SSH服務:
Ubuntu 桌面版默認并沒有安裝 ssh 服務,因此如果需要遠程管理你的服務器還需要手動安裝,安裝命令如下:
$ sudo apt-get install openssh-serverNoMachine 遠程桌面:
可能你的 CI 沒在你眼前而是在你的路由器附近、別的屋子甚至幾公里外的地方。我使用過多種遠程桌面程序,IMHO NOMachine 是最好的一款,它平臺無關并且僅僅需要你的 ssh 憑證。(當然 CI 服務器和你的本機都需要進行安裝)
NoMachine - 對任何人都免費
第 3 步 —— 環境配置
下面我將安裝 Jenkins pull 代碼、編譯運行 android 項目所依賴工具,包括 JAVA8,Git,和 Android SDK。
SDKMAN!:
SDKMAN! 是一個非常酷的命令行工具,它支持主流的 SDK(例如:Gradle, Groovy, Grails, Kotlin, Scala 等),它可以提供可用列表供我們選擇并可以方便地在不同版本之間進行切換。
SDKMAN! 軟件開發工具管理器
SDKMAN! 最近支持了 JAVA8,所以我選擇使用它而不是主流的 webupd8 庫來安裝 JAVA 環境,當對你而言用不用 SDKMAN! 都可以,不過我認為將來你一定會用。
安裝 SDKMAN! 只需要執行下面的命令:
$ curl -s "https://get.sdkman.io" | bashOracle JAVA8:
如果前面已經安裝了 SDKMAN! ,安裝 JAVA8 只需要簡單的執行下面的命令:
$ sdk install java或者使用 webupd8 庫進行安裝:
Ubuntu 或 Linux Mint 通過 PPA 庫安裝 Java 8 [JDK8]
Git:
安裝 git 非常簡單,不需要多說:
$ sudo apt install gitAndroid SDK:
在本頁的底部:
下載 Android Studio 和 SDK 工具 | Android Studio
你可以看到 “Get just the command line tools”,復制像下面的鏈接:
https://dl.google.com/android/repository/tools_r25.2.3-linux.zip
然后下載并解壓到 /opt/android-sdk-linux
$ cd /opt $ sudo wget [https://dl.google.com/android/repository/tools_r25.2.3-linux.zip](https://dl.google.com/android/repository/tools_r25.2.3-linux.zip) $ sudo unzip tools_r25.2.3-linux.zip -d android-sdk-linux因為我們是使用 root 用戶創建的目錄,我們需要修改目錄權限允許主用戶對其讀和寫:
$ sudo chown -R YOUR_USERNAME:YOUR_USERNAME android-sdk-linux/接下來修改 /.bashrc 來配置 SDK 環境變量:
$ cd $ nano .bashrc在文件的底部(SDKMAN! 配置之前)添加如下內容:
export ANDROID_HOME="/opt/android-sdk-linux" export PATH="$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH"關掉終端并重新打開一個,以確認環境變量配置正確(譯者注:不關閉,執行 source ~/.bashrc 也可以)
$ echo $ANDROID_HOME /opt/android-sdk-linux接著打開 Android SDK Manager 的窗口程序,安裝你需要的平臺版本以及依賴
$ androidAndroid SDK Manager 界面
第 4 步 —— Jenkins 服務:
接下來我將描述 Jenkins 的安裝與配置,并創建一個 Jenkins 任務來拉取 Android 項目代碼并對其進行編譯和測試,以及查看控制臺輸出。
Jenkins 安裝:
Jenkins 可以從官網獲得:
Jenkins
有多方式可以運行?Jenkins,例如運行一個?.war?文件,作為一個 linux?服務, 作為一個 Docker?容器?等。
我的第一反應是使用 Docker 容器的方式安裝,但我發現那簡直是個噩夢,因為我需要配置代碼目錄、android-sdk 目錄的可見性,以及運行 Android 測試的物理可插拔設備 USB 的可見性。
為了方便使用,我最終選擇將它作為服務使用,通過?apt?來安裝、更新穩定的版本
$ wget -q -O - [https://pkg.jenkins.io/debian-stable/jenkins.io.key](https://pkg.jenkins.io/debian-stable/jenkins.io.key)| sudo apt-key add -修改 sources.list 文件
$ sudo nano /etc/apt/sources.list添加如下內容
#Jenkin Stable deb https://pkg.jenkins.io/debian-stable binary/然后安裝
sudo apt-get update sudo apt-get install jenkins將?jenkins?用戶添加到你的用戶組,確保其對 Android SDK 目錄有讀寫權限
$ sudo usermod -a -G YOUR_USERNAME jenkinsJenkins 服務會在開機的時候自啟動,可以通過?http://localhost:8080?進行訪問
為了安全起見,剛剛裝完顯示的是如下的頁面,只需要跟著說明就可以完成 Jenkins 的啟動了。
解鎖成功安裝的 Jenkins 服務
Jenkins 配置:
Jenkins 解鎖后需要安裝插件,點擊 “Select plugins to Install” 瀏覽、選擇如下建議的插件,然后進行安裝
- JUnit
JUnit Plugin - Jenkins - Jenkins Wiki
- JaCoCo
JaCoCo Plugin - Jenkins - Jenkins Wiki
- EnvInject
EnvInject Plugin - Jenkins - Jenkins Wiki
- GitHub plugins
GitHub Plugin - Jenkins - Jenkins Wiki
安裝 Jenkins 插件
創建 admin 完成安裝。
在配置完成之前,我們還要配置 ANDROID_HOME 和 JAVA_HOME:
點擊進入 Manage Jenkins > Configure 頁面
滾動到?Global properties?部分,勾選?Environment variables?選項,將?ANDROID_HOME?和?JAVA_HOME?填好
添加全局的環境變量
創建 “Jenkins 任務”
Jenkins 任務由一系列連續執行的步驟組成。我在 GitHub 上準備了一個 “Hello Jenkins” 的 Android 工程,如果你是跟著本教程做的,你可以用來測試你的Jenkins配置。這只是一個簡單的多模塊 app,包括單元測試、Android 測試 以及 JaCoCo 和 SonarQube 插件。
pamartineza/helloJenkins
首先新建一個?自由風格工程項目?并取個名字例如 “Hello_Android” (Jenkins 任務名不要有空格,避免將來與 SonarQube 的兼容性問題)
創建自由風格的 Jenkins 任務
下面讓我們一起進行配置,我會對每個部分截圖
General:
該部分和我們最終的目標關系不大,在這你可以修改任務名,添加描述,如果使用的是 GitHub 項目可以添加項目的 URL,(不要帶 *.git, 這個 url 項目的 url 不是 repo)
項目 Url 配置
源代碼管理:
這里我們需要選擇 Git 作為 CVS 選項,并且填寫代碼庫地址(需要包含 *.git)并選擇要獲取的分支。這是一個公開的 GitHub 倉庫,因此不需要添加憑證,否則需要填寫你的用戶名和密碼。
我建議你重新創建一個只有你私有倉庫只讀權限 GitHub 賬戶 供你的 Jenkins 使用,而不是直接使用你的真實 GitHub 賬戶。
此外如果你開啟了雙重身份驗證 Jenkins 將不能獲取代碼,這時為 Jenkins 單獨創建賬戶是能夠正常獲取私有倉庫代碼的方法。
倉庫配置
構建觸發器:
構建可以被以下方式觸發:手動的、遠程的、周期性的、另一個任務構建、檢測到變更時等等。
理想的最好的情景是,當新的變更推送到倉庫是觸發構建,GitHub 提供了一個叫 Webhooks的系統
Webhooks | GitHub Developer Guide
我們可以配置 Webhooks 發送事件到 CI 服務觸發構建,但是這需要我們的 CI 服務器對 GitHub 在線并可以通過 GitHub 訪問。
可能處于安全考慮你的 CI 是放在私有網絡里的,這時唯一的解決方案就是周期性的查詢 GitHub。就我個人而言,我一工作就會打開 CI,在下面的截圖中我配置的是每 15 分鐘查詢一次 GitHub。查詢的頻次與?CRON?語法一樣,如果你對其不熟悉,可以點擊右面的幫助按鈕獲得幫助文檔。
任務配置
構建環境:
我推薦配置構建的?stuck?超時時間,避免 Jenkins 當意外錯誤發生時阻塞占用內存和 CPU。這里也可以配置環境變量和賬號密碼等。
錯誤構建超時
構建:
這里是最神奇的地方!添加一個?構建步驟?選擇?執行 Gradle 腳本?選擇 Gradle Wrapper (Android 項目默認情況下都包含 Gradle Wrapper,不要忘記將其添加到 Git)并且配置需要執行的任務:
clean:?刪除所有之前構建產生的輸出,確保本次構建沒有任何緩存。
assembleDebug:?生成 debug .apk
test:?對所有模塊執行單元測試
connectedDebugAndroidTest:?在連接到 CI 的真機上執行 Android 測試。(通過安裝 Android Emulator Jenkins 插件也可以在 Android 模擬器上運行 Android 測試,但是并不支持所有版本的模擬器,并且配置非?,嵥?#xff09;
Gradle 任務配置
構建后操作
這部分我們添加?發布 JUnit 測試結果報告,本步驟由 JUnit 插件提供,收集 JUnit 測試產生的 .XML 報告,并生成測試結果圖表報告。
該部分對 debug 包來說測試結果的路徑是:
app/build/test-results/debug/*.xml
在多模塊工程中,“純” Java 模塊的測試結果路徑是:
/build/test-results/*.xml
同時添加?Record JaCoCo coverage report?以生成展示代碼變更進程的圖標
運行 Jenkins 任務
如果有新的任務推送到倉庫,上面的任務會每個 15 分鐘運行一次;如果不想等下次自動運行而是想立即看到修改,也可以手動觸發。點擊?立即構建?之后當前的構建會出現在?構建歷史?中,點擊它可以查看詳情。
手動執行任務
最有趣的部分是控制臺輸出,可以看到 Jenkins 是如何獲取代碼并且如何執行前面配置的 Gradle 任務(例如?clean.)。
控制臺輸出的開頭
如果所有任務都成功執行控制臺輸出會如下圖(倉庫連接錯誤、單元測試問題或者 Android 測試問題都會導致構建失敗)
構建成功和測試結果收集
第 5 步 —— SonarQube
這部分我將介紹使用 Docker 容器安裝配置 SonarQube 和它的伴侶 MySQL數據庫。
Continuous Code Quality | SonarQube
SonarQube 是一個靜態代碼分析工具,它可以幫助開發者編寫干凈的代碼、發現 bug、學習好的經驗,并且可以跟蹤代碼覆蓋、測試結果、技術債務等。所有 SonarQube 檢測到的問題都可以導入到安裝了插件的 Android Studio/IntelliJ 中,并修復。
JetBrains Plugin Repository :: SonarQube Community Plugin
安裝 Docker:
按照 Docker 官方文檔進行安裝非常的簡單:
Install Docker on Ubuntu?在 Ubuntu 上安裝 Docker
創建容器:
MySQL:
下面我們創建 MySQL 5.7.17 叫做?mysqlserver?的服務容器,配置如下:自啟動、安裝到你自己的目錄下、配置密碼、以及端口 3306?( YOUR_USER 和 YOUR_MYSQL_PASSWORD 用真實值替換)
$ docker run --name mysqlserver --restart=always -v /home/YOUR_USER/mysqlVolume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=YOUR_MYSQL_PASSWORD -p 3306:3306 -d mysql:5.7.17phpMyAdmin:
我使用 phpMyAdmin 管理 MySQL 服務,當然最簡單的方法就是創建一個叫做?phpmyadmin?的容器關聯到?mysqlserver,配置如下:自啟動、端口 9090、使用最新的版本
$ docker run --name phpmyadmin --restart=always --link mysqlserver:db -p 9090:80 -d phpmyadmin/phpmyadmin通過訪問 localhost:9090?使用 phpMyAdmin, 使用?root?賬戶登錄,并創建?sonar?數據庫,字符集設為?utf8_general_ci。新建一個?sonar?用戶并授權?sonar?數據庫的全部權限
SonarQube:
下面我們開始創建 SonarQube 容器,取名?sonarqube?配置如下:自啟動、關聯到剛剛配置的 db,端口 9000,使用 5.6.4(LTS)版。
$ docker run --name sonarqube --restart=always --link mysqlserver:db -p 9000:9000 -p 9092:9092 -e "SONARQUBE_JDBC_URL=jdbc:mysql://db:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance" -e "SONARQUBE_JDBC_USER=sonar" -e "SONARQUBE_JDBC_PASSWORD=YOUR_SONAR_PASSWORD" -d sonarqube:5.6.4SonarQube 配置:
如果一切 OK,訪問 localhost:9000 將會看到下圖:
下面安裝必要的插件和 Quality Profiles
右上角登錄(默認的管理員賬號是 admin/admin)
點擊 Administration > System > Update Center >?Updates Only
- 如果需要請更新?Java?插件
-
Android?(提供 Android lint 規則)
-
Checkstyle
-
Findbugs
-
XML
SonarQube 配置:
我們已經安裝的插件定義了一系列用來評估代碼質量的規則。
一個項目只能應用一個配置,但是我們為一個配置指定父配置來繼承它,所以我們可以新建一個自定義配置將所有配置串起來,來評價項目。
點擊 Quality Profiles > Create 并取個名字(例如?CustomAndroidProfile)
添加 Android Lint 作為父配置,然后切換到?Android Lint?并將?FindBugs Security Minimal?設為父配置,繼續設置直到將所有配置串聯起來,最后將?CustomAndroidProfile?設為默認配置
繼承鏈
運行 SonarQube 分析:
現在 SonarQube 已經配置好,接下來只需要添加 Gradle 任務,?sonarqube,并在 Jenkins任務的最后一步執行:
添加 sonarqube gradle 任務
再運行一次 Jenkins 任務,任務成功完成后在 localhost:9000 可以看到:
分析結果頁面
我們可以通過點擊工程名來切換儀表盤,這里面包含了很多內容,其中最重要的是 Issues 部分。
下面的截圖顯示的是一個被標記為空構造方法的?major?問題。對我個人而言,使用 Sonarqube 最大價值是當你點擊 period … 后,屏幕下方顯示的非常寶貴的學習編程經驗和技巧。
獲得問題的說明
第 6 步 —— 其它:配置其它 Android 應用
配置一個 Android 應用獲得覆蓋統計和 sonarqube 結果,只需要使用 JsCoCo 和 SonarQube 插件就可以了??梢栽谖业?demo 應用?HelloJenkins?中找到詳細的配置:
pamartineza/helloJenkins
The end!
本文到了該結束的時候!希望能對您有所幫助。如果您發現任何問題或有所疑問不吝賜教,我會盡最大努力幫助您。如果您喜歡本文,麻煩分享一下。
原文發布時間為:2017年2月8日
本文來自云棲社區合作伙伴掘金,了解相關信息可以關注掘金網站。
總結
以上是生活随笔為你收集整理的如何搭建安卓开发持续化集成环境(Ubuntu + Jenkins + SonarQube)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安全牛学习笔记】拒绝服务***工具
- 下一篇: 就是好骑!骑ofo小黄蜂和舒畅早晨say