概述
簡介
jenkins是一個開源軟體專案,是基於Java開發的一種持續整合工具,用於監控持續重複的工作,旨在提供一個開放易用的軟體平臺,使軟體的持續整合變成可能。
關於Android Studio持續整合的文章已經是滿天飛了,不過都是在AS 2.X的環境下面進行整合的,最近升級了AS 3.0之後,發現按照之前的一些方法無法在AS 3.0上順利整合,本來很簡單的幾步操作,卻除錯了很久,下面簡單記錄一下除錯的過程,可以讓一部分開發者少走彎路。
本文是基於GitLab整合,其餘的類似於Git,SVN其實原理都一樣,稍微有點區別,稍微除錯一下就好。
正文
基本知識
簡單的Groovy語法
普通識別符號:以字母、美元符號$或下劃線_開始,不能以數字開始
def date = new Date()複製程式碼
引號識別符號:使用單引號括住的字串
def name = 'android'複製程式碼
括號{}:表示引用
美元符號$:表示拼接
assemble${PRODUCT_FLAVOR}${BUILD_TYPE}
//相當於assembleWandoujiaRelease複製程式碼
基本的gradle命令
說來慚愧,平時都是點選AS的視覺化按鈕,很少去研究這些命令,直到這次debug,才發現,命令列在debug確實很有用
- gradlew clean //刪除app目錄下的build檔案
- gradlew build //編譯debug跟release包
- gradlew assembleDebug //編譯debug包
- gradlew assembleRelease //編譯release包
jenkins提供的全域性變數
這些變數可以在寫指令碼,包括gradle指令碼以及python指令碼的時候可以呼叫,我們也可以自己通過外掛來配置一些變數,用來進行構建不同的渠道包,下面選取了一些常用的:
- BRANCH_NAME :專案分支名稱
- CHANGE_AUTHOR:修改專案的作者
- BUILD_NUMBER:構建的序列號
- JOB_NAME:構建的專案名稱
- WORKSPACE:伺服器構建專案的位置
- JENKINS_HOME:jenkins的根目錄
- GIT_COMMITTER_EMAIL: Git提交作者的郵箱
登陸無效解決方案
當關掉jenkins的網頁,再重新開啟的時候,會讓你重新登入,但是當你輸入正確的使用者名稱跟密碼的時候,卻會提示你登陸無效,解決方案如下:
- 1.找到安裝目錄下的config檔案
- 2.找到useSecurity節點,將true改為false
<useSecurity>false</useSecurity>複製程式碼
- 3、找到authorizationStrategy跟securityRealm刪除
- 4、重啟jenkins,不知道怎麼重啟的,直接重啟電腦,再次啟動jenkins即可。
修改build.gradle檔案
AS3.0升級了gradle,改動較大,對比一下之前的程式碼,便可以發現區別,主要是在flavor的新增時必須增加一個dimension,apk輸出路徑做了較大的修改,為了減少程式碼量,只貼出了變動的部分
android {
signingConfigs {
config {
keyAlias 'demo'
keyPassword '123456'
storeFile file('chuangmei.jks')
storePassword '123456'
flavorDimensions "versionCode"
}
}
flavorDimensions "market"
productFlavors {
xiaomi {
dimension "market"
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
}
wandoujia {
dimension "market"
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
}
}
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = variant.productFlavors[0].name + new Date().format('yyyyMMddHHmmss') + '-' + variant.buildType.name + '.apk'
}
}
}複製程式碼
安裝jenkins
官網是jenkins.io,有三種安裝方式,分別是war包,native包以及docker容器,這裡我選擇的是native包,因為這種方式可以幫助我們安裝一部分外掛,基本上可以滿足我們的需求。
配置環境
外掛安裝
native包安裝
基本夠用,然後可以根據需求擴充套件
war包安裝
- Git plugin
- Gradle Plugin
- SSH plugin
這裡選擇的幾個外掛貌似能夠打出apk,網上有很多文章,會安裝很多外掛,一來沒必要,二來很多外掛已經過時了,最新的jenkins版本已經不支援,即使是通過本地上傳的方式,除非使用較老的jenkins版本。
系統設定
設定構建路徑
找到主目錄,然後點選高階
理解了groovy語法,上面的路徑就很好理解了,這個是可以隨便修改的
設定環境變數
找到全域性屬性,勾選環境變數,設定SDK路徑
全域性工具配置
name可以隨便填,對應的value則是相應的路徑
JDK路徑
Git路徑
Gradle路徑
配置專案
建立一個專案
名稱隨便填,這裡選擇自由風格的軟體專案,選擇第一個也可以,看自己需求
配置專案
引數化構建
引數名稱 | 引數型別 | 引數值 |
---|---|---|
BUILD_TYPE | choice | Build,Debug |
PRODUCT_FLAVOR | choice | Xiaomi,Wandoujia |
構建環境
配置相應的構建環境
構建
根據之前設定的條件進行編譯操作
構建後操作
主要是可以用來收集構建出來的apk以及相應的編譯檔案
開始構建
其實最花時間的還是這裡,因為,升級了AS 3.0之後,gradle的版本變成了4.1,改動特別大,所以升級要慎重,但是已經升級了,問題還是得解決。
執行 gradle clean assembleRelease
是從這一行程式碼進行報的錯,提示我說是在release合併資源的時候報錯了,下面是具體的資訊
下面最後一行開始報錯
:app:generateAndroidReleaseResValues
:app:generateAndroidReleaseResources
:app:mergeAndroidReleaseResources複製程式碼
然後錯誤一直不斷重複
AAPT err(Facade for 1119711668) : No Delegate set : lost message:\\?\C:\Windows\System32\config\systemprofile\.gradle\caches\transforms-1\files-1.1\appcompat-v7-25.4.0.aar\76d6a769daf730ed767830374ebcd3bd\res\drawable-hdpi-v4\abc_textfield_search_default_mtrl_alpha.9.png ERROR: Unable to open PNG file複製程式碼
追蹤堆疊資訊 --stacktrace --debug
* What went wrong:
16:04:41.129 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Execution failed for task ':app:mergeAndroidReleaseResources'.
16:04:41.129 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Error: java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.AaptException:
16:04:41.129 [ERROR]複製程式碼
對吧,日誌都出來了,看地我是一臉懵逼,只看懂了app:mergeAndroidReleaseResources。
漫長的debug之路
環境檢查
我的專案在本地是成功編譯過的,不管是debug還是release都是OK的,clean也是沒問題的,所以我當時就覺得應該是服務端編譯的問題,但是服務端的程式碼是從gitlab上面獲取的,跟我本地的是一模一樣的,不應該有問題,難道是編譯環境出了問題嗎,因為上面的報錯都是跟gradle相關的,所以我就列印了各自的gradle:
本地grade版本:
Gradle 4.1
------------------------------------------------------------
Build time: 2017-08-07 14:38:48 UTC
Revision: 941559e020f6c357ebb08d5c67acdb858a3defc2
Groovy: 2.4.11
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_131 (Oracle Corporation 25.131-b11)
OS: Windows 10 10.0 amd64複製程式碼
服務端grade版本:
Gradle 4.1
------------------------------------------------------------
Build time: 2017-08-07 14:38:48 UTC
Revision: 941559e020f6c357ebb08d5c67acdb858a3defc2
Groovy: 2.4.11
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_131 (Oracle Corporation 25.131-b11)
OS: Windows 10 10.0 amd64複製程式碼
是一樣的,呵呵噠,只能再分析別的原因了,其實這個時候是沒有什麼思路的,因為太詭異了,基本上什麼都一樣了,但是服務端就是編譯不成功,我能怎麼辦,我也很絕望啊。然後就用Google搜尋了一下,搜到的答案基本上都不是太相關,只好作罷。
目錄對比
其實在對比環境之後當時就想著回退版本了,畢竟已經摺騰了很久了,不過轉念一想,程式設計師不就是為問題而生的嗎,然後又冷靜思考了一會兒,還有什麼是不一樣的,終於發現了,目錄,服務端編譯的目錄跟本地的目錄不一樣,可是這個在理論上是沒有影響的,不過值得一試。然後我就直接開啟了服務端在本地的專案,然後進行檢查。
gradle clean
本地
E:\Jenkins\workspace\Test>gradle clean
> Configure project :app
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:clean'.
> Unable to delete file: E:\Jenkins\workspace\Test\app\build\intermediates\merged-not-compiled-resources\android\release\anim\abc_fade_in.xml複製程式碼
服務端
[Gradle] - Launching build.
[Test] $ cmd.exe /C "C:\Users\pangchao\.gradle\wrapper\dists\gradle-4.1-all\bzyivzo6n839fup2jbap0tjew\gradle-4.1\bin\gradle.bat clean && exit %%ERRORLEVEL%%"
:clean
:app:clean
BUILD SUCCESSFUL in 20s
2 actionable tasks: 2 executed
Build step 'Invoke Gradle script' changed build result to SUCCESS複製程式碼
是不是很意外,一個失敗一個成功,而且居然是本地失敗,服務端成功,很詭異。
gradle assembleRelease
本地打包
E:\Jenkins\workspace\Test>gradle assembleMumayi
> Configure project :app
[E:\Jenkins\workspace\Test\app\build\outputs\mapping\mumayi\release\dump.txt]...
Removed unused resources: Binary resource data reduced from 559KB to 539KB: Removed 3%
BUILD SUCCESSFUL in 31s
51 actionable tasks: 49 executed, 2 up-to-date
E:\Jenkins\workspace\Test>複製程式碼
服務端打包
[Gradle] - Launching build.
:app:assembleMumayiRelease
:app:assembleMumayi
BUILD SUCCESSFUL in 7s
51 actionable tasks: 6 executed, 45 up-to-date
Build step 'Invoke Gradle script' changed build result to SUCCESS
Finished: SUCCESS複製程式碼
可以看到先由本地編譯,然後再經過服務端編譯時都可以成功的,但是之前我們是先經過服務端編譯時不能成功的,也就是說,我們要先進入到服務端的目錄本地成功編譯一次之後,才能在服務端成功編譯。最重要的一點是服務端打包之間不能進行clean,具體原因我也不是很清楚,應該是跟AS 3.0升級的特性有關係,改天研究一下官方文件才能知道具體原因,也就是說目前的情況如下:
也就是在AS3.0的基礎上,如果我想在服務端自動構建apk,那麼首先必須在本地成功編譯一次,既然是這樣,那麼我們乾脆在本地先把所有渠道的Debug包Release包先統一編譯一次,這樣的話在服務端不管想要打哪種包都是OK的,就這麼愉快地決定了。
- gradlew clean
- gradlew build
這樣就好了,剩餘的操作跟之前的AS 2.X基本一致,OK,到此為止,AS 3.0也可以很輕鬆的使用jenkins,雖然折騰了很久,但是最終還是解決了問題。
後續
整合過jenkins的小夥伴們可能知道,其實還有很多功能沒有細說,比如說打完包後將安裝包自動上傳到fir或者蒲公英,生成一個二維碼,傳送郵件到指定的收件人,其實這些都比較好解決的,網上已經有很多教程了,而且這些都可以通過外掛跟指令碼實現,下面貼一下相關的外掛,大家Google或者百度一下就可以搞定了,本文主要在於分析一下AS 3.0的繼承問題,沒有針對這些問題進行研究。