搭建CI环境:配置Jenkins/GitHub Actions Runner、Android SDK与Build Tools安装、环境变量设置

CI环境搭不好,后面所有自动化测试都是空中楼阁。我自己带团队的时候,遇到最多的新手问题就是:照着文档配完了,但一跑就挂,而且不知道挂在哪。说白了,CI环境搭建不是「装个软件」那么简单,它是一整套工具的协同工作。今天咱们就把它拆开揉碎了讲。

1. 整体架构:CI环境由哪些部分组成?

先看一张图,你心里就有谱了:

CI环境搭建核心流程 机器 / 镜像准备 Runner / Agent 配置 JDK 安装 Android SDK Build Tools / NDK 环境变量配置 验证 + 运行测试 常见选择 · GitHub Actions (托管) · Jenkins (自托管) · GitLab CI / CircleCI

嗯,流程其实不复杂:从机器到Runner,再到JDK、SDK、Build Tools,最后环境变量收尾。每一步都环环相扣,有一个断链,编译就跑不起来。

2. 机器 / 镜像准备

我自己习惯用 Linux 作为 Runner 系统。为什么?因为 Android SDK 的工具链全部是 Linux first,Windows 上偶尔会有路径编码的问题,macOS 倒是可以但成本高。如果用的是 GitHub Actions,官方提供的 ubuntu-latest 镜像已经预装了大部分工具,但你得注意版本——它默认的 SDK 可能不是你项目需要的版本。

小提示:用 Jenkins 的话,我建议在 Docker agent 里运行,一句话搞定依赖隔离。比如 android-sdk:latest 镜像,我项目里直接拉下来用,省去重复安装的麻烦。

3. Runner / Agent 配置

3.1 GitHub Actions Runner

GitHub Actions 有两种模式:

  • GitHub 托管 Runner:配置简单,直接用 runs-on: ubuntu-latest。但是并发数有限,而且你不一定拿得到 root 权限。
  • 自托管 Runner:你在自己的机器上跑 ./config.sh --url https://github.com/your/repo -- xxxx。我个人更推荐这种,因为你可以控制硬件、缓存加速、还能跑需要 root 的测试。

我曾经踩过一个坑:自托管 Runner 默认用 ubuntu 用户,没有 sudo 权限,导致安装 SDK 时 sdkmanager 写不进去系统目录。解决办法是给 Runner 用户配置 sudo 免密,或者把 SDK 装到用户目录下。

3.2 Jenkins Agent

Jenkins 的话,我用 pipeline 语法配置 agent:

pipeline {
    agent {
        label 'linux-android'
    }
    stages {
        stage('Setup') {
            steps {
                // 这里做环境准备
            }
        }
    }
}

Jenkins 的 Agent 可以是固定节点,也可以是动态 Docker 容器。我个人偏向用 Docker,因为不同分支或不同项目可能需要不同的 SDK 版本,容器切换比清理机器快多了。

4. JDK 安装

Android 编译依赖 JDK,而且版本要对。Android Gradle Plugin 8.x 要求 JDK 17,旧版项目可能还在用 JDK 11。你想想看,如果 JDK 版本不对,编译一开始就报 Unsupported class file major version,那只能干瞪眼。

我的做法:在 Runner 上装多个 JDK 版本,然后通过 JAVA_HOME 环境变量切换。比如安装 openjdk-17 和 openjdk-11,然后在 Jenkins pipeline 里:

withEnv(['JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64']) {
    sh './gradlew assembleDebug'
}

别问我为什么强调这个——我试过在同一个 Runner 上同时跑两个项目,一个用 JDK 11 一个用 JDK 17,结果 Gradle daemon 冲突,编译全挂了。从此我每个 agent 只跑一个项目,或者用容器隔离。

5. Android SDK 与 Build Tools 安装

这是整个环境搭建里最核心的部分,也是最容易出错的地方。

5.1 安装命令行工具

Google 现在推荐的安装方式是先下载 commandlinetools。步骤如下:

  1. 从官方下载 commandlinetools-linux-xxx_latest.zip。
  2. 解压到 /opt/android-sdk(或 $HOME/Android/Sdk)。
  3. 运行 sdkmanager --install "platforms;android-33" "build-tools;33.0.2"。

你看,核心命令就这一条。但是——这里有个陷阱:sdkmanager 默认会检查 Java 环境,而且它自己也是一个 Java 程序。你装了 JDK 但 JAVA_HOME 没设对,它就会直接退出了,连个像样的提示都没有。我曾经在 Jenkins 日志里翻了十分钟才找到原因。

注意:一定要确保 JAVA_HOME 指向 JDK 目录,而不是 JRE。可以用 sdkmanager --list 测试一下能不能正常输出。

5.2 我需要装哪些包?

一个典型的 Android CI 环境需要安装以下内容:

组件 作用 安装命令示例
platforms;android-34 编译目标平台 API sdkmanager "platforms;android-34"
build-tools;34.0.0 构建工具链 (aapt, dx, zipalign) sdkmanager "build-tools;34.0.0"
ndk;26.1.10909125 NDK (如果你有 C/C++ 代码) sdkmanager "ndk;26.1.10909125"
cmake;3.22.1 CMake (NDK 构建用) sdkmanager "cmake;3.22.1"

嗯,别懒省事把所有平台都装了,那样磁盘空间会爆炸。我一般只装项目 compileSdk 对应版本,以及兼容的 build-tools。项目里 build.gradle 写什么,我就装什么。

6. 环境变量设置

配置环境变量是最后一个环节,也是「功亏一篑」的高发区。

6.1 必须设置的环境变量

无论你用 Jenkins 还是 GitHub Actions,至少需要设置下面三个:

  • ANDROID_HOME —— 指向 SDK 根目录,比如 /opt/android-sdk。
  • ANDROID_SDK_ROOT —— 和上一个功能相同,但 Gradle 优先使用这个。我建议两个都设,免得兼容性问题。
  • PATH —— 把 $ANDROID_HOME/tools/bin 和 $ANDROID_HOME/platform-tools 加进去。

我在 Jenkins pipeline 里是这样写的:

withEnv([
    'ANDROID_HOME=/opt/android-sdk',
    'ANDROID_SDK_ROOT=/opt/android-sdk',
    'PATH+SDK=/opt/android-sdk/tools/bin:/opt/android-sdk/platform-tools'
]) {
    sh 'sdkmanager --list'
}

6.2 一个经典的「环境变量没生效」案例

我曾经遇到这样一个问题:本地开发编译正常,CI 上一跑就报 Could not find tools.jar。查了半天,发现是 Jenkins 服务以 systemd 方式启动,而 systemd 的 EnvironmentFile 里没有加载 JDK 路径。

解决方案:在 /etc/systemd/system/jenkins.service 里加入 Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64",然后重启服务。自托管 Runner 同理,要在启动脚本或者 .bashrc 里显式设置。

经验总结:CI 环境中的环境变量不会自动继承自你本地 shell。Runner 启动时用的什么用户、什么 shell 模式,决定了它能看到哪些变量。最稳妥的方法是在 pipeline 的 step 里用 withEnv 或 env 块显式设置。

7. 快速验证步骤

所有配置完事后,跑一个最小化检查:

  1. java -version —— 检查 JDK 版本。
  2. sdkmanager --list —— 检查 SDK 可访问。
  3. gradle wrapper --version —— 检查 Gradle。
  4. 执行 ./gradlew assembleDebug —— 跑一次完整编译。

嗯,如果前两步正常,第三步出问题就去查 Gradle 版本兼容性。如果前三步都正常但第四步挂了,那大概率是项目自己的依赖问题,跟环境无关了。

8. 工具版本对照速查

为了方便你快速对应,我整理了一个 Android CI 环境常用版本搭配表:

Android Gradle Plugin Gradle 版本 JDK 版本 Build Tools 推荐
8.2 8.5+ 17 34.0.0
7.4 7.5+ 11 或 17 33.0.2
4.2 6.7+ 8 或 11 30.0.3

这张表你记着就行,项目升级 AGP 时记得同步升级 Gradle wrapper。我见过有人只升级了 AGP,Gradle 还是老版本,结果 DSL 语法不兼容,编译直接报 Unsupported method。

9. 一句话总结

搭建 Android CI 环境,说白了就是:选好机器 → 配好 Runner → 装对 JDK → 下对 SDK → 设好变量。每一步都有坑,但只要你按流程来,验证慢慢过,就不会有翻车的地方。下一次遇到 CI 编译失败,先回到这张流程图上,看哪个环节出了问题。