前言
Travis CI 是 GitHub 上开源项目采用持续集成的常见选择。为了给 豆芽 提供持续集成版本用于公开测试,我配置了 Travis CI,并自己编写了脚本将构建结果发布到另一个空项目的 Release 中,并将其间的过程和遇到的问题记录于此。
Travis CI 构建 Android 项目的时间较长,因此调试配置时十分耗时。希望我的经验能对他人有所帮助。
Travis CI
Travis CI 分为免费版(travis-ci.org)和付费版(travis-ci.com),两者之间没有相互的链接或说明,第一次配置时容易混淆。开源项目选择免费版即可。配置过程可以参考官方的 Getting Started 和 Android 项目配置。
关于 Android 项目有一些较为微妙的配置问题,我自己调试并查阅了一些 Issue 方才解决。
- 为了能够找到并下载最新的 Build Tools,需要启用最新版本的 Tools(
- tools
)。 - Lint 过程中如果 Platform Tools 版本低于 SDK 版本则会报错,需要启用最新版本的 Platform Tools(
-platform-tools
)。 - 为了能够找到并下载最新的 Platform Tools,需要已有最新的 Tools,因此与官方给出的样例不同,需要将
- tools
放置在- platform-tools
之前。
因此我的 Android 部分最终配置如下:
1 | android: |
详细配置可以参考我的 .travis.yml。
启用构建缓存
Gradle 是一个为缓存优化过的工具,因此官方也提供了相应的 开启缓存的方法。
1 | before_cache: |
应用签名
为了给 CI 版本的 APK 签名,需要提供相应的 keystore 和密码。Travis CI 提供了 在设置中定义环境变量 的方式来传递低敏感级的信息。
基于以上文档和一些搜索结果,并参考过 Shadowsocks-Android 的配置方式,我将我的签名配置编写为了从 signing.properties
、环境变量、终端输入三个层级进行获取的方式。
以下是我的 signing.gradle
:
1 | android { |
在 Android Studio 中进行 Gradle 同步时,System.console()
返回 null
,因而密码均为 null
,不会中断同步过程,也不影响调试版本的构建。
我创建了 signing.properties
和 signing.properties.travis
两个文件,在前者中填写 keystore 的路径并加入 .gitignore
,而将后者在 .travis.yml
的 before_script
中复制为 signing.properties
。
而在 Travis CI 的设置中,添加 STORE_PASSWORD
和 KEY_PASSWORD
两个环境变量即可。建议在环境变量值的两端加上单引号以避免特殊字符被 shell 错误处理。
获取版本信息
直接在 .travis.yml
中调用 git describe
或 git log
等命令是无法成功的,因为 Travis CI 采用了 git clone --depth=50
来进行 clone。相应地,需要先执行 git fetch --unshallow
来完成 clone。
我采用了 语义化版本(Semver)来命名版本。因此,我的版本名称采用了如下方式获取:
1 | version="$(git describe --long --tags | sed 's/^v//;s/-\([0-9]\+\)-g\([0-9a-f]\+\)/+\1.\2/')" |
例如,在名为 1.0.0-alpha
的 tag 后第 227 次短哈希值为 886f8ce
的 commit,对应的版本名即为 1.0.0-alpha.1+227.886f8ce
。
然后使用 sed -i 's/versionName .*/versionName "'"${version}"'"/' app/build.gradle
即可更新 build.gradle
中的 versionName
字段。
上传至 Release
GitHub 提供了在 Release 中上传二进制构建输出的功能。然而,如果直接在项目仓库中为每次 commit 添加 Release(和相应的 tag)则未免过于杂乱,因此我选择了新建 一个只有 README 的仓库,并将所有持续集成版本的 Release 创建在此仓库中。
为了实现此功能,我选择了通过 curl 调用 GitHub API 的方式来完成。经过查阅文档和大量的调试,我的脚本最终是如下编写的:
1 |
|
而设置 GITHUB_ACCESS_TOKEN
环境变量后的用法则如:
1 | ./upload-to-releases.sh 'zhanghai/DouyaCiBuilds' "${version}" "${description}" "douya-ci-${version}.apk" |
其他
如果无法确定错误原因,就多加些 echo
或者 cat
吧。
如果希望在 Lint 失败时查看输出,可以在 after_failure
中加入 cat app/build/outputs/lint-results-*.html
。
我所采用的配置都可以在 豆芽 中找到。
结语
为 Android 项目使用 Travis CI 的过程还算简单,但是也有一些微妙的问题需要解决,这令我花费了不少时间。而将每次的构建输出上传至另一个仓库的 Release 则是我考虑了一段时间后得出的方案,之前没见到过这种方式,用 curl 调用 GitHub API 也是第一次,同时再次感受到了 bash 的得心应手,总体上是一次十分有趣的体验。
因此,将我的配置过程和结果记录在此,希望对其他开发者有所帮助。