Lee Blog

专注移动开发

0%

Android Gradle最佳实践系列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上安装AndroidStudio。安装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配置的结果如下所示:

通过选择Gradle构建步骤,并将其添加到构建配置中,TeamCity可以自动检测到项目使用Gradle,甚至可以直接调用Gradle wrapper。我们可以打开项目概述并单击Android项目的 Run… 按钮来开始构建。

Travis CI

如果我们的项目托管在GitHub上,那么可以将 Travis CI 用做CI系统。Travis CI是一个开源托管的持续集成系统可免费用于公共存储库,还有有一个私人存储库的付费版本,但在本章节中,我们将只学习免费相关选项配置。

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

由于Travis内部运行机制,我们无法在Build Server部署Travis,而需要做的只是创建一个配置文件,包含Travis构建Android应用程序或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不会分配一个特定的机器来运行build任务,而是触发的每个构建启动一个vanilla虚拟机。这意味着对于每个新的构建,Travis必须下载并安装Android SDK和构建工具,才能开始构建我们的应用程序或Library。

更多技巧

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

运行测试

如果我们想在构建服务器的构建过程中运行单元测试(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,使用UI界面上传APK这些繁琐的步骤。我们不必基于Google Play开发者API创建自己的发布脚本,有许多现成的第三方的Gradle插件就支持,通过插件,可以直接在构建系统成功构建之后,将APK推送到Google Play上。

有一个名为Google Play Android Publisher的Jenkins插件,可以处理发布任务。然而,更好的选择是使用Gradle插件,而不是CI环境的插件,这样方便便我们可以从任何设备和任何其他的持续集成系统执行发布任务。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文档中的步骤操作。[官方介绍](https://developers.google.com/android- publisher/getting_started)

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

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插件会自动hook到打包流程中。 Crashlytics会暴露一个名为 crashlyticsUploadDistributionInternal 的新任务,此任务可以用来上传APK到Crashlytics。要推送新版本的应用程序,首先需要使用build或assemble任务来构建它。一旦APK准备就绪,你就可以使用 crashlyticsUploadDistributionInternal 任务将其上传到Crashlytics。Crashlytics插件为项目中的每个build variant创建一个上传任务。

由于自定义Gradle插件,开发人员很容易开始使用Crashlytics,只需要在构建过程中执行一个额外的任务,我们就可以轻松地将测试版本apk上传到Crashlytics上。Crashlytics的例子说明了正确使用Gradle有多强大,以及一个好的Gradle插件如何使开发人员开发工作更轻松。

总结

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

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