當 jenkins趕上Android Studio 3.0

概述

簡介

jenkins是一個開源軟件項目,是基於Java開發的一種持續集成工具,用於監控持續重複的工做,旨在提供一個開放易用的軟件平臺,使軟件的持續集成變成可能。
關於Android Studio持續集成的文章已是滿天飛了,不過都是在AS 2.X的環境下面進行集成的,最近升級了AS 3.0以後,發現按照以前的一些方法沒法在AS 3.0上順利集成,原本很簡單的幾步操做,卻調試了好久,下面簡單記錄一下調試的過程,可讓一部分開發者少走彎路。java

本文是基於GitLab集成,其他的相似於Git,SVN其實原理都同樣,稍微有點區別,稍微調試一下就好。python

正文

基本知識

簡單的Groovy語法

普通標識符:以字母、美圓符號$或下劃線_開始,不能以數字開始android

def date = new Date()複製代碼

引號標識符:使用單引號括住的字符串git

def name = 'android'複製代碼

括號{}:表示引用
美圓符號$:表示拼接程序員

assemble${PRODUCT_FLAVOR}${BUILD_TYPE}
//至關於assembleWandoujiaRelease複製代碼

基本的gradle命令

說來慚愧,平時都是點擊AS的可視化按鈕,不多去研究這些命令,直到此次debug,才發現,命令行在debug確實頗有用docker

  • gradlew clean //刪除app目錄下的build文件
  • gradlew build //編譯debug跟release包
  • gradlew assembleDebug //編譯debug包
  • gradlew assembleRelease //編譯release包

jenkins提供的全局變量

這些變量能夠在寫腳本,包括gradle腳本以及python腳本的時候能夠調用,咱們也能夠本身經過插件來配置一些變量,用來進行構建不一樣的渠道包,下面選取了一些經常使用的:bash

  • 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>複製代碼
  • 三、找到authorizationStrategy跟securityRealm刪除
  • 四、重啓jenkins,不知道怎麼重啓的,直接重啓電腦,再次啓動jenkins便可。

修改build.gradle文件

AS3.0升級了gradle,改動較大,對比一下以前的代碼,即可以發現區別,主要是在flavor的添加時必須增長一個dimension,apk輸出路徑作了較大的修改,爲了減小代碼量,只貼出了變更的部分app

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路徑

JDK路徑
JDK路徑

Git路徑
Git路徑
Git路徑

Gradle路徑
Gradle路徑
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的繼承問題,沒有針對這些問題進行研究。

相關文章
相關標籤/搜索