上一篇聊了启动优化,这篇换个方向——工程效率。CI/CD 不是写代码本身,但它决定了代码从提交到上线的效率和质量。很多团队的 Android CI 还停留在"跑个 lint 就打包"的阶段,这篇聊聊怎么搭一套真正有用的 CI/CD。
Android CI/CD 要做什么
一个完整的 Android CI pipeline 应该包括:
代码检查:Lint、ktlint/detekt
编译构建:Debug + Release
单元测试:JUnit + Robolectric
Instrumentation 测试:UI 自动化(需要模拟器或真机)
覆盖率报告:JaCoCo / Kover
打包分发:APK/AAB 上传到内部测试或 Play Console
安全扫描:依赖漏洞检查
GitHub Actions 方案
基础工作流
# .github/workflows/android-ci.yml
name: Android CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Run ktlint
run: ./gradlew ktlintCheck
- name: Run Lint
run: ./gradlew lintDebug
- name: Run Unit Tests
run: ./gradlew testDebugUnitTest
- name: Build Debug APK
run: ./gradlew assembleDebug
- name: Upload APK
uses: actions/upload-artifact@v4
with:
name: app-debug.apk
path: app/build/outputs/apk/debug/app-debug.apk
Gradle 缓存是加速 CI 的关键。actions/setup-java 的 cache: gradle 选项会缓存 ~/.gradle/caches,第二次构建能省 2-5 分钟。
Release 流水线
release:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle
- name: Build Release AAB
run: ./gradlew bundleRelease
env:
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
- name: Upload to Play Store
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
packageName: com.example.app
releaseFiles: app/build/outputs/bundle/release/app-release.aab
track: internal
签名密钥不要放在仓库里,用 GitHub Secrets 管理。构建时通过环境变量注入。
GitLab CI 方案
# .gitlab-ci.yml
stages:
- check
- test
- build
- deploy
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.caching=true"
lint:
stage: check
image: cimg/android:2024.07
script:
- ./gradlew ktlintCheck detekt
cache:
key: gradle-cache
paths:
- .gradle/
- build/
- app/build/
unit_test:
stage: test
image: cimg/android:2024.07
script:
- ./gradlew testDebugUnitTest
artifacts:
reports:
junit: app/build/test-results/**/TEST-*.xml
paths:
- app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
cache:
key: gradle-cache
policy: pull
build_release:
stage: build
only:
- main
script:
- ./gradlew bundleRelease
artifacts:
paths:
- app/build/outputs/bundle/release/app-release.aab
GitLab CI 的缓存策略比 GitHub Actions 更灵活,可以指定 policy: pull 只拉不推,适合多阶段流水线。
Instrumentation 测试
需要模拟器跑 UI 测试,是 Android CI 的难点。两种方案:
方案一:GitHub Actions 模拟器
instrumentation_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
arch: x86_64
script: ./gradlew connectedAndroidTest
缺点:模拟器启动慢(3-5 分钟),稳定性一般,偶尔会超时。
方案二:Firebase Test Lab
- name: Run on Firebase Test Lab
run: |
gcloud auth activate-service-account --key-file=service-account.json
gcloud firebase test android run \
--type instrumentation \
--app app/build/outputs/apk/debug/app-debug.apk \
--test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device model=Pixel8,version=34,locale=zh_CN,orientation=portrait
Firebase Test Lab 更稳定,支持多设备并行,但有费用。
Gradle 缓存优化
CI 上 Gradle 构建慢,主要是依赖下载和编译缓存。加速手段:
Gradle Build Cache:开启本地和远程缓存
// gradle.properties
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx4g
版本目录(Version Catalog):统一依赖版本,减少解析时间
按需配置:
./gradlew assembleDebug --configuration-cache配置缓存(Configuration Cache):Gradle 8+ 支持,减少配置阶段时间,能省 20-40% 构建时间
质量门禁
在 CI 中设置质量门槛,不达标就阻止合并:
- name: Check coverage
run: |
COVERAGE=$(./gradlew jacocoTestReport -q | grep "Total" | awk '{print $NF}')
if (( $(echo "$COVERAGE < 60" | bc -l) )); then
echo "Coverage $COVERAGE% is below 60%"
exit 1
fi
小结
CI/CD 的核心不是工具选择,而是流程设计。先保证基础流程跑通(lint + test + build),再逐步加质量门禁、自动化分发、性能测试。Gradle 缓存和配置缓存是加速 CI 的关键,别让 CI 成为开发效率的瓶颈。
下一篇聊聊 Android 依赖管理:Version Catalogs 的使用。