Android GitLab CI:如何复用编译文件优化流水线后续阶段执行
GitLab CI 复用编译产物优化流水线方案
核心问题分析
本地验证通过但CI失效,本质是CI各阶段的执行环境是隔离容器,默认不共享文件,且Gradle的增量校验依赖完整的build目录(包括缓存、任务状态记录),只传部分文件会导致校验失败。
可行解决方案
1. 完整归档并恢复build目录(推荐)
在compile阶段完整打包目标module的build目录,test阶段完整恢复,确保Gradle能识别增量状态:
stages: - compile - test compile_release: stage: compile script: - ./gradlew compileReleaseKotlin compileReleaseJavaWithJavac artifacts: paths: - app/build/ # 替换为你的实际module路径 expire_in: 1h # 按需设置过期时间 when: on_success test_release: stage: test dependencies: - compile_release script: - ./gradlew --console=plain app:testReleaseUnitTest
注意:必须归档整个build目录,不能只传子文件夹(比如outputs)。Gradle的任务状态文件(build/task-configuration-cache、build/.gradle等)都在build根目录下,缺失会导致重新执行任务。
2. 配置Gradle缓存与CI缓存联动
如果不想依赖artifacts,可用GitLab CI的缓存功能持久化Gradle缓存和build目录:
stages: - compile - test # 全局缓存配置 cache: key: "$CI_COMMIT_REF_NAME-gradle" paths: - ~/.gradle/caches/ - ~/.gradle/wrapper/ - app/build/ policy: pull-push compile_release: stage: compile script: - ./gradlew compileReleaseKotlin compileReleaseJavaWithJavac test_release: stage: test script: - ./gradlew --console=plain app:testReleaseUnitTest
这种方式下,compile阶段的build目录会被缓存,test阶段直接拉取缓存使用,无需手动处理artifacts。注意缓存key的设置,避免不同分支互相干扰。
3. 排查常见失效原因
- 权限问题:CI容器中build目录的所有者可能和后续阶段不一致,导致Gradle无法读取文件。可在test阶段添加
chmod -R 755 app/build/修复权限。 - Gradle参数冲突:如果test阶段的Gradle命令加了
--no-build-cache或--rerun-tasks,会强制重新执行,需移除这些参数。 - artifacts过滤错误:确保paths没有排除build目录下的关键子文件夹(比如
build/tmp、build/intermediates),这些是增量校验的核心文件。
验证方法
在test阶段的script开头添加ls -la app/build/,确认build目录的文件结构和本地一致,特别是.gradle、task-configuration-cache这些隐藏文件夹是否存在。如果存在,Gradle应该会标记相关任务为UP-TO-DATE。
内容的提问来源于stack exchange,提问作者Dannie
相关产品推荐
相关产品推荐

