React Native Android应用通过GitHub Actions签名时出现invalid entry compressed size错误求助
That ZipException about mismatched compressed sizes is exactly what happens when you try to sign an already-signed App Bundle (AAB). Let's break down why this is happening and how to fix it.
Why This Error Occurs
Your React Native Android project's build.gradle is likely configured to automatically sign the release bundle during the bundleRelease Gradle task. When you then run the r0adkll/sign-android-release action, you're trying to sign an already-signed file—this causes the zip entry mismatch error you're seeing.
Looking at your android/app/build.gradle, the signingConfigs and buildTypes sections are the culprit here. If you have a release signing config linked to your keystore, and the release build type uses that signing config, Gradle will sign the bundle for you automatically during the build step.
Two Fixes to Choose From
Option 1: Let Gradle Handle Signing (Recommended)
This is the more native approach—keep Gradle's automatic signing, then skip the GitHub Action signing step entirely. Here's how to set it up:
Update GitHub Secrets
Ensure you have these secrets stored in your repo's GitHub Secrets:ANDROID_KEYSTORE: Base64-encoded content of youryour_key_name.keystorefileANDROID_KEYSTORE_PASSWORD: Your keystore's store passwordANDROID_KEY_ALIAS: Your keystore's key aliasANDROID_KEY_PASSWORD: Your key's password
Add Keystore Import Step to GitHub Actions
Before building the bundle, decode the keystore from secrets and save it to the correct path:- name: Import Keystore run: | echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > android/app/your_key_name.keystoreUpdate build.gradle to Use Environment Variables
Modify yoursigningConfigsinandroid/app/build.gradleto pull credentials from environment variables (so they don't live in plaintext):signingConfigs { release { storeFile file('your_key_name.keystore') storePassword System.getenv("ANDROID_KEYSTORE_PASSWORD") keyAlias System.getenv("ANDROID_KEY_ALIAS") keyPassword System.getenv("ANDROID_KEY_PASSWORD") } } buildTypes { release { signingConfig signingConfigs.release // Keep your existing minifyEnabled, proguardFiles, etc. } }Pass Environment Variables to Gradle Build
Update your build step in GitHub Actions to inject the secrets as environment variables:- name: Build Android App Bundle run: | cd android && ./gradlew bundleRelease --no-daemon env: ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}Remove the Signing Step
Delete the entireSign App Bundlestep from your GitHub Actions workflow. Then, update theDeploy to Play Storestep to use the directly built (and already signed) AAB:- name: Deploy to Play Store (BETA) uses: r0adkll/upload-google-play@v1 with: serviceAccountJsonPlainText: ${{ secrets.ANDROID_SERVICE_ACCOUNT }} packageName: com.wmsappbare releaseFile: android/app/build/outputs/bundle/release/app-release.aab track: beta inAppUpdatePriority: 3 userFraction: 0.5 whatsNewDirectory: android/release-notes/ # mappingFile: android/app/build/outputs/mapping/release/mapping.txt
Option 2: Disable Gradle Signing, Use GitHub Action Signing
If you prefer to handle signing via the GitHub Action, modify your build.gradle to skip automatic signing for release builds:
Update build.gradle
Comment out or setsigningConfigto null for the release build type:buildTypes { release { // signingConfig signingConfigs.release // Comment this line out signingConfig null // Or add this line to disable signing // Keep your existing minifyEnabled, proguardFiles, etc. } }Keep Your Existing GitHub Actions Workflow
Now, thebundleReleasetask will generate an unsigned AAB, so ther0adkll/sign-android-releasestep can sign it without conflicts.
How to Verify the Fix Locally
Before pushing changes to GitHub, test locally:
- Run
./gradlew bundleReleasefrom theandroiddirectory. - Verify if the AAB is signed with:
jarsigner -verify android/app/build/outputs/bundle/release/app-release.aab- If it says "jar verified", Gradle signed it (use Option 1).
- If it says "jar is unsigned", you're good to use Option 2.
内容的提问来源于stack exchange,提问作者MindaugasN

