Skip to content

Build Signed Android APK/AAB #12

Build Signed Android APK/AAB

Build Signed Android APK/AAB #12

Workflow file for this run

name: Build Signed Android APK/AAB
on:
workflow_dispatch:
inputs:
build_type:
description: 'Build type'
required: true
default: 'release'
type: choice
options:
- debug
- release
push:
tags:
- 'v*.*.*'
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: Install dependencies
run: npm install --legacy-peer-deps
- name: Expo Prebuild with signing
run: npx expo prebuild --platform android --clean
- name: Decode Keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/release.keystore
- name: Setup Gradle cache
uses: gradle/actions/setup-gradle@v3
with:
gradle-home-cache-cleanup: true
- name: Create keystore.properties
run: |
echo "storeFile=release.keystore" > android/keystore.properties
echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> android/keystore.properties
echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> android/keystore.properties
echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/keystore.properties
- name: Configure Gradle for release signing
run: |
# Inject signing config into build.gradle
cat >> android/app/build.gradle << 'EOF'
android.signingConfigs {
release {
def keystorePropertiesFile = rootProject.file("keystore.properties")
if (keystorePropertiesFile.exists()) {
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
}
android.buildTypes.release.signingConfig = android.signingConfigs.release
EOF
- name: Make gradlew executable
run: chmod +x android/gradlew
- name: Build Signed APK
run: cd android && ./gradlew assembleRelease --no-daemon --stacktrace
- name: Build Signed AAB
run: cd android && ./gradlew bundleRelease --no-daemon --stacktrace
- name: Verify APK signature
run: |
APK_PATH=$(find android/app/build/outputs/apk/release -name "*.apk" | head -1)
echo "Checking signature of: $APK_PATH"
unzip -p "$APK_PATH" META-INF/CERT.RSA | keytool -printcert | grep SHA1
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: app-release-apk
path: android/app/build/outputs/apk/release/*.apk
retention-days: 30
- name: Upload AAB artifact
uses: actions/upload-artifact@v4
with:
name: app-release-aab
path: android/app/build/outputs/bundle/release/*.aab
retention-days: 30
- name: Cleanup keystore
if: always()
run: |
rm -f android/app/release.keystore
rm -f android/keystore.properties