构建变体与CI/CD:在命令行中构建变体、配置Gradle任务、集成到Jenkins/GitHub Actions
说实话,很多Android开发者对构建变体的理解,就停留在「debug和release两个版本」上。但当你真正进入团队协作、自动化交付的阶段,你会发现构建变体才是整个工程体系的基石。今天我们就来聊聊,怎么在命令行里玩转构建变体,怎么配置Gradle任务,以及怎么把它们集成到Jenkins或GitHub Actions里。
一、构建变体到底是什么?
构建变体 = 构建类型 × 产品风味。这个公式我估计大家都见过,但真正理解它的人不多。我刚开始带团队时,就遇到过有人把debug和release当成两个独立APK来维护,结果代码里全是if-else判断,维护成本直线上升。
构建类型(Build Type)通常就是debug和release,控制的是签名、混淆、可调试性这些属性。产品风味(Flavor)则用来区分不同的产品版本,比如免费版和付费版,或者国内版和海外版。
核心公式:构建变体 = 构建类型 × 产品风味
举个例子:你有free和paid两个风味,debug和release两个类型,那么就会生成4个变体:freeDebug、freeRelease、paidDebug、paidRelease。
二、在命令行中构建变体
为什么要用命令行?因为CI/CD环境没有图形界面。你想想看,Jenkins服务器上哪来的Android Studio?所以掌握命令行构建是自动化部署的第一步。
2.1 基础命令
# 列出所有可用的构建变体
./gradlew assembleDebug --list
# 构建特定变体
./gradlew assembleFreeDebug
# 构建所有变体
./gradlew assemble
# 构建所有release变体
./gradlew assembleRelease
我个人习惯在本地开发时用./gradlew assembleFreeDebug,因为只构建一个变体,速度最快。但CI/CD环境里,我通常会跑./gradlew assembleRelease,一次性生成所有release版本。
小技巧:如果你只想构建某个风味的所有类型,可以用./gradlew assembleFree,它会同时构建freeDebug和freeRelease。
2.2 传递参数
命令行构建时,经常需要传递一些参数。比如指定版本号、渠道号等。
# 传递版本号
./gradlew assembleFreeRelease -PversionCode=100 -PversionName="1.0.0"
# 指定签名配置
./gradlew assemblePaidRelease -PsigningConfigName="release"
我曾经在项目中遇到过一个问题:本地构建没问题,但Jenkins上构建出来的APK签名不对。后来发现是Jenkins环境变量没传对。嗯,这里要注意,CI/CD环境里的签名文件路径和密码,最好通过环境变量注入,不要硬编码在build.gradle里。
三、配置Gradle任务
Gradle任务就像是构建流水线上的一个个工序。你可以自定义任务,也可以利用已有的任务。
3.1 自定义任务示例
// 在app/build.gradle中
task printBuildVariant {
doLast {
println "当前构建变体: ${android.defaultConfig.versionName}"
println "构建类型: ${android.buildTypes.each { it.name }}"
}
}
// 依赖关系
assembleFreeDebug.dependsOn printBuildVariant
说白了,Gradle任务就是一段Groovy代码,你可以用它做任何事情:生成版本号、上传APK到服务器、发送通知等等。
3.2 常用内置任务
| 任务名称 | 作用 |
|---|---|
| assemble | 构建所有变体 |
| lint | 代码静态检查 |
| test | 运行单元测试 |
| connectedCheck | 运行设备测试 |
| clean | 清理构建产物 |
注意:在CI/CD环境中,建议先跑./gradlew clean再构建,避免缓存导致的问题。我曾经因为没清理缓存,导致Jenkins构建出来的APK还是旧代码,排查了半天才发现是缓存问题。
四、集成到Jenkins
Jenkins是目前最流行的CI/CD工具之一。集成Android构建其实不复杂,核心就是配置好构建步骤。
4.1 Jenkins Pipeline示例
pipeline {
agent any
environment {
ANDROID_HOME = '/opt/android-sdk'
KEYSTORE_PATH = credentials('keystore-path')
KEYSTORE_PASSWORD = credentials('keystore-password')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh './gradlew clean assembleRelease'
}
}
stage('Test') {
steps {
sh './gradlew test'
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'app/build/outputs/apk/**/*.apk'
}
}
}
}
我个人建议在Jenkins里把构建和测试分开成不同的stage,这样如果测试失败,可以快速定位问题,不用重新跑整个构建流程。
4.2 常见问题
- SDK路径问题:Jenkins服务器上要提前配置好ANDROID_HOME环境变量
- 签名问题:签名文件不要放在代码仓库里,用Jenkins的凭据管理功能
- 内存不足:Gradle构建很吃内存,建议给Jenkins分配至少4GB内存
五、集成到GitHub Actions
GitHub Actions是GitHub自带的CI/CD工具,配置起来比Jenkins简单很多。我个人更喜欢用GitHub Actions做小团队的自动化构建,因为不用自己维护服务器。
5.1 GitHub Actions Workflow示例
name: Android CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew assembleRelease
- name: Upload APK
uses: actions/upload-artifact@v3
with:
name: app-release
path: app/build/outputs/apk/release/app-release.apk
你想想看,GitHub Actions最大的优势是什么?是免费!对于开源项目来说,完全不用操心服务器费用。而且它和GitHub仓库深度集成,PR触发构建、自动发布release,这些功能都是开箱即用。
5.2 多风味构建
# 构建所有风味
- name: Build all flavors
run: |
./gradlew assembleFreeRelease
./gradlew assemblePaidRelease
提示:GitHub Actions支持矩阵构建,可以同时跑多个构建任务,大幅缩短总构建时间。比如同时构建free和paid两个风味,互不干扰。
六、构建变体与CI/CD的最佳实践
说了这么多,最后总结几条我踩过坑之后得出的经验:
- 版本号自动化:不要在代码里硬编码版本号,用Gradle的versionCode和versionName,通过CI/CD环境变量注入
- 签名分离:debug签名用默认的,release签名用CI/CD环境里的,不要混用
- 构建产物命名:建议用
app-{flavor}-{version}-{buildNumber}.apk的格式,方便追溯 - 缓存优化:Gradle的缓存机制很强大,CI/CD环境里建议开启缓存,能节省50%以上的构建时间
避坑指南:我曾经在GitHub Actions里忘记配置JDK版本,结果默认的JDK 11和Android Gradle Plugin不兼容,构建一直失败。后来加了setup-java步骤才解决。所以,CI/CD配置里的每一个步骤都要仔细检查,不要想当然。
七、知识体系总览
下面这张图展示了构建变体与CI/CD的核心逻辑关系,我把它画成了流程图,方便你理解整个体系:
从这张图可以看出,整个流程其实很清晰:代码提交触发CI/CD,然后Gradle根据配置生成不同的构建变体,最终输出对应的APK文件。每个环节都有它的作用,缺一不可。
好了,关于构建变体与CI/CD的内容就聊到这里。记住,自动化构建不是一蹴而就的,需要根据团队的实际需求逐步完善。刚开始可以只做最简单的assembleRelease,后面再慢慢加上测试、代码检查、自动发布等功能。