Merge pull request #1836 from utkarshdalal/1.2.0-prerelease #930
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
| name: Android CI | |
| on: | |
| push: | |
| branches: [ "master" ] | |
| paths-ignore: | |
| - '**.md' | |
| - '.gitignore' | |
| - 'keyvalues/**' | |
| - 'media/**' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| workflow_dispatch: | |
| concurrency: | |
| group: android-ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: set up Java 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| cache: gradle | |
| - name: Validate Gradle wrapper | |
| uses: gradle/actions/wrapper-validation@v4 | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| - name: Configure Keystore | |
| env: | |
| KEYSTORE: ${{ secrets.KEYSTORE }} | |
| KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }} | |
| KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }} | |
| KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }} | |
| run: | | |
| mkdir -p app/keystores | |
| echo "$KEYSTORE" | base64 --decode > app/keystores/keystore | |
| echo "storeFile=keystores/keystore" >> app/keystores/keystore.properties | |
| echo "keyAlias=$KEYSTORE_KEY_ALIAS" >> app/keystores/keystore.properties | |
| echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> app/keystores/keystore.properties | |
| echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> app/keystores/keystore.properties | |
| - name: Configure Production Keystore | |
| env: | |
| PROD_KEYSTORE: ${{ secrets.PROD_KEYSTORE }} | |
| PROD_KEYSTORE_KEY_ALIAS: ${{ secrets.PROD_KEYSTORE_KEY_ALIAS }} | |
| PROD_KEYSTORE_KEY_PASSWORD: ${{ secrets.PROD_KEYSTORE_KEY_PASSWORD }} | |
| PROD_KEYSTORE_STORE_PASSWORD: ${{ secrets.PROD_KEYSTORE_STORE_PASSWORD }} | |
| run: | | |
| mkdir -p app/keystores | |
| echo "$PROD_KEYSTORE" | base64 --decode > app/keystores/prod.keystore | |
| cat <<EOF > app/keystores/prod-keystore.properties | |
| keyAlias=$PROD_KEYSTORE_KEY_ALIAS | |
| keyPassword=$PROD_KEYSTORE_KEY_PASSWORD | |
| storePassword=$PROD_KEYSTORE_STORE_PASSWORD | |
| EOF | |
| - name: Inject credentials | |
| run: | | |
| cat <<EOF > local.properties | |
| POSTHOG_API_KEY=${{ secrets.POSTHOG_API_KEY }} | |
| POSTHOG_HOST=${{ secrets.POSTHOG_HOST }} | |
| STEAMGRIDDB_API_KEY=${{ secrets.STEAMGRIDDB_API_KEY }} | |
| CLOUD_PROJECT_NUMBER=${{ secrets.CLOUD_PROJECT_NUMBER }} | |
| EOF | |
| - name: Install Android SDK Build Tools | |
| run: | | |
| SDKMANAGER="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" | |
| if [ ! -x "$SDKMANAGER" ]; then | |
| SDKMANAGER="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" | |
| fi | |
| yes | "$SDKMANAGER" --install "build-tools;34.0.0" | |
| - name: Build with Gradle | |
| run: ./gradlew :app:bundleLegacyRelease :app:bundleModernRelease :app:bundleLegacyXrRelease | |
| - name: Stage bundles | |
| run: | | |
| cp app/build/outputs/bundle/legacyRelease/app-legacy-release.aab app-release.aab | |
| cp app/build/outputs/bundle/modernRelease/app-modern-release.aab app-modern-release.aab | |
| cp app/build/outputs/bundle/legacyXrRelease/app-legacyXr-release.aab app-legacy-xr-release.aab | |
| - name: Stop Gradle daemon to free memory | |
| run: ./gradlew --stop | |
| - name: Extract APKs from Bundles | |
| run: | | |
| java -jar tools/bundletool-all-1.17.2.jar build-apks --bundle=app-release.aab --output=app-release.apks --mode=universal | |
| unzip -o app-release.apks universal.apk | |
| java -jar tools/bundletool-all-1.17.2.jar build-apks --bundle=app-modern-release.aab --output=app-modern-release.apks --mode=universal | |
| unzip -p app-modern-release.apks universal.apk > universal-modern.apk | |
| java -jar tools/bundletool-all-1.17.2.jar build-apks --bundle=app-legacy-xr-release.aab --output=app-legacy-xr-release.apks --mode=universal | |
| unzip -p app-legacy-xr-release.apks universal.apk > universal-legacy-xr.apk | |
| - name: Copy lineage file | |
| run: | | |
| mkdir -p app/keystores | |
| cp prod-debug.lineage app/keystores/prod-debug.lineage | |
| - name: Dual sign universal APKs | |
| env: | |
| DEBUG_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }} | |
| DEBUG_KEY_PASS: ${{ secrets.KEYSTORE_KEY_PASSWORD }} | |
| DEBUG_STORE_PASS: ${{ secrets.KEYSTORE_STORE_PASSWORD }} | |
| PROD_ALIAS: ${{ secrets.PROD_KEYSTORE_KEY_ALIAS }} | |
| PROD_KEY_PASS: ${{ secrets.PROD_KEYSTORE_KEY_PASSWORD }} | |
| PROD_STORE_PASS: ${{ secrets.PROD_KEYSTORE_STORE_PASSWORD }} | |
| run: | | |
| BUILD_TOOLS_DIR="${ANDROID_HOME}/build-tools/34.0.0" | |
| if [ ! -d "$BUILD_TOOLS_DIR" ]; then | |
| BUILD_TOOLS_DIR="${ANDROID_SDK_ROOT}/build-tools/34.0.0" | |
| fi | |
| for apk in universal.apk universal-modern.apk universal-legacy-xr.apk; do | |
| "${BUILD_TOOLS_DIR}/apksigner" sign \ | |
| --lineage app/keystores/prod-debug.lineage \ | |
| --ks app/keystores/keystore \ | |
| --ks-key-alias "$DEBUG_ALIAS" \ | |
| --ks-pass pass:$DEBUG_STORE_PASS \ | |
| --key-pass pass:$DEBUG_KEY_PASS \ | |
| --next-signer --ks app/keystores/prod.keystore \ | |
| --ks-key-alias "$PROD_ALIAS" \ | |
| --ks-pass pass:$PROD_STORE_PASS \ | |
| --key-pass pass:$PROD_KEY_PASS \ | |
| --out "${apk%.apk}-signed.apk" \ | |
| "$apk" | |
| mv "${apk%.apk}-signed.apk" "$apk" | |
| done | |
| - name: Upload Legacy APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-signed | |
| path: ${{ github.workspace }}/universal.apk | |
| - name: Upload Modern APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-signed-modern | |
| path: ${{ github.workspace }}/universal-modern.apk | |
| - name: Upload Legacy XR APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-release-signed-legacy-xr | |
| path: ${{ github.workspace }}/universal-legacy-xr.apk | |
| - name: Build changelog text | |
| id: changelog | |
| run: | | |
| text=$(jq -r '.commits[] | "• " + (.message | split("\n")[0]) + " (" + .id[0:7] + ")"' "$GITHUB_EVENT_PATH") | |
| # Stable random delimiter so newlines in $text can't terminate the heredoc. | |
| delim="EOF_$(openssl rand -hex 8)" | |
| { | |
| echo "log<<$delim" | |
| echo "$text" | |
| echo "$delim" | |
| } >>"$GITHUB_OUTPUT" | |
| - name: Post to Discord | |
| env: | |
| DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} | |
| # Read via env to avoid shell-quoting traps with multiline changelogs. | |
| CHANGELOG: ${{ steps.changelog.outputs.log }} | |
| LEGACY_URL: https://nightly.link/utkarshdalal/GameNative/actions/runs/${{ github.run_id }}/app-release-signed.zip | |
| MODERN_URL: https://nightly.link/utkarshdalal/GameNative/actions/runs/${{ github.run_id }}/app-release-signed-modern.zip | |
| LEGACY_XR_URL: https://nightly.link/utkarshdalal/GameNative/actions/runs/${{ github.run_id }}/app-release-signed-legacy-xr.zip | |
| run: | | |
| # jq -n handles JSON escaping (newlines, quotes, etc.) for us. | |
| payload=$(jq -n \ | |
| --arg legacy "$LEGACY_URL" \ | |
| --arg modern "$MODERN_URL" \ | |
| --arg legacyXr "$LEGACY_XR_URL" \ | |
| --arg changes "$CHANGELOG" \ | |
| '{content: "**New Android build**\nRegular Build (Recommended): \($legacy)\nModern Build (Play Store, features stripped): \($modern)\nXR Build (for Quest): \($legacyXr)\n\nChanges:\n\($changes)"}') | |
| curl -H 'Content-Type: application/json' -d "$payload" "$DISCORD_WEBHOOK_URL" |