作為一名Android程序猿,能偷懶時是一定要偷懶的。
大家在開發(fā)中一定遇到過:
測試說:幫我打個包吧,
產(chǎn)品說:幫我打個包吧,
......說:幫我打個包吧
此時的你,正思緒如潮的構(gòu)思著邏輯,激情的敲著代碼。。。。。。
看完這篇文章以后,你可以直接對著他們說:自己玩去吧,我這忙著呢!
jenkins可以讓所有人都體驗到自己打包的樂趣!
先給大家看一下效果圖:

這里先奉上2篇參考的文章地址:
http://m.itdecent.cn/p/38b2e17ced73
Jenkins+ Git + Gradle + 二維碼生成,二維碼與下載鏈接使用本地Tomcat作為服務(wù)器,超詳細?。?!
http://blog.csdn.net/mabeijianxi/article/details/52680283
郭霖原創(chuàng),Jenkins+ Svn + Gradle + 蒲公英二維碼生成 + Python
下面開始我們的Jenkins之旅:
一.安裝(下面安裝的,均是指安裝在Jenkins服務(wù)器下的)
首先到Jenkins的官網(wǎng)下載https://jenkins.io,點擊Download Jenkins按鈕會彈出兩個版本選擇:LTS Release(長期支持版本),Weekly Release(每周更新版本)。首先說一下這兩個版本,個人覺得和MIUI的更新類似,一個開發(fā)版本一個穩(wěn)定版,大家可以自行選擇,功能上幾乎沒區(qū)別。點擊尖角號會彈出操作系統(tǒng),可以選擇對應(yīng)的操作系統(tǒng)安裝,也可以直接下載2.xx.x.war包然后放在Tomcat(下文會詳細介紹Tomcat一些功能)的webapps目錄,新建Jenkins文件夾再放入。
我選擇的是Windows安裝版的,首先安裝版和war版我都嘗試過,功能是沒區(qū)別的,主要的區(qū)別在于目錄上,安裝版指定安裝目錄以后幾乎所有的東西都會在對應(yīng)的文件夾下生成,比如Jobs(即存放工程目錄),不會在其他磁盤再生成多余的文件夾,而war版放在Tomcat目錄下以后,用瀏覽器打開,所有的東西會在C盤生成.Jenkins文件夾。我自己是有一些強迫癥的,喜歡目錄整潔,不生成多余文件夾的。還有一個理由就是安裝版可以不依賴Tomcat,即使本機沒有安裝Tomcat,安裝版安裝完成后依然可以用本機ip:port啟動。大家可以自行選擇喜歡的版本。
由于安裝部分比較簡單,就不上圖了。
插件
1.進入管理插件
接下來就要說說,Jenkins最強大的部分之一了,那就是插件。Jenkins提供了非常多的插件,幾乎你想要的插件全有,前提是你能找的到~官網(wǎng)提供了插件搜索功能,選擇Plugins頁就可以各種搜索了。
重點來了(敲黑板,啪啪啪~):首次進入,首先要輸入一個密鑰來進入Jenkins,接下來...接下來...上圖

一般選擇第一項即可,會自動安裝推薦的插件,注意:這里并不是所有插件都能安裝成功,有的安裝失敗也不影響,所有的安裝完進行下一步就可以了。
But,有時候點擊以后會發(fā)生下面的情況

setup_error.png
怎么點擊Retry按鈕依然是錯誤,這時候不要慌張,咱們選擇第一張圖中的第二項,進行自己選擇,這里系統(tǒng)推薦的插件默認也是選中的,直接點安裝即可。But,個別情況依然會出現(xiàn)上圖的錯誤頁面,那么解決辦法就是:進入自行選擇頁面,清空選項即所有都不選,然后點安裝按鈕,進入下一頁。
下一頁就是創(chuàng)建用戶頁面,這里建議創(chuàng)建用戶,下面提供了Continue as admin按鈕也可進入主頁,但是后期想創(chuàng)建用戶還是很麻煩的,所以建議創(chuàng)建用戶。
創(chuàng)建好用戶,就可以進入到主頁了~選擇系統(tǒng)管理->管理插件->可選插件來開始安裝我們需要的插件。
2.插件列表
注意:列表中為主要插件,而Jenkins的插件是有依賴關(guān)系的,安裝一個插件可能要先安裝它依賴的插件,否則會安裝失敗。在可選插件勾選列表中的插件即可,依賴插件會自動下載,是不是很棒。這里也沒什么技術(shù)含量,但是很耗時,系統(tǒng)管理->插件管理->管理插件->可選插件: 勾選如下插件:
fir-plugin(可選,fir平臺上傳二維碼時)
Subversion Release Manager plugin(可選)
Subversion Plug-in(可選)
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 此插件存在Bug,后面詳細說
Git Parameter Plug-In配置
插件安裝完畢,我們就可以來配置Jenkins了,打包又離我們近了一步。
1.Global Tool Configuration
在系統(tǒng)管理選項中找到Global Tool Configuration進入,如果上面的插件安裝成功,在這里會看到三個板塊,如圖

Global_Tool_Configuration.png
分別是JDK,Git,Gradle板塊,分別配置這三個的路徑。
JDK:別名=任意,JAVA_HOME=JDK目錄
Git:別名=任意, Path to Git executable=Git安裝目錄\bin\git.exe
Gradle:別名=任意,GRADLE_HOME=Gradle下載目錄\Gradle\gradle-2.xxGradle盡量配置多個,因為項目的gradle版本可能不一樣,所以需要選擇不同的Gradle版本進行編譯
這個Gradle的目錄,可以是Android Studio默認下載的Gradle目錄,在用戶目錄的.gradle\wrapper\dists文件夾下,但是目錄不是很整潔;也可以到http://www.androiddevtools.cn找到gradle資源處下載常用的gradle版本,放到一個指定的文件夾,然后配置路徑即可,目錄比較整潔。
SVN用戶設(shè)置類似,不再重復(fù)。
2.全局屬性
在這里最好配置一下全局屬性,這里先說一個,就是配置Android SDK目錄,在打包是有可能會出現(xiàn)ANDROID_HOME not found的情況,所以在系統(tǒng)管理->系統(tǒng)設(shè)置->全局屬性版塊勾選上Environment variables選項,然后添加

記得更改值內(nèi)的路徑為本機sdk目錄。
注意:這里的鍵需要和本機環(huán)境變量內(nèi)的Android SDK目錄的鍵一致
真正配置起來可能比較繁瑣,遇到一些問題,但是多摸索摸索都會成功,接下來開啟步入正題
二.項目打包
1.創(chuàng)建項目
距離開始打包又近了一步,接下來就開始創(chuàng)建新項目了,點擊首頁的新建,進入下圖界面

給自己的項目起個名字,然后選擇構(gòu)建一個自由風格的軟件項目,點擊OK按鈕,進入項目的配置界面。
2.項目配置
直接選擇源碼管理tab或者向下滾動找到源碼管理,如圖;
Git用戶:

選中Git選項,會出現(xiàn)上圖的界面,配置Git項目的URL,我測試用的是Github項目,并且傳輸協(xié)議選擇的是HTTP,需要選擇Credentials選項,選擇通行證,第一次需要點擊Add添加通行證,如圖:

Kind種類選擇默認的Username with password,然后在Username和Pasword處分別輸入Git賬戶的用戶名和密碼,然后滾動到下方點擊Add,然后在Credentials中選擇我們剛才添加的通行證。
SVN用戶:
填寫svn項目地址,用戶名,密碼

接著滾動到構(gòu)建Tab,點擊添加構(gòu)建步驟,然后選擇Invoke Gradle script,如圖:

然后配置構(gòu)建時的Gradle版本,和需要執(zhí)行的任務(wù),如圖:

build1.png
這個Tasks是先clean工程,然后打包所有渠道的Release版本,這是Gradle的命令,不多說了。然后點擊保存按鈕,馬上就可以打包了。
3.開始構(gòu)建
點擊保存后,進入項目界面,如圖:

點擊左側(cè)菜單欄的立即構(gòu)建,開始構(gòu)建項目,這時候Build History版塊會出現(xiàn)構(gòu)建任務(wù)列表,點擊進入可以查看構(gòu)建詳情頁,如圖

定制想要的功能
1.參數(shù)化構(gòu)建
在我們打包的時候,我們大多時候不想只是簡簡單單打一個版本的包,我們想通過配置一下參數(shù),來滿足一些需求,比如根據(jù)渠道打不同版本的包、根據(jù)Tag打不同的包等,下面就來說一下Jenkins參數(shù)化構(gòu)建。
在我們項目中需要配置的選項有:版本(Release 或 Debug),版本號,渠道包,根據(jù)Tag打包。另外我們還需要加上打包途徑,AS打包還是Jenkins打的包,還要加一個時間戳。所有的參數(shù)列出來了,下面就配置Jenkins的參數(shù)化構(gòu)建吧~
在Jenkins項目主頁選擇配置,進入配置頁,在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等
下面直接放我的配置截圖:

build_type.png

product_flavor.png

app_version.png

is_jenkins.png

build_time.png

git_tag.png
配置完參數(shù)還不算完,我們要在下方構(gòu)建時候引用,首先找到構(gòu)建標簽處,將Tasks屬性值修改為:
clean assemble${PRODUCT_FLAVORS}${BUILD_TYPE} --stacktrace --debug
其中${PRODUCT_FLAVORS}
和&{BUILD_TYPE}
分別對應(yīng)上面的參數(shù)名。配置如圖:

看了圖大家肯定留意到了紅色框內(nèi)的選項而且很好奇吧,這個選項是APP_VERSION、IS_JENKINS、BUILD_TIME需要用到的,因為這三個參數(shù)需要注入到Android項目中的配置一樣,而紅色框中的這個選項可以幫我們侵入到gradle.properties文件中替換值,并且build.gradle文件能夠直接引用gradle.properties文件中的屬性,所以起到了侵入的效果。下面分別是我的gradle.properties和主項目的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
#代碼版本管理
VERSION_NAME=1.0.3
VERSION_CODE=5
IS_JENKINS=false
//build.gradle
def releaseTime() {
return new Date().format("yyyy-MM-dd")
}
/**
* 獲取本地svn版本號,不準,故本地打包不是用svn版本號
* @return
*/
def getSvnRevision() {
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = 'svn'
args = ['info']
standardOutput = os
}
def outputAsString = os.toString()
def matchLastChangedRev = outputAsString =~ /Last Changed Rev: (\d+)/
ext.svnRev = "${matchLastChangedRev[0][1]}".toInteger()
}
return svnRev
}
/**
* 根據(jù)不同平臺來獲取版本號
*/
def getSvnRevisionByPlatform() {
boolean flag = "true".equals(IS_JENKINS);
if (flag) {
ext.env = System.getenv()
ext.svnNum = env.SVN_REVISION?.toInteger()
return "$svnNum"
} else {
return getSvnRevision()
}
}
......
......
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName
def nowTime
if ("true".equals(IS_JENKINS)) {
//jenkins的動態(tài)參數(shù)插件,存在bug,自動構(gòu)建時無法獲取到時間,這里去掉時間
//這里的xxxxxx為自己的項目名稱
fileName = "xxxxxx_v${defaultConfig.versionName}_${variant.productFlavors[0].name}_${getSvnRevisionByPlatform()}.apk"
} else {
nowTime = releaseTime()
//本地獲取svn版本號不準,或者需要導(dǎo)入插件,故本地不獲取版本號
if (variant.buildType.name.equals('release')) {
fileName = "xxxxxx_v${defaultConfig.versionName}_${nowTime}_${variant.productFlavors[0].name}.apk"
} else if (variant.buildType.name.equals('debug')) {
fileName = "xxxxxx_t${defaultConfig.versionName}_${nowTime}_${variant.productFlavors[0].name}.apk"
}
}
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
這樣在Jenkins打包的時候上面三個參數(shù)就會隨著選擇變化而變化了。
GIT_TAG參數(shù)使用配置,只需在源碼管理處的Branch引用改為$GIT_TAG
引用參數(shù)名,如圖:

參數(shù)配置完畢,看一下主頁面的效果吧,現(xiàn)在立即構(gòu)建選項變成了* Build with Parameters***,完成圖:

提示:
如果選中了GIT_TAG中的任意版本都無法取消選中,只能刷新;
還有使用GIT_TAG時最好選擇tag版本大于等于支持Jenkins打包的版本,因為之前版本代碼中沒加需要侵入的屬性
2.按時打包
由于篇幅原因加上這個功能我沒用在項目中,所以請參考使用Jenkins搭建iOS/Android持續(xù)集成打包平臺的配置構(gòu)建觸發(fā)器部分。
3.構(gòu)建命名
每次構(gòu)建的時候,Build History模塊顯示是這樣的,如圖:

每次構(gòu)建都只顯示數(shù)字(#xx),這樣很不好看,我們想要它顯示更多的信息怎么辦呢?比如加入構(gòu)建者姓名、構(gòu)建的app版本、構(gòu)建的類型等。請看下圖:

set_build_name.png
配置完以后再次打包,變成了這個樣子,如圖:

build_history1.png
是不是很Nice,當然大家還可以根據(jù)需求自行發(fā)揮~
5.二維碼下載
二維碼下載功能,現(xiàn)在網(wǎng)上大多數(shù)的做法是通過蒲公英或者fir.im來生成二維碼,這兩個都是內(nèi)測平臺,我體驗過蒲公英,需要將文件傳到蒲公英網(wǎng)站然后他們生成二維碼返回,傳到別處總感覺怪怪的,于是我決定自己生成二維碼然后放在下載地址的文件夾中,通過鏈接顯示。
首先要在電腦上安裝python環(huán)境,請看http://www.cnblogs.com/yuanzm/p/4089856.html和(Python問題一)python 安裝PIL (Python Imaging Library )來進行安裝,如果已經(jīng)安裝繼續(xù)往下看。生成二維碼我用了qrcode這個庫,感謝大神的分享,這個庫如何使用就不介紹了,我只說一下Jenkins如何執(zhí)行python。
添加python的環(huán)境變量到Jenkins的環(huán)境變量中,文章前面有提到過,在系統(tǒng)管理->系統(tǒng)設(shè)置中,如圖添加python環(huán)境變量:

注意:鍵名需要和電腦上系統(tǒng)環(huán)境變量內(nèi)的鍵名保持一致。
然后打開項目配置頁面,在構(gòu)建版塊點擊添加構(gòu)建步驟,如圖:

在編輯框內(nèi)輸入qrcode項目的使用命令

注意:下載地址需要自己拼接,生成路徑也需要自己拼接。
這樣每次打包后都會在生成apk的文件夾內(nèi)生成一個對應(yīng)的二維碼。掃一掃就可以下載啦~~~
6.構(gòu)建后操作
構(gòu)建完成后,我希望將下載地址和二維碼放在Build History的版塊中,方便下載,那么我們就來設(shè)置一下,打開項目配置頁,如圖操作:

在Description輸入框內(nèi)添加
<a >下載連接</a>
7.郵件通知
打完包,我想通知需要下載的人怎么辦?發(fā)郵件~~Jenkins自帶了郵件功能,但是不太好用,所以我選擇了Email Extension Plugin這個插件來實現(xiàn)發(fā)郵件功能(已經(jīng)在插件列表中)。進入系統(tǒng)管理->系統(tǒng)設(shè)置頁面,如圖:


郵件格式:
[Jenkins構(gòu)建通知]$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!(郵件由Jenkins自動發(fā)出,請勿回復(fù)~)
項目名稱:$PROJECT_NAME
構(gòu)建編號:$BUILD_NUMBER
構(gòu)建狀態(tài):$BUILD_STATUS
觸發(fā)原因:${CAUSE}
構(gòu)建地址:<A HREF="${BUILD_URL}">${BUILD_URL}</A>
構(gòu)建輸出日志:<a >http://192.168.1.201:8090/job/${PROJECT_NAME}/${BUILD_NUMBER}/console</a>
下載地址:<a >http://192.168.1.88:8088/downloadApk</a>
二維碼下載:
最近修改:
${CHANGES, showPaths=false, format="%a:"%m"
", pathFormat="\n\t- %p"}
最終的效果圖是介個樣子的:

mail1.png