update build.yml #22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| jobs: | |
| build-android: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Setup Android SDK | |
| uses: android-actions/setup-android@v3 | |
| - name: Install dependencies | |
| run: npm install --legacy-peer-deps | |
| - name: Expo Prebuild | |
| run: npx expo prebuild --platform android --clean | |
| - name: Setup Gradle cache | |
| uses: gradle/actions/setup-gradle@v3 | |
| with: | |
| gradle-home-cache-cleanup: true | |
| - name: Decode Keystore | |
| run: | | |
| echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > release.keystore | |
| echo "✅ Keystore decoded to release.keystore" | |
| - name: Make gradlew executable | |
| run: chmod +x android/gradlew | |
| # Build the UNsigned Release APK | |
| - name: Build Release APK (Unsigned) | |
| run: | | |
| cd android | |
| ./gradlew assembleRelease --no-daemon | |
| # Sign the APK manually using apksigner | |
| - name: Sign APK | |
| id: sign_apk | |
| run: | | |
| # Find the unsigned APK | |
| APK_PATH=$(find android/app/build/outputs/apk/release -name "*-release-unsigned.apk" -o -name | |
| "*-release.apk" | head -1) | |
| echo "Found APK: $APK_PATH" | |
| # Align the APK (Optimization step required before signing) | |
| $ANDROID_HOME/build-tools/34.0.0/zipalign -v -p 4 "$APK_PATH" release-aligned.apk | |
| # Sign the APK | |
| $ANDROID_HOME/build-tools/34.0.0/apksigner sign --ks release.keystore \ | |
| --ks-key-alias "${{ secrets.KEY_ALIAS }}" \ | |
| --ks-pass "pass:${{ secrets.KEYSTORE_PASSWORD }}" \ | |
| --key-pass "pass:${{ secrets.KEY_PASSWORD }}" \ | |
| --out release-signed.apk \ | |
| release-aligned.apk | |
| echo "✅ APK Signed successfully" | |
| echo "signed_apk_path=release-signed.apk" >> $GITHUB_OUTPUT | |
| # Build the AAB (Android App Bundle) | |
| - name: Build Release AAB | |
| run: | | |
| cd android | |
| ./gradlew bundleRelease --no-daemon | |
| # Sign the AAB manually using jarsigner | |
| - name: Sign AAB | |
| run: | | |
| # Find the AAB | |
| AAB_PATH=$(find android/app/build/outputs/bundle/release -name "*-release.aab" | head -1) | |
| echo "Found AAB: $AAB_PATH" | |
| # Sign using jarsigner (AABs use jarsigner, not apksigner) | |
| jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \ | |
| -keystore release.keystore \ | |
| -storepass "${{ secrets.KEYSTORE_PASSWORD }}" \ | |
| -keypass "${{ secrets.KEY_PASSWORD }}" \ | |
| "$AAB_PATH" "${{ secrets.KEY_ALIAS }}" | |
| mv "$AAB_PATH" release-signed.aab | |
| echo "✅ AAB Signed successfully" | |
| - name: Verify APK signature | |
| run: | | |
| echo "📦 Verifying: release-signed.apk" | |
| # Use apksigner verify which is more robust | |
| $ANDROID_HOME/build-tools/34.0.0/apksigner verify --print-certs release-signed.apk | |
| # Quick check for your specific SHA1 if needed | |
| SHA1=$($ANDROID_HOME/build-tools/34.0.0/apksigner verify --print-certs release-signed.apk | | |
| grep "SHA-1 digest:" | head -1 | awk '{print $3}') | |
| echo "Detected SHA1: $SHA1" | |
| - name: Upload APK artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-apk-${{ github.run_number }} | |
| path: release-signed.apk | |
| retention-days: 30 | |
| - name: Upload AAB artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-aab-${{ github.run_number }} | |
| path: release-signed.aab | |
| retention-days: 30 | |
| - name: Cleanup sensitive files | |
| if: always() | |
| run: | | |
| rm -f release.keystore | |
| echo "✅ Cleanup completed" |