在項(xiàng)目的上個(gè)版本,老大說將Android打包搞到服務(wù)器上,讓所有人都可以享受打包的樂趣,接著就有了這篇文章~Jenkins自動(dòng)打包,已經(jīng)用了一段時(shí)間了,奈何前段時(shí)間陷入了王者峽谷,所以一直懶得寫文章,現(xiàn)在終于找回狀態(tài),開擼。雖然Jenkins的文章又很多,但我覺得這篇會(huì)給你幾乎所有想要的。
我用的是Jenkins+Git+Gradle實(shí)現(xiàn)自動(dòng)打包
安裝
上來就是干的,首先到Jenkins的官網(wǎng)下載https://jenkins.io,點(diǎn)擊Download Jenkins按鈕會(huì)彈出兩個(gè)版本選擇:LTS Release(長期支持版本),Weekly Release(每周更新版本)。首先說一下這兩個(gè)版本,個(gè)人覺得和MIUI的更新類似,一個(gè)開發(fā)版本一個(gè)穩(wěn)定版,大家可以自行選擇,功能上幾乎沒區(qū)別。點(diǎn)擊尖角號(hào)會(huì)彈出操作系統(tǒng),可以選擇對(duì)應(yīng)的操作系統(tǒng)安裝,也可以直接下載2.xx.x.war包然后放在Tomcat(下文會(huì)詳細(xì)介紹Tomcat一些功能)的webapps目錄,新建Jenkins文件夾再放入。
我選擇的是Windows安裝版的,首先安裝版和war版我都嘗試過,功能是沒區(qū)別的,主要的區(qū)別在于目錄上,安裝版指定安裝目錄以后幾乎所有的東西都會(huì)在對(duì)應(yīng)的文件夾下生成,比如Jobs(即存放工程目錄),不會(huì)在其他磁盤再生成多余的文件夾,而war版放在Tomcat目錄下以后,用瀏覽器打開,所有的東西會(huì)在C盤生成.Jenkins文件夾。我自己是有一些強(qiáng)迫癥的,喜歡目錄整潔,不生成多余文件夾的。還有一個(gè)理由就是安裝版可以不依賴Tomcat,即使本機(jī)沒有安裝Tomcat,安裝版安裝完成后依然可以用本機(jī)ip:port啟動(dòng)。大家可以自行選擇喜歡的版本。
由于安裝部分比較簡(jiǎn)單,就不上圖了。
插件
1.進(jìn)入管理插件
接下來就要說說,Jenkins最強(qiáng)大的部分之一了,那就是插件。Jenkins提供了非常多的插件,幾乎你想要的插件全有,前提是你能找的到~官網(wǎng)提供了插件搜索功能,選擇Plugins頁就可以各種搜索了。
重點(diǎn)來了(敲黑板,啪啪啪~):首次進(jìn)入,首先要輸入一個(gè)密鑰來進(jìn)入Jenkins,接下來...接下來...上圖
一般選擇第一項(xiàng)即可,會(huì)自動(dòng)安裝推薦的插件,注意:這里并不是所有插件都能安裝成功,有的安裝失敗也不影響,所有的安裝完進(jìn)行下一步就可以了。
But,有時(shí)候點(diǎn)擊以后會(huì)發(fā)生下面的情況
怎么點(diǎn)擊Retry按鈕依然是錯(cuò)誤,這時(shí)候不要慌張,咱們選擇第一張圖中的第二項(xiàng),進(jìn)行自己選擇,這里系統(tǒng)推薦的插件默認(rèn)也是選中的,直接點(diǎn)安裝即可。But,個(gè)別情況依然會(huì)出現(xiàn)上圖的錯(cuò)誤頁面,那么解決辦法就是:進(jìn)入自行選擇頁面,清空選項(xiàng)即所有都不選,然后點(diǎn)安裝按鈕,進(jìn)入下一頁。
下一頁就是創(chuàng)建用戶頁面,這里建議創(chuàng)建用戶,下面提供了Continue as admin按鈕也可進(jìn)入主頁,但是后期想創(chuàng)建用戶還是很麻煩的,所以建議創(chuàng)建用戶。
創(chuàng)建好用戶,就可以進(jìn)入到主頁了~選擇系統(tǒng)管理->管理插件->可選插件來開始安裝我們需要的插件。
2.插件列表
注意:列表中為主要插件,而Jenkins的插件是有依賴關(guān)系的,安裝一個(gè)插件可能要先安裝它依賴的插件,否則會(huì)安裝失敗。在可選插件勾選列表中的插件即可,依賴插件會(huì)自動(dòng)下載,是不是很棒。
- Git plugin
- Gradle Plugin
- Email Extension Plugin
- description setter plugin
- build-name-setter
- user build vars plugin
- Post-Build Script Plug-in
- Branch API Plugin
- SSH plugin
- Scriptler
- Dynamic Parameter Plug-in
- Git Parameter Plug-In
配置
插件安裝完畢,我們就可以來配置Jenkins了,打包又離我們近了一步。
1.Global Tool Configuration
在系統(tǒng)管理選項(xiàng)中找到Global Tool Configuration進(jìn)入,如果上面的插件安裝成功,在這里會(huì)看到三個(gè)板塊,如圖
分別是JDK,Git,Gradle板塊,分別配置這三個(gè)的路徑。
- JDK:別名=任意,JAVA_HOME=JDK目錄
- Git:別名=任意, Path to Git executable=Git安裝目錄\bin\git.exe
- Gradle:別名=任意,GRADLE_HOME=Gradle下載目錄\Gradle\gradle-2.xx
Gradle盡量配置多個(gè),因?yàn)轫?xiàng)目的gradle版本可能不一樣,所以需要選擇不同的Gradle版本進(jìn)行編譯
這個(gè)Gradle的目錄,可以是Android Studio默認(rèn)下載的Gradle目錄,在用戶目錄的.gradle\wrapper\dists文件夾下,但是目錄不是很整潔;也可以到http://www.androiddevtools.cn找到gradle資源處下載常用的gradle版本,放到一個(gè)指定的文件夾,然后配置路徑即可,目錄比較整潔。
2.全局屬性
在這里最好配置一下全局屬性,這里先說一個(gè),就是配置Android SDK目錄,在打包是有可能會(huì)出現(xiàn)ANDROID_HOME not found的情況,所以在系統(tǒng)管理->系統(tǒng)設(shè)置->全局屬性版塊勾選上Environment variables選項(xiàng),然后添加
記得更改值內(nèi)的路徑為本機(jī)sdk目錄。
注意:這里的鍵需要和本機(jī)環(huán)境變量?jī)?nèi)的Android SDK目錄的鍵一致
打包
1.創(chuàng)建項(xiàng)目
距離開始打包又近了一步,接下來就開始創(chuàng)建新項(xiàng)目了,點(diǎn)擊首頁的新建,進(jìn)入下圖界面
給自己的項(xiàng)目起個(gè)名字,然后選擇構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目,點(diǎn)擊OK按鈕,進(jìn)入項(xiàng)目的配置界面。
2.項(xiàng)目配置
直接選擇源碼管理tab或者向下滾動(dòng)找到源碼管理,如圖;
選中Git選項(xiàng),會(huì)出現(xiàn)上圖的界面,配置Git項(xiàng)目的URL,我測(cè)試用的是Github項(xiàng)目,并且傳輸協(xié)議選擇的是HTTP,需要選擇Credentials選項(xiàng),選擇通行證,第一次需要點(diǎn)擊Add添加通行證,如圖:
Kind種類選擇默認(rèn)的Username with password,然后在Username和Pasword處分別輸入Git賬戶的用戶名和密碼,然后滾動(dòng)到下方點(diǎn)擊Add,然后在Credentials中選擇我們剛才添加的通行證。
接著滾動(dòng)到構(gòu)建Tab,點(diǎn)擊添加構(gòu)建步驟,然后選擇Invoke Gradle script,如圖:
然后配置構(gòu)建時(shí)的Gradle版本,和需要執(zhí)行的任務(wù),如圖:
這個(gè)Tasks是先clean工程,然后打包所有渠道的Release版本,這是Gradle的命令,不多說了。然后點(diǎn)擊保存按鈕,馬上就可以打包了。
3.開始構(gòu)建
點(diǎn)擊保存后,進(jìn)入項(xiàng)目界面,如圖:
點(diǎn)擊左側(cè)菜單欄的立即構(gòu)建,開始構(gòu)建項(xiàng)目,這時(shí)候Build History版塊會(huì)出現(xiàn)構(gòu)建任務(wù)列表,點(diǎn)擊進(jìn)入可以查看構(gòu)建詳情頁,如圖
又很多菜單可以選擇來查看狀態(tài),點(diǎn)擊Console Output來查看構(gòu)建輸出的日志,所有的信息都會(huì)顯示,日志最后輸出Finished: SUCCESS即構(gòu)建成功。
成功之后,返回項(xiàng)目地址就可以點(diǎn)擊工作空間,在app的build目錄下面查看apk生成情況。
以上就是Jenkins打包最簡(jiǎn)單的配置,我知道大家想要的不止這些,更精彩的還在后面。
定制想要的功能
1.參數(shù)化構(gòu)建
在我們打包的時(shí)候,我們大多時(shí)候不想只是簡(jiǎn)簡(jiǎn)單單打一個(gè)版本的包,我們想通過配置一下參數(shù),來滿足一些需求,比如根據(jù)渠道打不同版本的包、根據(jù)Tag打不同的包等,下面就來說一下Jenkins參數(shù)化構(gòu)建。
在我們項(xiàng)目中需要配置的選項(xiàng)有:版本(Release 或 Debug),版本號(hào),渠道包,根據(jù)Tag打包。另外我們還需要加上打包途徑,AS打包還是Jenkins打的包,還要加一個(gè)時(shí)間戳。所有的參數(shù)列出來了,下面就配置Jenkins的參數(shù)化構(gòu)建吧~
在Jenkins項(xiàng)目主頁選擇配置,進(jìn)入配置頁,在General tab將參數(shù)化構(gòu)建過程選中,如圖:
接下來就可以添加參數(shù)了,下面我先列出參數(shù)表格:
參數(shù)名 | 參數(shù)類型 | 參數(shù)值列表 |
---|---|---|
BUILD_TYPE | Choice | Release or Debug |
IS_JENKINS | Choice | true |
PRODUCT_FLAVORS | Choice | Xiaomi 、Wandoujia等 |
BUILD_TIME | Dynamic Parameter | 2016-12-21-11-11 |
APP_VERSION | Choice | 1.0.0、1.0.1等 |
GIT_TAG | Git Parameter | tag1.0.0等 |
下面直接放我的配置截圖:
配置完參數(shù)還不算完,我們要在下方構(gòu)建時(shí)候引用,首先找到構(gòu)建標(biāo)簽處,將Tasks屬性值修改為:
clean assemble${PRODUCT_FLAVORS}${BUILD_TYPE} --stacktrace --debug
其中${PRODUCT_FLAVORS}
和&{BUILD_TYPE}
分別對(duì)應(yīng)上面的參數(shù)名。配置如圖:
看了圖大家肯定留意到了紅色框內(nèi)的選項(xiàng)而且很好奇吧,這個(gè)選項(xiàng)是APP_VERSION、IS_JENKINS、BUILD_TIME需要用到的,因?yàn)檫@三個(gè)參數(shù)需要注入到Android項(xiàng)目中的配置一樣,而紅色框中的這個(gè)選項(xiàng)可以幫我們侵入到gradle.properties文件中替換值,并且build.gradle文件能夠直接引用gradle.properties文件中的屬性,所以起到了侵入的效果。下面分別是我的gradle.properties和主項(xiàng)目的build.gradle文件全代碼:
//gradle.properties
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
#http://www.gradle.org/docs/current/userguide/multi_project_builds.html
#sec:decoupled_projects
#org.gradle.parallel=true
APP_VERSION=1.0.1
IS_JENKINS=true
BUILD_TIME=''
//build.gradle
apply plugin: 'com.android.application'
def getDate() {
def date = new Date()
def formattedDate = date.format('yyyy-MM-dd-HH-mm')
return formattedDate
}
def verCode = 14
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.zyyoona7.autobuildtest"
minSdkVersion 15
targetSdkVersion 23
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
versionCode verCode
versionName APP_VERSION
}
signingConfigs {
signingConfig {
//由于本地打包使用的是本機(jī)上的KeyStore
//而Jenkins打包用的是服務(wù)器上的KeyStore
//兩個(gè)路徑不一樣
if("true".equals(IS_JENKINS)){
storeFile file("服務(wù)器上KeyStore的路徑")
}else {
storeFile file(STORE_FILE_PATH)
}
keyAlias KEY_ALIAS
keyPassword KEY_PASSWORD
storePassword STORE_FILE_PASSWORD
}
}
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.signingConfig
}
debug { }
}
dexOptions {
javaMaxHeapSize "2g"
}
//渠道Flavors
productFlavors {
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
}
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
}
}
//修改生成的apk名字及輸出文件夾
applicationVariants.all { variant ->
variant.outputs.each { output ->
//新名字
def newName
//時(shí)間戳
def timeNow
//輸出文件夾
def outDirectory
//是否為Jenkins打包,輸出路徑不同
if ("true".equals(IS_JENKINS)) {
//Jenkins打包輸出到服務(wù)器路徑
timeNow = BUILD_TIME
//BUILD_PATH為服務(wù)器輸出路徑
outDirectory = BUILD_PATH
//AutoBuildTest-v1.0.1-xiaomi-release.apk
newName = 'AutoBuildTest-v' + APP_VERSION + '-' + variant.productFlavors[0].name + '-' + variant.buildType.name + '.apk'
} else {
//本機(jī)打包輸出在本機(jī)路徑
timeNow = getDate()
outDirectory = output.outputFile.getParent()
if ('debug'.equals(variant.buildType.name)) {
newName = "AutoBuildTest-v${APP_VERSION}-debug.apk"
} else {
//AutoBuildTest-v1.0.1-xiaomi-release.apk
newName = 'AutoBuildTest-v' + APP_VERSION + '-' + variant.productFlavors[0].name + '-' + variant.buildType.name + '.apk'
}
}
output.outputFile = new File(outDirectory+'/'+timeNow, newName)
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.0'
testCompile 'junit:junit:4.12'
}
這樣在Jenkins打包的時(shí)候上面三個(gè)參數(shù)就會(huì)隨著選擇變化而變化了。
GIT_TAG參數(shù)使用配置,只需在源碼管理處的Branch引用改為$GIT_TAG
引用參數(shù)名,如圖:
參數(shù)配置完畢,看一下主頁面的效果吧,現(xiàn)在立即構(gòu)建選項(xiàng)變成了_ Build with Parameters_,完成圖:
提示:
- 如果選中了GIT_TAG中的任意版本都無法取消選中,只能刷新;
- 還有使用GIT_TAG時(shí)最好選擇tag版本大于等于支持Jenkins打包的版本,因?yàn)橹鞍姹敬a中沒加需要侵入的屬性
2.按時(shí)打包
由于篇幅原因加上這個(gè)功能我沒用在項(xiàng)目中,所以請(qǐng)參考使用Jenkins搭建iOS/Android持續(xù)集成打包平臺(tái)的配置構(gòu)建觸發(fā)器部分。
3.構(gòu)建命名
每次構(gòu)建的時(shí)候,Build History模塊顯示是這樣的,如圖:
每次構(gòu)建都只顯示數(shù)字(#xx),這樣很不好看,我們想要它顯示更多的信息怎么辦呢?比如加入構(gòu)建者姓名、構(gòu)建的app版本、構(gòu)建的類型等。請(qǐng)看下圖:
配置完以后再次打包,變成了這個(gè)樣子,如圖:
是不是很Nice,當(dāng)然大家還可以根據(jù)需求自行發(fā)揮~
4.Tomcat配置下載地址
打完包放在服務(wù)器上,我們得配置一下下載環(huán)境才能下載,首先是Tomcat的安裝,這里對(duì)Tomcat安裝就不做詳細(xì)的介紹了,如果不熟悉的請(qǐng)自行谷歌或百度,下面內(nèi)容需基于Tomcat環(huán)境進(jìn)行,我的Tomcat版本為8.0+。
這里說一下如何使用Tomcat配置下載地址,首先進(jìn)入Tomcat目錄下的conf文件夾,然后打開server.xml文件在最后添加如圖代碼:
<!-- docBase為絕對(duì)路徑即板寸apk文件的文件夾,path為相對(duì)地址即在地址欄訪問的地址-->
<Context reloadable="true" docBase="C://android/downloadApk" crossContext="true" path="/downloadApk"/>
添加完這句話以后啟動(dòng)Tomcat服務(wù),打開瀏覽器輸入IP:Port/downloadApk,就可以訪問了點(diǎn)擊你想要的文件下載吧。
5.二維碼下載
二維碼下載功能,現(xiàn)在網(wǎng)上大多數(shù)的做法是通過蒲公英或者fir.im來生成二維碼,這兩個(gè)都是內(nèi)測(cè)平臺(tái),我體驗(yàn)過蒲公英,需要將文件傳到蒲公英網(wǎng)站然后他們生成二維碼返回,傳到別處總感覺怪怪的,于是我決定自己生成二維碼然后放在下載地址的文件夾中,通過鏈接顯示。
首先要在電腦上安裝python環(huán)境,請(qǐng)看http://www.cnblogs.com/yuanzm/p/4089856.html和(Python問題一)python 安裝PIL (Python Imaging Library )來進(jìn)行安裝,如果已經(jīng)安裝繼續(xù)往下看。生成二維碼我用了qrcode這個(gè)庫,感謝大神的分享,這個(gè)庫如何使用就不介紹了,我只說一下Jenkins如何執(zhí)行python。
添加python的環(huán)境變量到Jenkins的環(huán)境變量中,文章前面有提到過,在系統(tǒng)管理->系統(tǒng)設(shè)置中,如圖添加python環(huán)境變量:
注意:鍵名需要和電腦上系統(tǒng)環(huán)境變量?jī)?nèi)的鍵名保持一致。
然后打開項(xiàng)目配置頁面,在構(gòu)建版塊點(diǎn)擊添加構(gòu)建步驟,如圖:
在編輯框內(nèi)輸入qrcode項(xiàng)目的使用命令
注意:下載地址需要自己拼接,生成路徑也需要自己拼接。
這樣每次打包后都會(huì)在生成apk的文件夾內(nèi)生成一個(gè)對(duì)應(yīng)的二維碼。掃一掃就可以下載啦~~~
6.構(gòu)建后操作
構(gòu)建完成后,我希望將下載地址和二維碼放在Build History的版塊中,方便下載,那么我們就來設(shè)置一下,打開項(xiàng)目配置頁,如圖操作:
在Description輸入框內(nèi)添加
<!-- 需替換鏈接地址 -->
<br>
<a >下載連接</a>
7.郵件通知
打完包,我想通知需要下載的人怎么辦?發(fā)郵件~~Jenkins自帶了郵件功能,但是不太好用,所以我選擇了Email Extension Plugin這個(gè)插件來實(shí)現(xiàn)發(fā)郵件功能(已經(jīng)在插件列表中)。進(jìn)入系統(tǒng)管理->系統(tǒng)設(shè)置頁面,如圖:
郵件格式:
[Jenkins構(gòu)建通知]$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
(郵件由Jenkins自動(dòng)發(fā)出,請(qǐng)勿回復(fù)~)<br>
項(xiàng)目名稱:$PROJECT_NAME<br>
構(gòu)建編號(hào):$BUILD_NUMBER<br>
構(gòu)建狀態(tài):$BUILD_STATUS<br>
觸發(fā)原因:${CAUSE}<br>
構(gòu)建地址:<A HREF="${BUILD_URL}">${BUILD_URL}</A><br>
構(gòu)建輸出日志:<a >http://192.168.1.201:8090/job/${PROJECT_NAME}/${BUILD_NUMBER}/console</a><br>
下載地址:<a >http://192.168.1.88:8088/downloadApk</a><br><br>
二維碼下載:<br>
最近修改:<br>${CHANGES, showPaths=false, format="%a:\"%m\"<br>", pathFormat="\n\t- %p"}
注意:請(qǐng)自行修改對(duì)應(yīng)的地址,關(guān)于最近修改請(qǐng)參照http://stackoverflow.com/questions/7773010/how-to-include-git-changelog-in-jenkins-emails
最終的效果圖是介個(gè)樣子的:
遇到的錯(cuò)誤
1.AAPT err(Facade for 26390200):build-tools/23.0.1/aapt: /lib/libc.so.6: version `GLIBC_2.11' not found /23.0.1/aapt)####
在將Jenkins部署到linux服務(wù)器的時(shí)候出現(xiàn)了這個(gè)錯(cuò)誤,lib/libc.so.6是linux系統(tǒng)的c庫,由于我們公司服務(wù)器的linux系統(tǒng)太老,導(dǎo)致最高支持GLIBC_2.5
,雖然可以通過升級(jí)內(nèi)核來解決,但是有風(fēng)險(xiǎn),所以最后決定還是部署到了Windows服務(wù)器上面。所以在部署到Linux服務(wù)器上面之前先檢查你的Linux系統(tǒng)所支持的GLIBC_2.xx
的版本,Android Build-Tools 25.0.0的需要GLIBC_2.14
。
2.local.properties:sdk.dir not found or ANDROID_HOME not found
不好意思,因?yàn)闆]及時(shí)記錄所以這個(gè)錯(cuò)誤我只記了大概,而且配置完以后,想出現(xiàn)這個(gè)錯(cuò)誤竟然沒復(fù)現(xiàn),所以只能看個(gè)大概了。這個(gè)錯(cuò)誤主要是配置Android SDK路徑為ANDROID_HOME環(huán)境變量沒有配置。Windows上面配置一下環(huán)境變量;名字ANDROID_HOME:值為Android SDK路徑。還有一種方法,配置Jenkins的環(huán)境變量名字和值和上面一樣,添加到系統(tǒng)管理->系統(tǒng)設(shè)置->全局屬性下面有一個(gè)Environment variables 勾上,然后添加環(huán)境變量即可
總結(jié)
Jenkins打包并不難,最難的地方就是安裝插件,由于公司網(wǎng)絡(luò)不太給力導(dǎo)致安裝插件至少半天,坑啊~~~
如果在Linux系統(tǒng)上和Mac上使用Jenkins的化設(shè)置起來幾乎無差別,只是需要的文件格式大同小異而已。
由于篇幅比較多,希望大家看完多多反饋,有什么問題也可以留言。
參考
使用Jenkins搭建iOS/Android持續(xù)集成打包平臺(tái)
利用Jenkins玩轉(zhuǎn)Android自動(dòng)打包發(fā)包