Gradle For Android系列8:设置CI(集成开发环境)

持续集成(CI)是一种开发实践方式,需要团队中的开发人员定期集成他们的工作,通常每天多次。每次推送到主代码仓库都需要通过自动构建进行验证。这种做法有助于尽快发现问题,从而加快开发速度,并提高代码的质量。大拿Martin Fowler写了一篇关于这个主题的文章,解释了这些概念,并描述了最佳实践

有几种方式可以为Android设置CI。最广泛使用的是Jenkins,TeamCity和Travis CI。Jenkins有最大的生态系统,有大约1000个可用的插件,Jenkins本身是一个开源项目与现在仍然有很多贡献者。TeamCity是JetBrains的产品,JetBrains我们应该都很熟悉,JetBrains也创建了IntelliJ IDEA(Android Studio就是基于此开发的)。 Travis CI是相对较新,主要用于开源项目。

这一章节,你将学习到这些CI系统,以及如何让Gradle在这些系统上工作。在本章结尾处,你还将学到一些Gradle技巧,使CI更容易。

这一章节,主要包括如下几个部分:

  • Jenkins
  • TeamCity
  • Travis CI
  • 更多技巧

Jenkins

Jenkins最初由Sun Microsystems于2005年发布,取名为Hudson。多年来,它逐渐成长为Java社区中最受欢迎的CI系统。在Oracle收购Sun Microsystems后不久,Oracle和Java社区之间就Hudson存在冲突。当时双方都没能妥协,因为Hudson名称由Oracle拥有,社区就只能在名为Jenkins的项目上继续工作。

Jenkins的强大在于它的插件系统。每个在构建系统中需要新功能的人都可以创建一个扩展Jenkins功能的新插件。这也是为什么为Android应用或Library设置自动化集成非常简单的原因。

Jenkins配置

如果你从来没有在Build Server上安装并运行过Jenkins,请从Jenkins官网下载并按照官方介绍的步骤操作。

在开始使配置Jenkins之前,你需要确保Build Server上具有构建Android应用和Library项目所需的所有依赖包。要在Java中构建任何东西,你首先需要下载并安装JDK,这可以从Java官网下载。

您还需要确保安装了Android SDK和Build tools。除非你打算在Build Server上打开或编辑项目,否则不必在构Build Server上安装IDE。如果你只是想安装Android SDK,你可以从Android Developer上下载,一旦下载并安装了软件包,你需要在SDK目录中执行android文件,以便你可以安装所需的API和构建工具。

一旦安装了Java和Android SDK,您需要在Jenkins中配置这些。首先打开你的Web浏览器并导航到Jenkins Home页。转到Manage Jenkins(管理Jenkins) | Configure System(系统配置) 并滑动到Global properties(全局属性)。在其中添加两个环境变量ANDROID_HOME和JAVA_HOME,并将它们的值设置为正确的Android SDK和JDK所在的目录,如下面的截图所示:

Jenkins配置Android构建环境

Jenkins配置成功后,就可以在Jenkins中创建一个CI项目。你应该做的第一件事是设置代码仓库地址,以便Jenkins知道在哪里获得对应项目的源代码。你可以通过构建触发器在项目有新的操作(如:有新的merge或者新的push)时自动触发CI构建,或者你也可以选择只做手动触发构建。构建Android项目,你需要在Jenkins新添调用Gradle脚本的构建步骤。你可以配置Jenkins使用Gradle wrapper,使用Gradle wrapper不仅消除了在构建服务器上手动安装Gradle的需要,而且还确保自动处理Gradle的更新。配置时,勾选Make gradlew executable选项。

如果需要在构建过程添加详细的日志输入,并且添加两个标志开关–info–stacktrace。信息开关用于打印构建过程的详细步骤,这在出现错误情况时很有用。如果构建引起异常,stacktrace开关将打印出此异常的starcktrace。有时你可能需要更详细的信息,在这种情况下,你可以使用full-stacktrace开关。

最后配置需要执行的Gradle任务。首先,执行clean任务,以确保没有留下任何先前的构建记录。其次,执行build任务,触发构建所有build variant。Jenkins配置应该如下所示:

按以上步骤配置完成后,即可执行构建

如果你的Build Server安装在64位Linux计算机上,可能会遇到此异常java.io.IOException: Cannot run program “aapt”: error=2, No such file or directory ,这是因为AAPT是一个32位应用程序,需要一些额外的库才能在64位机器上运行。 要安装必需的库,请使用以下命令:
$ sudo apt-get install lib32stdc ++ 6 lib32z1

如果构建成功,构建任务会为所有Build Variant生成APK。您可以使用指定的Gradle任务来发布这些APK。我们将在本章结尾处提到自动发布,因为它独立于构建系统。

TeamCity

与Jenkins不同,TeamCity由JetBrains开发和管理,是一个专利产品,当前只能用于开源项目,同时TeamCity对Android构建的支持是安装即可用。

TeamCity配置

如果你的Build Server还没有安装TeamCity,请从JetBrains网站下载并按照步骤安装。

要使用TeamCity构建Android应用和库,你需要确保JDK,Android SDK和Android Build tools安装在构建服务器上。你可以在Jenkins网站上找到部分相关说明。你还需要将ANDROID_HOME添加到机器的环境变量,并将其指向Android SDK目录。

与Jenkins不同,TeamCity不需要任何插件来触发Gradle构建,因为TeamCity内置了对运行Gradle的支持。

TeamCity设置Android构建

要设置Android构建,你需要创建一个新项目,你只需要填写一个名称即可。项目创建后,开始配置: 首先,需要添加源码仓库(Git或SVN等)配置,以便TeamCity可以找到项目的源代码。然后,你需要创建一个新的build configuaration,并且将源码仓库的配置绑定到构建配置上。设置完成后,你就可以添加一个新的build step。如果使用Auto-detect build steps,TeamCity将根据项目的内容自动检测必要的构建步骤。在基于Gradle的Android项目的情况下,TemaCity配置的结果如下所示:

TeamCity检测到项目使用Gradle,甚至Gradle wrapper的存在。你可以选择Gradle构建步骤,并将其添加到构建配置中。如果你不需要执行任何高级操作,这足以确保Android应用程序被正确构建。你可以打开项目概述并单击Android项目的Run…按钮来开始构建。

Travis CI

如果你的项目托管在GitHub上,那么你可以将Travis CI用做CI系统。Travis CI是一个开源托管的持续集成系统可免费用于公共存储库。有一个私人存储库的付费计划,但在本书中,我们将只看免费选项。

当Travis检测到有新提交push到存储库时就会自动启动一个新的构建。默认情况下,Travis会构建所有的分支,而不仅仅是master分支。它也会自动构建Pull Request(GitHub项目的功能合并请求)。

由于Travis内部运行机制,你无法在Build Server部署Travis,你需要做的只是创建一个配置文件,包含Travis构建应用程序或Library所需的各种信息。

Travis CI配置Android构建

如果要为项目启用Travis构建,首先你需要登录到Travis CI并将你的帐户连接到GitHub。一旦完成,你需要在设置中启用你想要构建的项目。

为了配置构建过程,Travis需要你创建一个名为.travis.yml的文件,其中包含整个设置。 要配置Android项目,您需要定义语言属性并添加一些Android特定的属性:

1
2
3
4
5
6
7
8
9
language: android
android:
components:
# The build tools version used by your project
- build-tools-22.0.1
# The SDK version used to compile your project
- android-22
# Additional components
- extra-android-m2repository

language设置指定要运行哪种构建。在上面代码中,language指定为android表示构建android程序。 Android特定的属性包括需要使用的构建工具的版本和Android SDK版本。Travis将在运行构建任务之前下载这些文件。如果你使用support Library或Google Play服务,这都需要明确指定,因为Travis也需要下载这些依赖关系的Library。

travis配置中每个有规定一定要配置构建工具和SDK版本,但如果你确保版本与build.gradle文件中指定的版本一致,则会尽量减少一些异常问题的出现。

如果Android项目是在Windows平台上创建的,Gradle wrapper可能会有权限的问题。因此,在运行实际构建脚本之前修需要赋予gradlew文件正确的权限。你可以像这样添加预构建步骤:

1
2
3
before_script:
# Change Gradle wrapper permissions
- chmod +x gradlew

启动Android构建,请将此行添加到Travis配置文件:

1
2
# Let's build
script: ./gradlew clean build

上面的命令将运行Gradle wrapper程序,就像在开发人员机器上一样,执行Gradle clean和build任务。

完成配置Travis后,你可以提交并将文件推送到项目的GitHub仓库。如果一切都正确设置,Travis将开始构建,你可以在Travis网站上跟踪。如下是项目成功构建后的样子:

Travis还会在每次构建后发送电子邮件报告。如果你是定期获取pull request的开源库维护者,这可能特别有用。当构建成功时,Travis的报告电子邮件如下所示:

你很快会注意到Travis有一个很大的缺点,就是速度。 Travis不会给你一个特定的机器,而是为你触发的每个构建启动一个vanilla虚拟机。这意味着对于每个新的构建,Travis必须下载并安装Android SDK和构建工具,才能开始构建你的应用程序或Library。

上面说了,Travis是免费的,这使得它完美使用开源项目,Travis会自动构建pull request,当有人向你的代码提交PR时,这可以让你放心合并PR。

更多技巧

大多数现代持续集成系统在默认情况下或通过插件的方式都能支持Gradle。这意味着,你可以创建各种Gradle任务,以进一步自动化开发流程,而不仅仅是打包的应用程序或Library。Gradle能将额外的构建步骤组合成一个task或者plugin,这独立于CI系统本身,所以增加额外的构建任务就变得更加方便。比如,依赖Jenkins插件的构建任务就不可能在没有安装Jenkins的情况下运行,这使得构建任务不能快速的一直到其他CI系统,但是Gradle任务就可以轻松地移植到不同的项目。在本节中,我们将介绍使用Gradle任务和插件进一步自动构建和部署应用程序和库的几种方法。

sdk-manager插件

你可能会遇到的一个问题是,构建服务器上的Android SDK不是最新的。当你更新应用或库的SDK版本时,还需要在构建服务器上安装新的SDK。如果你有多个构建代理,这变得异常麻烦。

由于社区的努力,有一个Gradle插件,它负责检查构建是否依赖于不存在的Android SDK版本。如果SDK不存在,插件将自动下载。

SDK-manager插件不仅将下载构建配置文件中指定的编译SDK,还将下载构建工具和平台工具的正确版本。 如果你的项目对支持库或Google Play服务有依赖性,则插件也将下载指定的版本。

sdk-manager是一个开源插件,你可以在GitHub上找到它的sdk-manager源码。

运行测试

如果你想在构建服务器构建过程中运行单元测试(JUnit或Robolectric),你只需要将相应的任务添加到Gradle执行。如果你想运行任何功能性测试,你将需要一个模拟器来安装你的应用程序,所以你可以使用gradlew connectAndroidTest来运行测试。

运行功能测试最简单的选择是在Build Server上启动一个模拟器,并保持它一直打开。不幸的是,这不是一个最佳的解决方案,因为Android模拟器很容易发生随机崩溃,特别是当开启了很长时间后。

如果你使用Jenkins,有一个称为Android模拟器插件的Jenkins插件,可以配置为每个你需要构建的应用程序或Library启动一个模拟器。TeamCity也有一个活跃的插件生态系统,有一个称为Android模拟器的插件,与Jenkins插件一样,也是为每次构建设置一个模拟器。你可以在TeamCity官方插件页面上找到它以及其他TeamCity的插件。

Travis CI有能力启动一个模拟器,但这是一个实验功能。如果要尝试它,请将此代码段添加到.travis.yml配置文件中,以在Travis构建期间启动Android模拟器:

1
2
3
4
5
6
7
# Emulator Management: Create, Start and Wait
before_script:
- echo no | android create avd --force -n test -t android-22 --
abi armeabi-v7a
- emulator -avd test -no-skin -no-audio -no-window &
- android-wait-for-emulator
- adb shell input keyevent 82 &

“android-wait-for-emulator”指令告诉Travis等待模拟器启动。当模拟器启动时,执行“adb shell input keyevent 82 &”以解锁屏幕。之后,你即可以执行Gradle测试。

持续发布

为了协助开发人员自动部署Android应用,Google发布了Google Play Developer API,这是一种以程序化化方式将APK传送至Google Play的API,此API再也无需你打开浏览器,登录Google Play,使用网络界面上传APK这些繁琐的步骤。你不必基于Google Play开发者API创建自己的发布脚本,有许多第三方的Gradle插件就支持,通过插件,你可以直接在构建系统成功构建之后,将APK推送到Google Play上。

有一个名为Google Play Android Publisher的Jenkins插件,可以处理发布任务。然而,更好的选择是使用Gradle插件,以便你可以从任何设备和任何其他的持续集成系统执行发布任务。Android社群中的一些人创建了一个基于Google Play Developer API的Gradle插件,可以配置整个发布过程。 你可以在GitHub上找到Gradle Play Publisher Gradle插件源代码或直接依赖Maven Central或JCenter的插件包。

使用此插件,需要将如下代码添加到主build.gradle文件中:

1
2
3
4
5
6
7
8
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.triplet.gradle:play-publisher:1.0.4'
}
}

然后在Android模块的build.gradle文件中应用插件:

1
apply plugin: 'play'

当插件被应用到项目中后,你可以在gradle任务列表中发现一些新任务:

  • publishApkRelease 上传apk
  • publishListingRelease 上传描述和图片
  • publishRelease 上传所有apk和各种其他信息

如果你有不同的Build Type,还可以执行这些特定版本的publish任务,例如publishApkFreeRelease和publishApkPaidRelease。

要访问Google Play开发者API,你需要设置Google Play帐户。这个设置超出了本文档的范围,但如果你想使用Gradle Play Publisher插件,账号配置是必需的。使用详细步骤,可以按照Google Play Developer API文档中的步骤操作。官方介绍

创建服务帐户后,你可以在构建配置文件中输入密钥,如下所示:

1
2
3
4
play {
serviceAccountEmail = 'serviceaccount'
pk12File = file('key.p12')
}

play块用于Gradle Play Publisher插件的属性。除了服务帐户密钥配置,你还可以指定APK应推送到的渠道:

1
2
3
play {
track = 'production'
}

默认渠道是alpha,但你可以将其更改为beta或production。

Beta发布

Android应用的测试发布有很多选项,例如Google Play Store本身的测试版。另一个选项是Crashlytics,Creashlytics很好的集成了Gradle。Crashlytics的团队创建了一个自定义插件,它不仅创建了新的Gradle任务来发布版本到他们的平台,还整合了Android插件的任务来处理ProGuard混淆的mapping。

使用Crashlytics,请按照其网站上的步骤操作。一旦你设置了它,它将开始钩到你的构建。 Crashlytics会暴露一个名为crashlyticsUploadDistributionInternal的新任务,此任务可以用来上传APK到Crashlytics。要推送新版本的应用程序,你首先需要使用build或assemble任务来构建它。一旦APK准备就绪,你就可以使用crashlyticsUploadDistributionInternal任务将其上传到Crashlytics。Crashlytics插件为你项目中的每个build variant创建一个上传任务。

由于自定义Gradle插件,开发人员很容易开始使用Crashlytics。它也使你轻松地将测试版本上传到Crashlytics,因为只需要在构建过程中执行一个额外的任务。这是一个很好的例子来说明Gradle的正确使用有多强大,以及一个好的Gradle插件如何使开发人员的生活更容易。

总结

在本章中,你学习到了一些流行的CI系统,并了解如何使用它们来自动化构建Android应用和Library,其中包括如何配置CI系统以使用Gradle构建Android项目。然后,你学习了几个Gradle插件,以帮助进一步自动化构建
和部署流程。

在下一章中,你讲学习到Gradle的一些更高级的功能和基于Gradle构建的优化,还将了解如何通过直接从Gradle中使用Ant任务来迁移大型Ant构建配置,并以小步骤将它们移植到Gradle中

写得好,就打赏一下吧!