当 jenkins遇上Android Studio 3.0

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

概述

简介

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

JDK路径

Git路径
Git路径

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的继承问题,没有针对这些问题进行研究。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,858评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 1.介绍 如果你正在查阅build.gradle文件的所有可选项,请点击这里进行查阅:DSL参考 1.1新构建系统...
    Chuckiefan阅读 12,122评论 8 72
  • 版权声明:本文为LooperJing原创文章,转载请注明出处! · 读完这篇博客,你会了解到这些内容 1、Andr...
    LooperJing阅读 6,158评论 7 49
  • 今天老师发给我三朵小花。我们开学一个礼拜了,下星期一我们就要上新课了。今天老师发了试卷儿,我和爸爸一起完成的
    马涵晴阅读 198评论 0 0