架設Jenkins伺服器自動建置Android apk檔

在Android開發的過程難免我們會需要在寫完一定的功能之後,就將目前完成的內容打包成apk交付給其他的人員安裝測試,所以應該是會滿常會遇到:Android build了測試的apk之後,每次都要改版本號,然後再上傳到dropbox空間,然後再發信通知測試人員。

但其實這些機械化的動作,可以交給Jenkins去處理就好。所以最近也就開始研究Jenkins的架設,這篇整理介紹的內容能夠達成以下幾項任務:

A.架設Jenkins Server
B.自動從Git抓取程式碼
C.自動將Android的code build成apk檔案(並且檔名自動加上Jenkins Build Number)
D.自動將apk上傳至Dropbox
E.自動發信通知測試人員


一、架設Jenkins Server
1.到Jenkins官網下載war檔之後,使用Terminal輸入指令來啟動服務
java -jar jenkins.war


2.開啟瀏覽器,在網址列輸入: localhost:8080

3.輸入預設的管理密碼
這個時候會出現要你輸入啟動安裝的管理者密碼,畫面上會提示放置密碼的位置,通常都是放在使用者資料夾下的.jenkins/screts目錄下的initialAdminPassword檔案裡

所以可以直接用vi去打開來看(關閉vi時,輸入冒號、按q再按Enter的指令),或是直接用文字編輯軟體打開該檔案就能夠看到裡面寫的一長串的文字密碼

4.安裝外掛(plug-in)
接下來會要求安裝一些外掛,在這個階段可以先選擇建議的外掛選項就好,日後也都還可以進到Jenkins後台新增移除外掛

正在開始下載並安裝外掛

5.設定管理者帳號密碼

6.Jenkins已架設完成

二、Jenkins後台設定
1.管理外掛程式
透過這項功能可以將外掛程式新增/刪除/更新。進入的路徑:
①管理Jenkins
②管理外掛程式

進入管理外掛程式的頁面之後:
①選擇「可用的」分頁
②透過「過濾條件」快速找到想要安裝的外掛,然後勾選下列的外掛程式
Android Emulator PluginAndroid Lint PluginGradle pluginEmail Extension PluginPublish Over Dropbox
③按下「直接安裝」

2.Manage Credentials
透過這項功能可以管理憑證。進入的路徑:
①管理Jenkins
②Manage Credentials

SSH Username with private key
如果有使用SSH key,就要把private key寫進來。記得copy private key的時候要把內容完整複製,連同「-----BEGIN RSA PRIVATE KEY-----」與「-----END RSA PRIVATE KEY-----」也要貼進來。
Dropbox API token: 加入Dropbox的Token
①按下generated連結取得Dropbox的Token
②填入從Dropbox取得的Token
③在「Description」填入這項設定的名稱
④按下「存檔」

授權Jenkins使用Dropbox,按下「允許」。

按下允許之後就會取得Token

3.Global Tool Configuration
進入的路徑:「管理Jenkins/Global Tool Configuration」



  • 設定JDK

    • 名稱:<自訂名稱>。例如:jdk1.8.0_25
    • JAVA_HOME:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/



  • 設定Git

    • Name:<自訂名稱>。例如:Default
    • Path to Git executable:/usr/bin/git

    4.設定系統
    進入的路徑:「管理Jenkins/設定系統」



  • 全域屬性

    • 環境變數(勾選)
    • key: ANDROID_HOME
    • value: 。例如:/Users/ukyo/Documents/android_develop/SDK (不可以寫成~/Documents/android_develop/SDK)

    • key: DEFAULT_RECIPIENTS
    • value: <預設通知信收件人名單>。例如:abc@gamil.com,def@gmail.com,ghi@gmail.com (以逗號分隔)




  • 電子郵件通知(擴充電子郵件通知)

    • SMTP伺服器: <輸入伺服器位址>。例如:smtp.gmail.com
    • 使用SMTP驗證(勾選)
    • 使用者名稱:<輸入寄信mail的登入帳號>
    • 密碼<輸入寄信mail的登入密碼>
    • 使用SSL(勾選)
    • SMTP連接埠:465
    • 回信信箱:<輸入當使用者回信會寄到的email>
    • 字元集: UTF-8



  • Dropbox

    • Name:<自訂名稱>。由於可以加入多組Dropbox的設定,透過不同的 Dropbox名稱可以在別的設定頁選項切換不同的Dropbox。
    • Dropbox account:<下拉選擇一組在Manage Credentials加入的Dropbox API token的設定內容>。
    • Remote Directory:<輸入要上傳放置檔案的Dropbox目錄路徑>。



  • Android

    • Android SDK root:<輸入Android SDK放置的根目錄>。由於上面有寫到設定的全域變數-ANDROID_HOME,所以可以直接使用就好,例如: ${ANDROID_HOME}

    三、建立專案
    進入的路徑:「首頁/新增作業」

    ①Enter an item name:<輸入要新增的專案名稱>。例如:Android-app-每日報-debug
    ②建置Free-Style軟體專案。
    ③按下OK.

    專案設定
    第一次建立專案的時候會自動進入專案設定頁,而日後如果要自行進入專案設定頁可以從:
    ①在Jenkins首頁(dashboard)將滑鼠移到專案名稱右邊時按下出現的下拉選單按鈕
    ②按下「組態」


    Jenkins的專案設定主要分成「原始碼管理」、「建置」以及「建置後動作」...等幾個大項目,意思是要先取得程式原始碼,然後進行build code,而在build完code之後要再執行什麼動作。

    於是設定的內容就是在這三大項目再「新增」子項目功能,假設想要在Build完code之後執行:1.將apk檔案上傳至Dropbox,2.再寄信通知結果,就必須在「建置後動作」分別新增「Send build artifacts over Dropbox」及「可編式電子郵件通知」。

    原始碼管理
    選擇「Git/Repositories」
      ①Repositories URL: <輸入Repository URL>
      ②Credentials: 選擇一把在Manage Credentials時所設定好的key
      ③Branches to build: 預設是「*/master」。也可以改成專門用來Debug的branch,例如像是develop,就可以寫成「*/develop」

    建置

    Invoke Gradle script
      ①選擇Use Gradle Wrapper
      ②Make gradlew executable(勾選)
      ③Tasks:<填入要Gradle執行的語法>,例如:assembleDebug(執行build debug),就跟在terminal輸入「./gradlew assembleDebug」一樣
      ④Build File:<填入要使用的Gradle檔案>,如果要使用Android Studio專案裡的gradle可以直接輸入:app/build.gradle

    建置後動作

    Send build artifacts over Dropbox
      ①使用Dropbox之前先新增帳戶(Add Account),然後再填入該帳戶所屬的資料:
      ②Name:<選擇一個要建置的專案名稱>
      ③Transfer Set/Source files:<選擇要上傳的檔案位址>。檔案位址支援萬用字元*,例如:app/build/outputs/apk/每日報_ver_*debug.apk
      ④Transfer Set/Remove prefix:<刪除檔案的前綴路徑>。如果沒有刪除檔案的前綴路徑,就會在Dropbox的上傳根目錄建立了相同的路徑資料夾與檔案,以本例來看可以輸入:app/build/outputs/apk/


    可編式電子郵件通知
    • 專案收件人清單: <填入收件人名單>。預設已經填入收件人名單的變數($DEFAULT_RECIPIENTS),不使用該變數只要刪除這個欄位即可,如果要自訂收件人的eamil,即要在不同的email之間以逗號隔開。
    • 預設主旨:<填入預設的信件標題>。預設已經有預設主旨變數($DEFAULT_RECIPIENTS),不使用該變數只要刪除這個欄位即可,也可以自行填入文字內容。
    • 附上建置紀錄:<下拉選擇是否是附上建置紀錄>。如果是給非技術人員看的信件,可以選擇「Do Not Attach Build Log」
    • 附件:<寫下要夾帶的檔案路徑>。如果要使用Dropbox上傳檔案,這個項目可以不用填。

    • Triggers:觸發寄信的條件。如果沒有設定這個項目,會發現就算build成功了,但卻怎麼都沒有收到信,所以通常至少會設定「Failure - Any」以及「Success」兩項觸發的條件。而在每個觸發條件裡也要設定收件者的群組名單,不然也一樣會收不到信件,而出現下列的錯誤訊息:

      An attempt to send an e-mail to empty list of recipients, ignored.


    四、關於Gradle語法的小技巧

    1.apk檔名自動加上Jenkins的build number
    def getJenkinsBuildNumber() {
      def number = System.getenv("BUILD_NUMBER") as Integer ?: 0
       return number
    }
    
    android {
        compileSdkVersion 23
        buildToolsVersion '23.0.3'
        defaultConfig {
            applicationId "com.test.app"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0.0"
    
            project.ext.set("archivesBaseName", "MYAPP_ver_" + versionName + "-" + getJenkinsBuildNumber())
    
        }
    
    如此便可以在本地端build code的時候,生成的apk檔名為:MYAPP_ver_1.0.0-0.apk
    如果在Jenkins上build code的時候,生成的apk檔名為:MYAPP_ver_1.0.0-BuildNumber.apk

    2. build apk自動將key包進來
       signingConfigs {
            release {
                storeFile file("...../release.keystore") //存放key的路徑
                storePassword "<輸入這把key的password>"
                keyAlias "<輸入這把key的alias>"
                keyPassword "<輸入這把key的password>"
            }
    
            debug {
                storeFile file("....../debug.keystore") //存放key的路徑
                storePassword "<輸入這把key的password>"
                keyAlias "<輸入這把key的alias>"
                keyPassword "<輸入這把key的password>"
            }
        }
    
        buildTypes {
            release {
                
                signingConfig signingConfigs.release
            }
            debug {
                
                signingConfig signingConfigs.debug
            }
    
        }
    

    五、執行建置
    回到Dashboard按下建置,就會自動執行上述的「自動下載程式碼、打包成apk檔案、上傳到Dropbox,最後寄信通知」的動作了。
    Reference:
    http://developer.android.com/intl/zh-tw/tools/building/building-cmdline.html
    http://stackoverflow.com/questions/18332474/how-to-set-versionname-in-apk-filename-using-gradle
    http://blog.jensdriller.com/how-to-include-jenkins-ci-build-number-in-android-apk-name/

    留言

    這個網誌中的熱門文章

    Android使用Callback做為傳遞資料/通知的方法

    如何實作從API抓取資料顯示在列表頁(ListView)上

    Android如何實作強制App版本更新