如何为GitHub Actions中动态命名的构建配置upload-artifact路径?
解决GitHub Actions中上传Gradle动态生成APK的问题
问题场景
我在给Android项目配置GitHub Actions的CI/CD流水线,包含production和staging两种产品风味。要求代码合并到main分支时,自动上传stagingDebug的构建产物作为工件,但Gradle生成的APK文件名是动态的(包含日期、版本信息),不知道怎么在actions/upload-artifact的path参数里适配这种动态名称。
现有Gradle配置
defaultConfig { applicationId "com.xyz.app" minSdk 23 targetSdk 34 versionCode 22 versionName "1.7.0.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" def formattedDate = new Date().format('yy-MM-dd HH.mm.ss') archivesBaseName = "$applicationId-v$versionCode($versionName)-$formattedDate" vectorDrawables.useSupportLibrary = true } productFlavors { stagging { applicationId "com.xyz.app.stagging" copy { from 'src/stagging/' include 'google-services.json' into '.' } } }
生成的APK路径示例
app/build/outputs/apk/stagging/debug/com.xyz.app.stagging-v22(1.7.0.6)-24-02-05 10.10.19-stagging-debug.apk
当前GitHub Action配置(待修改)
name: AndroidBuild on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4.1.1 - name: Set up JDK uses: actions/setup-java@v4.0.0 with: distribution: 'adopt' java-version: '11' - name: Build with Gradle run: | ./gradlew assembleStaggingDebug - name: Upload APK uses: actions/upload-artifact@v4.3.0 with: name: stagging_artifiact path: app/build/outputs/apk/stagging/debug/${dynamically named apk}.apk
三种解决方案
方法1:用通配符直接匹配(最简便)
构建完成后,stagging/debug目录下通常只有一个目标APK,直接用通配符匹配即可:
- name: Upload APK uses: actions/upload-artifact@v4.3.0 with: name: stagging_artifiact path: app/build/outputs/apk/stagging/debug/*stagging-debug.apk
如果想更宽泛,也可以直接写:
path: app/build/outputs/apk/stagging/debug/*.apk
方法2:让Gradle输出APK路径,在Actions中捕获
通过Gradle任务输出APK的绝对路径,再在GitHub Actions中提取并使用:
- 修改app模块的
build.gradle,添加一个打印路径的任务:
task printStagingDebugApkPath { doLast { def apkFile = file("${project.buildDir}/outputs/apk/stagging/debug/${archivesBaseName}-stagging-debug.apk") println "STAGING_DEBUG_APK_PATH=${apkFile.absolutePath}" } } // 让这个任务在assembleStaggingDebug执行完成后自动运行 assembleStaggingDebug.finalizedBy(printStagingDebugApkPath)
- 在GitHub Actions中捕获输出并设置为环境变量:
- name: Build with Gradle id: build_apk run: | # 执行构建并保存输出 ./gradlew assembleStaggingDebug | tee build_output.txt # 提取APK路径并写入环境变量 APK_PATH=$(grep "STAGING_DEBUG_APK_PATH=" build_output.txt | cut -d'=' -f2) echo "APK_PATH=$APK_PATH" >> $GITHUB_ENV - name: Upload APK uses: actions/upload-artifact@v4.3.0 with: name: stagging_artifiact path: ${{ env.APK_PATH }}
方法3:固定Gradle生成的文件名(可选)
如果不需要文件名里的日期,可以修改Gradle配置去掉动态日期部分,让文件名固定:
// 在defaultConfig中修改archivesBaseName archivesBaseName = "$applicationId-v$versionCode($versionName)"
修改后生成的文件名会变成:
com.xyz.app.stagging-v22(1.7.0.6)-stagging-debug.apk
之后在GitHub Actions中直接写固定路径即可:
- name: Upload APK uses: actions/upload-artifact@v4.3.0 with: name: stagging_artifiact path: app/build/outputs/apk/stagging/debug/com.xyz.app.stagging-v22(1.7.0.6)-stagging-debug.apk
如果版本号也是动态的,同样可以通过Gradle输出版本信息到环境变量,再在路径中引用。
内容的提问来源于stack exchange,提问作者Faisal Naseer
相关产品推荐
相关产品推荐

