React Native在GitHub Actions构建Android APK时密钥库文件报错排查
已将my-upload-key.keystore转换为Base64格式并存入GitHub仓库密钥ANDROID_SIGNING_KEY,但执行GitHub Actions构建Android APK时出现以下错误:
Keystore file '/home/runner/work/SampleApp/SampleApp/android/app/my-upload-key.keystore' not found for signing config 'release'.
使用的GitHub Actions配置:
- name: Sign APK id: sign_app uses: r0adkll/sign-android-release@v1 with: releaseDirectory: android/app/build/outputs/apk/release signingKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }} alias: ${{ secrets.ANDROID_ALIAS }} keyStorePassword: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }} keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
Android项目/app/build.gradle配置:
signingConfigs { release { if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { storeFile file(MYAPP_UPLOAD_STORE_FILE) storePassword MYAPP_UPLOAD_STORE_PASSWORD keyAlias MYAPP_UPLOAD_KEY_ALIAS keyPassword MYAPP_UPLOAD_KEY_PASSWORD } } } buildTypes { release { signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } }
疑问:明明已经通过Base64密钥传入,为何仍要求本地存在my-upload-key.keystore文件?
核心原因
你混淆了两种签名时机:
- Gradle构建阶段签名:你的
build.gradle配置要求Gradle在编译生成release APK时,直接使用本地keystore文件完成签名。 - 第三方Action构建后签名:
r0adkll/sign-android-release@v1的作用是在Gradle完成构建、生成未签名APK之后,再用Base64解码出的keystore文件签名APK。
当前流程中,Gradle构建阶段先执行,此时Action还没有将Base64解码为本地keystore文件,所以Gradle找不到文件报错。
解决办法(二选一即可)
方法1:让Gradle生成未签名APK,交给Action签名
修改build.gradle中的buildTypes.release配置,让Gradle仅在本地有keystore时才签名,CI环境下生成未签名APK:
buildTypes { release { // 仅本地构建时使用签名配置,CI环境下生成未签名APK signingConfig project.hasProperty('MYAPP_UPLOAD_STORE_FILE') ? signingConfigs.release : null minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } }
这样Gradle构建时不会尝试找keystore,生成未签名APK后,r0adkll/sign-android-release@v1会自动用你传入的Base64密钥完成签名。
方法2:在Gradle构建前生成keystore文件,让Gradle完成签名
在GitHub Actions的构建步骤前,先将Base64解码为本地keystore文件,再传入Gradle属性完成签名:
# 先解码生成keystore文件 - name: Generate Keystore File run: | echo "${{ secrets.ANDROID_SIGNING_KEY }}" | base64 --decode > android/app/my-upload-key.keystore # 执行Gradle构建并传入签名参数 - name: Build Signed Release APK run: | cd android ./gradlew assembleRelease \ -PMYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore \ -PMYAPP_UPLOAD_STORE_PASSWORD=${{ secrets.ANDROID_KEY_STORE_PASSWORD }} \ -PMYAPP_UPLOAD_KEY_ALIAS=${{ secrets.ANDROID_ALIAS }} \ -PMYAPP_UPLOAD_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }}
这种情况下可以去掉原来的Sign APK步骤,因为Gradle已经完成了签名。
内容的提问来源于stack exchange,提问作者Alireza Navaie

