Linux中國

如何為安卓開發搭建一個持續集成(CI)伺服器

寫這篇文章我主要想總結一下安裝步驟,好給自己以後作參考,當然,這篇文章也是給同行看的,只要他們感興趣。好了,現在開始:

  1. 配置一個新的 Ubuntu ,以便運行 Android SDK。
  2. 安裝 Jenkins CI 服務來拉取、編譯、運行測試託管在 Github 的多模塊 Android 項目。
  3. 安裝 Docker 並在容器中運行 MySQL 伺服器和 SonarQube。來運行由 Jenkins 觸發的靜態代碼分析。
  4. Android app 配置需求。

第一步-安裝 Ubuntu:

我將使用 Ubuntu 作為持續集成的 SO,因為 Ubuntu 有一個強大的社區,它可以解決你遇到的任何問題,而且我個人推薦總是使用 LTS 版本,當前是 16.04 LTS。已經有很多教程教大家在各種硬體上怎麼安裝了,我就不廢話了,貼個下載鏈接就行了。

有人可能很奇怪:用什麼桌面版,伺服器版多好。額,這個嘛,蘿蔔青菜,各有所愛。我倒不在乎 UI 佔用的那點運算資源。相反,用那一點資源換來生產力的提升我覺得挺值的。

第二步-遠程管理:

SSH 伺服器

Ubuntu 桌面版默認安裝並沒有 ssh 伺服器,所以你想遠程通過命令行管理的話就只好自己安裝。

$ sudo apt-get install openssh-server

NoMachine 遠程桌面

可能你的持續集成伺服器沒有挨著你,而是在你的路由器後面,或者其它屋子,甚至還可能遠離你數里。我試過各種遠程桌面方案,不得不說,IMHO NoMachine 在這方面表現的最好,它只需要你的 ssh 證書就可以工作了(顯然你要先把它安裝在 CI 和你的機器中)。

第三步-配置環境:

這裡我打算安裝 Java8,Git,和 Android SDK,Jenkins 需要它們來拉取、編譯和運行 android 項目。

SDKMAN!

這個超級厲害的命令行工具讓你可以安裝各種流行的 SDK(比如說,Gradle、Groovy、Grails、Kotlin、 Scala……),並可以以容易方便的方式列出它們和在各個並行版本中切換。

它們最近又增加了對 JAVA8 的支持,所以我使用它來安裝 Java,而是用流行的 webupd8 倉庫。所以在你安裝開始前,務必要想清你要不要安裝 SDKMAN,話說回來,最好還是裝上,因為我們以後應該會用到。

安裝 SDKMAN! 很容易,執行以下命令即可:

$ curl -s "https://get.sdkman.io" | bash

Oracle JAVA8

因為我們已經安裝了 SDKMAN! ,所以安裝 JAVA8 就相當簡單了:

$ sdk install java

或者使用 webupd8 這個倉庫 :

Git:

安裝git的命令也非常直觀,就不廢話了。

$ sudo apt install git

Android SDK

這下面這篇文章的底部

你可以找到 「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
$ 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"

關閉此終端,再打開一個新的終端看看環境變數是否正確生效:

$ echo $ANDROID_HOME
/opt/android-sdk-linux

然後我們啟動圖形界面的 Android SDK 管理器,並安裝你所需的平台和依賴:

$ android

運行 Android SDK Manager 的圖形交互界面

第四步-Jenkins 伺服器

這裡,我要講講怎麼安裝、配置該伺服器,並創建 Jenkin 任務來拉取、構建和測試 Android 項目,並怎樣獲取控制台輸出。

安裝 Jenkins

你可以在下面的鏈接找到 Jenkins 伺服器相關信息:

我們有許多辦法運行 Jenkins,比如說運行 .war 文件,作為 Linux 服務,作為 Docker 容器等等。

我起初是想把它當做 Docker 容器運行,但是後來我意識到正確地配置代碼文件夾、android-sdk 文件夾的可見性,和插到運行的 Android 測試機上的物理設備的 USB 可見性簡直是一場噩夢。

少操點心,我最終決定以服務的方式,增加 Stable 倉庫的 key 來通過 apt 安裝和更新。

$ wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -

編輯 source.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 你的用戶組 jenkins

Jenkins 服務在開機引導時就會被啟動,並可通過 http://localhost:8080 訪問:

安裝完畢會有一些安全預警信息,跟著引導程序走,你的 Jenkins 就會運行了。

啟用安裝成功的 Jenkins 伺服器。

Jenkins 配置

啟用成功後,會有提示程序提示你安裝插件,單擊 「Select plugins to Install」 就可以開始瀏覽所有插件,然後選擇你要安裝的插件就 OK 了 。

安裝 Jenkins 插件

創建管理員用戶,並完成安裝。

要完成安全需要配置環境變數 ANDROID_HOMEJAVA_HOME

點擊 Manage Jenkins,接著 Configure System。

滾動文件至底部,在全局屬性模塊中找到環境變數,並增加 ANDROID_HOMOE,和 JAVA_HOME 變數。

給所有 Jenkins 任務增加全局變數

創建 Jenkins 任務

一個 Jenkins 任務定義了一系列不間斷的操作。如果你跟隨本篇引導的話,那麼你可以使用我已經在 GitHub 上為你準備了一個 Android 練習項目,你可以使用這個來試試手。它只是一個多模塊的 app,帶有單元測試、Android 測試,包括 JaCoCo、SonarQube 插件。

首先創建一個新的 Freestyle 任務項目,取名為 Hello_Android。不要在名字中使用空格,這樣可以避免與 SonarQube 不兼容的問題。

創建一個 Freestyle Jenkins 任務

接下來就是配置了,我給每一部分都做了截屏。

概況

這部分比較繁瑣,你可以在這裡變更任務的名字、增加簡介。如果你使用 GitHub 項目,你還可以寫下項目的 URL(不要 *.git,這是 url 的部分,不是倉庫的)。

項目 Url 配置

源代碼管理

這時候我們就要選擇我們的 CVS 作為 Git,並且增加倉庫的 url(這次就要包括 *.git)然後選擇分支拉取。因為這是一個公開的 GitHub 倉庫,我們就不需要提交證書了,否則的話就要設置賬號和密碼。

相比於使用你的帶有完全許可權的公開倉庫,我更傾向於為你的私有庫創建一個新的只讀用戶來專門配給 Jenkins 任務使用。

另外,如果你已經使用了雙因子認證,Jenkins 就無法拉取代碼,所以為 Jenkins 專門創建一個用戶可以直接從私有庫中拉取代碼。

配置倉庫

構建觸發器

你可以手動開始構建,也可以遠程地、周期性地、或者在另一個任務構建完成之後開始構建,只要這些改變可以被檢測到。

最好的情況肯定是一旦你更改了某些地方,就會立刻觸發構建事件,Github 為此提供了一個名叫 webhooks 的系統。

這樣,我們就可以配置來發送這些事件到 CI 伺服器,然後觸發構建。顯然,我們的 CI 伺服器必須要聯網,並且可以與 GitHub 伺服器通信。

你的 CI 伺服器也許為了安全只限於內網使用,那麼解決辦法就只有集中周期性的提交。我就是只有工作時才打開 CI,我把它設置為每十五分鐘輪詢一次。輪詢時間可以通過 CRON 語法設置,如果你不熟悉,請點擊右側的幫助按鈕獲取帶有例子的豐富文檔。

倉庫輪詢配置

構建環境

這裡我推薦設置構建超時來避免 Jenkings 佔用內存和 CPU ,畢竟有時候有意外發生。當然,你還可以插入環境變數和密碼等等。

構建超時

構建

現在是見證魔法的時刻了,增加一個 Build 步驟,引入 Gradle 腳本,選擇 Gradle Wrapper (默認情況下,Android 項目帶有 Gradle Wrapper,不要忘記把它檢入到 Git ),然後定義你要執行哪些任務:

  1. clean:清除之前構建的所有歷史輸出,這樣可以確保沒有東西緩存,從頭構建。
  2. asseembleDebug: 生成調試 .apk 文件。
  3. test:在所有模塊上執行 JUnit 測試。
  4. connectedDebugAndroidTest:在連接到 CI 的實體機上執行安卓測試單元(也可以使用安裝了安卓模擬器的 Jenkins 插件,但是它不支持所有型號,而且相當麻煩)。

配置 Gradle

構建後操作

我們將要增加「發布 JUnit 測試報告」,這一步由 JUnit 插件提供,其搜集由 JUnit 測試結果生成的 XML 文件,它會生成漂亮的圖表來按時間展示測試結果。

我們 app 模塊中,測試運行結果的路徑是: app/build/test-results/debug/*.xml

在多模塊項目中,其它的「純」 Java 模塊中測試結果在這裡:*/build/test-results/*.xml

還要增加「記錄 JaCoCo 覆蓋率報告」,它要創建一張顯示代碼覆蓋率的圖表。

運行 Jenkins 任務

只要有任何改變提交到倉庫,我們的測試任務將每十五分鐘執行一次,但是如果你不想等的話,或者你只是想驗證一下配置的改變,你也可以手動運行。單擊「現在構建」按鈕,當前的構建將出現在構建歷史中,點擊它可以查看細節。

手動執行任務

最有趣的部分是控制台輸出,你可以看到 Jenkins 是如何拉取代碼並執行我們之前定義的 Gradle 項目,例如 clean。

控制台輸出的開始部分

如果一切都正常的話,控制台將會有如下輸出 (任何倉庫連接問題,單元測試或 Android 測試的失敗都將導致構建失敗)。

哈哈哈哈,構建成功,測試結果符合預期

第五步-SonarQube

這部分我會講講如何安裝、配置 SonarQube ,並配以使用 Docker 作為容器的 MySQL 資料庫。

SonarQube 是個代碼靜態分析工具,它可以幫助開發者寫出乾淨的代碼、檢測錯誤和學習最佳體驗。它還可以跟蹤代碼覆蓋、測試結果、功能需求等等。SonarQube 檢測到的問題可以使用插件十分容易的導入到 Android Studion/IntelliJ 中去。

安裝 Docker

安裝 Docker 十分容易,按照下面的教程即可:

生成容器

MySQL

我們先搭建一個 MySQL5.7.17 伺服器容器,命名為 mysqlserver,它將在開機引導時啟動,帶有一個在你的家目錄下的本地卷,帶有密碼,服務暴露在 localhost:3306 上(把命令中的 YOUR_USERYOUR_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.17

phpMyAdmin

想要優雅簡單地管理 MySQL伺服器,我強烈推薦 phpMyAdmin。你只要建立個容器,命名為 phpmyadmin,然後鏈接到我們的 mysqlserver 容器,它會在開機引導時啟動,它暴露在 localhost:9090。使用最新的版本。

$ docker run --name phpmyadmin --restart=always --link mysqlserver:db -p 9090:80 -d phpmyadmin/phpmyadmin

你可以用你的 mysql 密碼 YOUR_MYSQL_PASSWORD ,以 root 身份登錄 localhost:9090 的 phpMyAdmin 界面,並創建一個資料庫 sonar,使用uft8_general_ci 字符集。此外,也創建一個 sonar 的新用戶,密碼 YOUR_SONAR_PASSWORD,並給它 sonar 資料庫的許可權。

SonarQube

現在我們已經創建好了我們的 SonarQube 容器,就叫 sonarqube,它會在機器引導時啟動,自動鏈接搭配我們的資料庫,服務暴露在 localhost:9090,使用 5.6.4 版本。

$ 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.4

配置 SonarQube

如果一起都正常,你將在 localhost:9000 看到如下頁面:

好了,讓我們來配置必要的插件和基本的配置文件:

  1. 在頁面的右上角可以登錄(默認的管理員賬號和密碼是 admin/admin)。
  2. 進入到 Administration,然後點擊 System,接下來是 Updata Center,最後是 Updates Only。
    • 如果需要的話,更新 Java 插件。
  3. 現在啟用,並安裝以下插件
    • Android (提供 Android lint 規則)
    • Checkstyle
    • Findbugs
    • XML
  4. 返回頂部,點擊重啟按鈕完成整個安裝。

SonarQube 配置文件

我們剛剛安裝的插件可以定義配置文件,可以用一套規則去衡量項目的代碼質量。

同一時間一個項目只能使用一個配置文件。但是我們可以定義父配置文件並繼承規則,所以要對我們的項目執行所有的規則,我們可以創建定製的配置文件並鏈狀串聯所有配置文件。

就這麼干,點擊 Quality Profiles ,跳轉到 Create ,然後命名,比如 CustomAndroidProfile。

將 Android Lint 作為父級,然後選擇 Android Lint 配置,增加 FindBugs Security Minial 作為上一級,繼續此步驟,直到你完成父級繼承方案,並且設置 CustomAndroidProfile 作為默認。

繼承鏈

運行 Sonarqube 分析器

現在我們的 SonarQube 已經正式配置完畢,我們需要添加一個 Gradle 任務 sonarqube 到我們的 Jenkins 任務。我們在最後執行。

再次運行 Jenkins 任務,一旦運行完畢,我們可以在 localhost:9090 中看到我們的 sonarQube 控制面板。

分析結果的顯示

點擊項目名稱我們可以進入到不同的顯示界面,最重要的可能就是問題界面了。

在下一屏,我將展示一個主要問題,它是一個空構造器方法。就我個人而言,使用 SonarQube 最大的好處就是當我點擊「...」時可以在屏幕底部顯示解釋。這是一個學習編程十分有用的技能。

第六步 附加:配置其他 Android 應用

想要配置 Android 應用得到覆蓋率和 sonarqube 的結果,只要安裝 JaCoCo 和 Sonarqube 插件就可以了。你也可以在我的示例中得到更多信息

你也可以看看我在雲上測試的文章:

最後

啊,你終於走到頭了,希望你覺得本文有點用處。你要是發現了任何錯誤,有任何疑問,別遲疑,趕緊評論。我拼了老命也要幫你。哦,忘了提醒,好東西要和朋友分享。

作者簡介:

Entrepreneur & CEO at GreenLionSoft · Android Lead @MadridMBC & @Shoptimix · Android, OpenSource and OpenData promoter · Runner · Traveller

via: https://medium.com/@pamartineza/how-to-set-up-a-continuous-integration-server-for-android-development-ubuntu-jenkins-sonarqube-43c1ed6b08d3#.x6jhcpg98

作者:Pablo A. Martínez 譯者:Taylor1024 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國