在Android项目的迭代过程中,手动执行gradle命令、等待模拟器测试、再打包APK传给测试人员,这套流程不仅耗时,而且容易因为环境差异导致构建失败。GitLab自带的CI/CD能力配合GitLab Runner,能把代码推送、合并请求和版本发布串成一条自动化流水线,让编译、测试、打包这些重复劳动从开发机上转移到独立的执行环境中。对于Android工程而言,流水线要处理的不只是Gradle任务,还包括SDK路径、依赖缓存、签名安全以及APK产物归档,这些细节决定了构建是否稳定、是否可重复。

本文以GitLab Runner为核心,结合Android项目的典型结构,给出从环境准备到流水线配置、再到签名发布的实施方案。
为什么Android流水线更适合用Shell执行器
GitLab Runner支持多种执行器,Docker执行器提供干净的隔离环境,但对Android构建并不友好。Android SDK体积大、许可协议需要交互确认,而且构建过程需要访问本地Gradle缓存。如果每次都在容器里从零下载SDK和依赖,流水线时间会大幅拉长。相比之下,Shell执行器直接使用宿主机的SDK、JDK和Gradle缓存,环境复用度高,配置和排障也更直观。
当然Shell执行器不隔离也有风险,比如多个流水线并发时可能争抢Gradle锁文件,但只要通过合理的缓存目录和并发控制,风险可控。对于中小团队或者需要快速落地的场景,Shell执行器是性价比最高的选择。如果团队已有成熟的Docker镜像,也可以采用Docker执行器,但需要额外维护镜像,本文统一以Shell执行器展开。
安装GitLab Runner与配置Android SDK
在Linux服务器上安装Runner通常使用官方软件源。以Ubuntu为例,添加GitLab官方仓库后执行apt install gitlab-runner即可。安装完成后运行gitlab-runner register命令,填写GitLab实例地址、注册令牌、描述信息和执行器类型。这里执行器选择shell。注册成功后会在/etc/gitlab-runner/config.toml中生成配置,后续可以修改并发数和标签。
# Ubuntu安装GitLab Runner curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | bash apt install gitlab-runner # 注册Runner gitlab-runner register \ --url https://gitlab.ipipp.com/ \ --registration-token PROJECT_REGISTRATION_TOKEN \ --description "android-shell-runner" \ --executor shell \ --tag-list android,shell
Android SDK的安装需要下载命令行工具包,解压后通过sdkmanager安装platform-tools、build-tools和platforms。为了构建不同版本的APK,至少安装一个platform,如android-34。许可协议可以通过yes | sdkmanager --licenses提前接受。然后在/etc/profile.d/android.sh中设置ANDROID_HOME和PATH,让Runner进程能读取到这些环境变量。同时需要安装JDK 17或11,取决于项目的AGP版本。配置完成后运行sdkmanager --list验证SDK可用。
# 安装Android SDK命令行工具 cd /opt mkdir -p android-sdk/cmdline-tools curl -O https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip unzip commandlinetools-linux-*.zip -d android-sdk/cmdline-tools mv android-sdk/cmdline-tools/cmdline-tools android-sdk/cmdline-tools/latest # 安装必要的SDK组件 export ANDROID_HOME=/opt/android-sdk yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platform-tools" "build-tools;34.0.0" "platforms;android-34"
编写.gitlab-ci.yml:从编译到测试的完整阶段
GitLab CI的配置文件放在项目根目录的.gitlab-ci.yml中。Android项目通常定义三个阶段:build、test和assemble。build阶段执行编译任务,确保代码没有语法错误;test阶段运行单元测试和Lint检查;assemble阶段打包APK。为了加快构建,需要配置Gradle缓存,将.gradle目录和项目下的build目录缓存起来。缓存键使用固定名称,保证不同分支间可以复用依赖。
before_script统一设置JAVA_HOME和ANDROID_HOME,并确保项目使用Gradle Wrapper,避免服务器全局安装的Gradle版本与项目不一致。使用./gradlew命令时加上--no-daemon,因为CI环境中常驻Gradle守护进程会占用内存且不易回收。下面是一个基础配置示例。
stages:
- build
- test
- assemble
before_script:
- export ANDROID_HOME=/opt/android-sdk
- export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
- export PATH=$PATH:$ANDROID_HOME/platform-tools
- chmod +x ./gradlew
cache:
key: android-gradle-cache
paths:
- .gradle/
- app/build/
build:
stage: build
script:
- ./gradlew --no-daemon compileDebugSources
unit-test:
stage: test
script:
- ./gradlew --no-daemon testDebugUnitTest
- ./gradlew --no-daemon lintDebug
artifacts:
reports:
junit: app/build/test-results/testDebugUnitTest/*.xml
assemble-debug:
stage: assemble
script:
- ./gradlew --no-daemon assembleDebug
artifacts:
paths:
- app/build/outputs/apk/debug/*.apk上面的配置先执行compileDebugSources快速暴露编译错误,再执行单元测试和Lint,最后生成Debug APK并收集到制品中。单元测试报告通过artifacts:reports:junit让GitLab界面直接显示测试结果,不需要额外插件。如果项目包含多模块,可以替换app为具体模块名,或使用./gradlew tasks查看任务名称。
Release签名与构建优化
生成可发布的APK离不开签名。直接在版本库中存放keystore文件会导致密钥泄露,推荐把签名文件转为Base64字符串存入GitLab CI/CD变量,并在流水线中解码还原。也可以使用GitLab的Secure Files功能,但变量方式更通用。在仓库的CI/CD设置里创建两个变量:KEYSTORE_FILE和KEYSTORE_PASSWORD,其中KEYSTORE_FILE是keystore文件的Base64编码,密码存入KEYSTORE_PASSWORD。流水线执行时先将变量内容解码为keystore文件,再调用assembleRelease。
release-build:
stage: assemble
script:
- echo "$KEYSTORE_FILE" | base64 -d > release.keystore
- ./gradlew --no-daemon assembleRelease
-Pandroid.injected.signing.store.file=release.keystore
-Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD
-Pandroid.injected.signing.key.alias=$KEY_ALIAS
-Pandroid.injected.signing.key.password=$KEY_PASSWORD
artifacts:
paths:
- app/build/outputs/apk/release/*.apk
only:
- main使用android.injected.signing参数可以在不修改Gradle文件的情况下进行签名,适合快速接入已有项目。如果项目已经配置了signingConfig,则可以直接读取环境变量或配置文件。签名后的Release APK同样通过artifacts上传,供后续手动下载或通过Fastlane发布到应用市场。为了安全,变量要设置为protected,只对受保护分支或标签生效。
如果首次构建时间很长,重点优化Gradle缓存和依赖下载。除了cache配置,还可以在服务器上预先执行一次./gradlew build,让Gradle提前下载依赖到全局缓存目录~/.gradle。另外,Runner的并发数不要超过服务器CPU核心数,构建任务可以通过tags指定到专用Runner,避免与其他项目争抢资源。如果项目使用Kotlin,可以考虑开启Kotlin增量编译和Gradle配置缓存。
GitLab RunnerAndroid流水线CI/CD修改时间:2026-09-20 13:02:01