Jenkins+Gradle實(shí)現(xiàn)Android自動化構(gòu)建

Jenkins簡介

Jenkins是一個開源軟件項(xiàng)目,旨在提供一個開放易用的軟件平臺蝶柿,使軟件的持續(xù)集成變成可能。目前大部分公司都在使用Jenkins來持續(xù)構(gòu)建陈惰。

Jenkins下載與安裝配置

Jenkins下載

安裝Jenkins有兩種方式:
第一種就是下載安裝包直接安裝北专,下載地址:http://mirrors.jenkins-ci.org
第二種就是下載war包禀挫,放到Tomcat中啟動。war包下載地址:http://mirrors.jenkins-ci.org/war/拓颓,
或者http://updates.jenkins-ci.org/download/war/
這里因?yàn)槲译娔X上面之前裝了Tomcat语婴,所以我使用直接下載war包的方式進(jìn)行安裝。

Jenkins安裝

將下載的jenkins.war放到Tomcat下的webapps目錄下驶睦,然后啟動Tomcat砰左。在瀏覽器中訪問"Tomcat訪問地址/jenkins"即可安裝,因?yàn)槲业腡omcat裝在本機(jī)场航,并且端口為8080缠导,所以訪問http://localhost:8080/jenkins/即可進(jìn)行安裝。

Jenkins配置

Jenkins安裝之后可以進(jìn)行用戶的權(quán)限設(shè)置旗闽、插件的安裝等配置酬核。

用戶權(quán)限設(shè)置

系統(tǒng)管理-->Configure Global Security
如下圖所示,在此處可以添加适室、刪除用戶以及配置用戶權(quán)限嫡意。

jenkins-gradle-1.png
插件安裝

搭建Android自動化打包環(huán)境需要安裝Gradle插件,如果使用Git還需要Git的插件捣辆,安裝Jenkins時默認(rèn)已經(jīng)安裝了這兩個插件蔬螟。如果沒有安裝可以進(jìn)入“系統(tǒng)管理>管理插件”進(jìn)行插件的安裝。

jenkins-gradle-2.png

創(chuàng)建Jenkins任務(wù)

要想Jenkins能夠幫我們自動構(gòu)建項(xiàng)目汽畴,我們需要創(chuàng)建一個任務(wù)旧巾,并且配置這個任務(wù)要它幫我們執(zhí)行什么操作,以及什么時候執(zhí)行等忍些。

jenkins-gradle-3.png

如上圖所示鲁猩,點(diǎn)擊“新建”按鈕并且選擇“構(gòu)建一個自由風(fēng)格的軟件項(xiàng)目”,完了之后會進(jìn)入到任務(wù)的配置界面罢坝,配置好之后任務(wù)會出現(xiàn)在如上圖右邊的任務(wù)列表中廓握。

任務(wù)配置

創(chuàng)建一個任務(wù)之后,會自動跳轉(zhuǎn)到任務(wù)的配置界面對該任務(wù)進(jìn)行配置嘁酿,大概包括如下配置:

源碼管理
jenkins-gradle-4.png

構(gòu)建項(xiàng)目隙券,當(dāng)然得有代碼了。Jenkins支持使用版本控制工具來進(jìn)行源碼管理闹司,比如Git或者SVN娱仔。這里我使用的是Git,項(xiàng)目使用的是我的github上面的一個多渠道打包的demo游桩。在Repository URL中輸入項(xiàng)目地址牲迫,點(diǎn)擊Add按鈕添加認(rèn)證信息耐朴,然后選擇構(gòu)建的分支,我這里使用的是master分支盹憎。

構(gòu)建觸發(fā)器

jenkins-gradle-5.png

Jenkins支持上圖所示的觸發(fā)時機(jī)配置隔箍,如果都不選,則為手動構(gòu)建脚乡,需要點(diǎn)擊“立即構(gòu)建”按鈕才構(gòu)建。
Build periodically:周期進(jìn)行項(xiàng)目構(gòu)建(它不關(guān)心源碼是否發(fā)生變化)滨达;
Build when a change is pushed to GItHub:表示只要GitHub上面源碼一更新即進(jìn)行構(gòu)件奶稠;
Poll SCM:定時檢查源碼變更(根據(jù)SCM軟件的版本號),如果有更新就checkout最新code下來捡遍,然后執(zhí)行構(gòu)建動作锌订。
Build periodically和Poll SCM都支持日程表的設(shè)置,這個與Spring框架中定時器的日程表配置類似画株,有5個參數(shù):
第一個參數(shù)代表的是分鐘 minute辆飘,取值 0~59;
第二個參數(shù)代表的是小時 hour谓传,取值 0~23蜈项;
第三個參數(shù)代表的是天 day,取值 1~31续挟;
第四個參數(shù)代表的是月 month紧卒,取值 1~12;
最后一個參數(shù)代表的是星期 week诗祸,取值 0~7跑芳,0 和 7 都是表示星期天。
如:
選擇Build periodically并設(shè)置日程表為“0 4 * * ”直颅,則表示每天凌晨4點(diǎn)構(gòu)建一次源碼博个。
選擇Poll SCM并設(shè)置日程表為“
/10 * * * *”,則表示每10分鐘檢查一次源碼變化功偿,如果有更新才進(jìn)行構(gòu)建盆佣。

構(gòu)建工具

因?yàn)楝F(xiàn)在Android項(xiàng)目默認(rèn)都是使用Gradle來進(jìn)行構(gòu)建的,所以在構(gòu)建中我選擇的是Invoke Gradle script脖含。當(dāng)然你也可以選擇其它的構(gòu)建工具罪塔,比如Ant。
選擇Invoke Gradle script之后可以選Invoke Gradle和Use Gradle Wrapper养葵,選擇Invoke Gradle就是調(diào)用本地安裝配置好的Gradle征堪,此時需要指定Gradle路徑。為了方便所有開發(fā)者同意Gradle版本关拒,一般都使用Gradle Wrapper佃蚜。關(guān)于Gradle和Gradlew的區(qū)別可以看這篇文章https://www.zybuluo.com/xtccc/note/275168庸娱。

jenkins-gradle-6.png

Tasks中填上需要執(zhí)行的gradle的task。上面我填的clean assembleRelease谐算,即執(zhí)行g(shù)radlew clean assembleRelease熟尉。

構(gòu)建后的操作

配置構(gòu)建后的操作可以讓Jenkins在構(gòu)建完之后執(zhí)行什么操作,比如郵件通知洲脂、構(gòu)建其它項(xiàng)目等斤儿。

jenkins-gradle-7.png

這里我配置了Archive the artifacts,在“用于存檔的文件”中填寫需要存檔的文件名恐锦,可以使用通配符往果。比如上面我配置了app/build/outputs/apk/v*.apk,表示疑v開頭的apk文件都存檔一铅。構(gòu)建完之后在任務(wù)首頁可以下載存檔的文件陕贮。
任務(wù)配置完成之后,點(diǎn)擊任務(wù)首頁的“立即構(gòu)建”按鈕潘飘,即可開始構(gòu)建肮之,構(gòu)建過程首先會將源碼下載下來,位于jenkins目錄下的workspace中卜录。然后執(zhí)行配置好的gradle命令戈擒,如果使用gradlew,第一次應(yīng)該會下載gradlew設(shè)置的版本的gradle艰毒,最后執(zhí)行構(gòu)建任務(wù)峦甩。構(gòu)建完之后,如下圖现喳,可以看到存檔的文件凯傲,點(diǎn)擊即可下載。

jenkins-gradle-8.png

附:Android工程build.gradle文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.lauren.multichanneldemo"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    signingConfigs {
        release {
            def liulingStoreFile = System.getenv("LIULING_STORE_FILE")
            def liulingKeyAlias = System.getenv("LIULING_KEY_ALIAS")
            def liulingKeyPassword = System.getenv("LIULING_KEY_PASSWORD")
            def liulingStorePassword = System.getenv("LIULING_STORE_PASSWORD")
            def isSigning = (liulingStoreFile != null) && (liulingKeyAlias != null) && (liulingKeyPassword != null) && (liulingStorePassword != null)
            if(isSigning){
                storeFile file(liulingStoreFile)
                keyAlias liulingKeyAlias
                keyPassword liulingKeyPassword
                storePassword liulingStorePassword
            } else {
                storeFile file("debug.keystore")
                keyAlias "AndroidDebugKey"
                keyPassword "android"
                storePassword "android"
            }
        }
        debug {
            storeFile file("debug.keystore")
            keyAlias "AndroidDebugKey"
            keyPassword "android"
            storePassword "android"
        }
    }

    buildTypes {
        release {
            // 不顯示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            //啟用混淆代碼的功能
            minifyEnabled true
            //壓縮對齊生成的apk包
            zipAlignEnabled true
            //指定混淆規(guī)則嗦篱,需要壓縮優(yōu)化的混淆要把proguard-android.txt換成proguard-android.txt
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            shrinkResources true
            signingConfig signingConfigs.release //打包命令行:gradlew assembleRelease
        }

        debug {
            signingConfig signingConfigs.debug
        }
    }

    lintOptions {
        abortOnError false
    }

//    productFlavors {
//        _91 {
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "91"]
//        }
//        wandoujia {
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "wandoujia"]
//        }
//        xiaomi {
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "xiaomi"]
//        }
//
//        _360shoufa{
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "360shoufa"]
//        }
//        anzhi{
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "anzhi"]
//        }
//        baidushoufa{
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "baidushoufa"]
//        }
//        huaweishoufa{
//            manifestPlaceholders = [MTA_CHANNEL_VALUE: "huaweishoufa"]
//        }
//    }

    // 如果嫌上面寫法麻煩,也可以這樣簡寫,加上一個批量處理即可.
    productFlavors {
        _91 {}
        wandoujia {}
        xiaomi {}
        _360shoufa{}
        anzhi{}
        baidushoufa{}
        huaweishoufa{}
    }
    //批量處理
    productFlavors.all {
        flavor ->
            def channel = name.startsWith("_") ? name.substring(1) : name
            flavor.manifestPlaceholders = [MTA_CHANNEL_VALUE: channel]
    }

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (variant.buildType.name.equals('release')) {
                //可自定義自己想要生成的格式
                def channel = variant.productFlavors[0].name.startsWith("_") ? variant.productFlavors[0].name.substring(1) : variant.productFlavors[0].name
                def fileName = "v${defaultConfig.versionName}_${releaseTime()}_${channel}.apk"
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }
    apply from: 'productFlavors.gradle'

}

def releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

本文首發(fā):http://www.liuling123.com/2016/10/jenkins-gradle-auto-build.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冰单,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子灸促,更是在濱河造成了極大的恐慌诫欠,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浴栽,死亡現(xiàn)場離奇詭異荒叼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)典鸡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門被廓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萝玷,你說我怎么就攤上這事嫁乘±バ觯” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵蜓斧,是天一觀的道長仓蛆。 經(jīng)常有香客問我,道長挎春,這世上最難降的妖魔是什么看疙? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮直奋,結(jié)果婚禮上狼荞,老公的妹妹穿的比我還像新娘。我一直安慰自己帮碰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布拾积。 她就那樣靜靜地躺著殉挽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拓巧。 梳的紋絲不亂的頭發(fā)上斯碌,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音肛度,去河邊找鬼傻唾。 笑死,一個胖子當(dāng)著我的面吹牛承耿,可吹牛的內(nèi)容都是我干的冠骄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼加袋,長吁一口氣:“原來是場噩夢啊……” “哼凛辣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起职烧,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扁誓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚀之,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝗敢,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年足删,在試婚紗的時候發(fā)現(xiàn)自己被綠了寿谴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡失受,死狀恐怖拭卿,靈堂內(nèi)的尸體忽然破棺而出骡湖,到底是詐尸還是另有隱情,我是刑警寧澤峻厚,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布响蕴,位于F島的核電站,受9級特大地震影響惠桃,放射性物質(zhì)發(fā)生泄漏浦夷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一辜王、第九天 我趴在偏房一處隱蔽的房頂上張望劈狐。 院中可真熱鬧,春花似錦呐馆、人聲如沸肥缔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽续膳。三九已至,卻和暖如春收班,著一層夾襖步出監(jiān)牢的瞬間坟岔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工摔桦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留社付,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓邻耕,卻偏偏與公主長得像鸥咖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子兄世,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容