Android库开发:如何在.yaml与.gradle文件间共享变量?
如何在Gradle配置文件与CI YAML文件之间共享变量
这确实是个很常见的痛点——重复维护相同变量太容易出错了!我分享几个在Gradle配置文件与CI YAML文件之间共享变量的实用方案,你可以根据自己的场景选择:
方案1:使用.properties文件作为单一数据源
这种方法最直观,把所有共享变量放在一个独立的.properties文件里,让Gradle和CI都从这里读取,实现“一处修改,处处生效”。
步骤1:创建共享配置文件
在项目根目录新建config.properties文件,定义需要共享的变量:
# config.properties ANDROID_API_LEVEL=34 ANDROID_BUILD_TOOLS_VERSION=34.0.0
步骤2:在Gradle中读取该文件
在项目根目录的build.gradle(或模块级build.gradle.kts,如果用Kotlin DSL)中加载这个配置文件:
// 根build.gradle def configProps = new Properties() file("config.properties").withInputStream { configProps.load(it) } android { compileSdk configProps.getProperty("ANDROID_API_LEVEL").toInteger() buildToolsVersion configProps.getProperty("ANDROID_BUILD_TOOLS_VERSION") defaultConfig { minSdk 21 targetSdk configProps.getProperty("ANDROID_API_LEVEL").toInteger() // 其他配置... } }
步骤3:在CI YAML中读取该文件
在你的CI配置文件(比如.github/workflows/build.yml)里,用shell命令提取变量并注入到环境中:
jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 提取共享变量到CI环境 run: | # 从config.properties中提取变量 ANDROID_API_LEVEL=$(grep -E "^ANDROID_API_LEVEL=" config.properties | cut -d'=' -f2) ANDROID_BUILD_TOOLS_VERSION=$(grep -E "^ANDROID_BUILD_TOOLS_VERSION=" config.properties | cut -d'=' -f2) # 写入CI环境变量 echo "ANDROID_API_LEVEL=$ANDROID_API_LEVEL" >> $GITHUB_ENV echo "ANDROID_BUILD_TOOLS_VERSION=$ANDROID_BUILD_TOOLS_VERSION" >> $GITHUB_ENV - name: 配置Android SDK uses: android-actions/setup-android@v3 with: api-level: ${{ env.ANDROID_API_LEVEL }} build-tools: ${{ env.ANDROID_BUILD_TOOLS_VERSION }} - name: 用Gradle构建 run: ./gradlew assembleRelease
方案2:从Gradle导出变量到CI环境
如果你的变量主要在Gradle中定义,希望CI直接复用Gradle的配置,可以在Gradle中添加一个任务来输出变量,再让CI捕获这些值。
步骤1:在Gradle中添加输出变量的任务
在根build.gradle里添加一个自定义任务:
task printSharedVariables { doLast { // 输出Gradle中定义的变量 println "ANDROID_API_LEVEL=${android.compileSdkVersion}" println "ANDROID_BUILD_TOOLS_VERSION=${android.buildToolsVersion}" } }
步骤2:在CI YAML中捕获变量
调用这个Gradle任务,把输出的变量注入到CI环境:
jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 从Gradle导出变量到CI环境 run: | # 执行Gradle任务并将输出保存到文件 ./gradlew printSharedVariables --no-daemon --quiet > gradle-vars.txt # 加载变量到当前shell source gradle-vars.txt # 写入CI环境变量 echo "ANDROID_API_LEVEL=$ANDROID_API_LEVEL" >> $GITHUB_ENV echo "ANDROID_BUILD_TOOLS_VERSION=$ANDROID_BUILD_TOOLS_VERSION" >> $GITHUB_ENV - name: 配置Android SDK uses: android-actions/setup-android@v3 with: api-level: ${{ env.ANDROID_API_LEVEL }} build-tools: ${{ env.ANDROID_BUILD_TOOLS_VERSION }} - name: 用Gradle构建 run: ./gradlew assembleRelease
方案3:使用环境变量作为桥梁
如果你的CI流程是核心,希望变量在CI中定义,Gradle读取CI的环境变量,这种方法也很实用。
步骤1:在CI YAML中定义环境变量
直接在YAML的env块中定义共享变量:
env: ANDROID_API_LEVEL: 34 ANDROID_BUILD_TOOLS_VERSION: 34.0.0 jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 配置Android SDK uses: android-actions/setup-android@v3 with: api-level: ${{ env.ANDROID_API_LEVEL }} build-tools: ${{ env.ANDROID_BUILD_TOOLS_VERSION }} - name: 用Gradle构建 run: ./gradlew assembleRelease
步骤2:在Gradle中读取环境变量
修改Gradle配置,读取CI注入的环境变量,同时可以设置默认值以防本地开发时没有这些变量:
android { // 读取环境变量,没有则用默认值34 compileSdk System.getenv("ANDROID_API_LEVEL")?.toInteger() ?: 34 // 读取环境变量,没有则用默认值34.0.0 buildToolsVersion System.getenv("ANDROID_BUILD_TOOLS_VERSION") ?: "34.0.0" defaultConfig { minSdk 21 targetSdk System.getenv("ANDROID_API_LEVEL")?.toInteger() ?: 34 // 其他配置... } }
各方案优缺点对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| .properties文件 | 单一数据源,本地开发和CI完全一致,修改方便 | 需要维护额外文件,CI中需要写shell命令提取 |
| Gradle导出变量 | 变量源在Gradle,无需额外文件 | CI依赖Gradle任务,首次运行可能稍慢 |
| 环境变量 | CI配置集中,无需修改Gradle外的文件 | 本地开发需要手动设置环境变量或依赖默认值 |
你可以根据自己的开发流程偏好选择最合适的方案!
内容的提问来源于stack exchange,提问作者HendraWD
相关产品推荐
相关产品推荐

