Skip to content

fix: dxwrappers and graphic drivers downloader handling on custom con… #760

fix: dxwrappers and graphic drivers downloader handling on custom con…

fix: dxwrappers and graphic drivers downloader handling on custom con… #760

name: Android CI
on:
push:
branches: [ "master" ]
paths-ignore:
- '**.md'
- '.gitignore'
- 'keyvalues/**'
- 'media/**'
- '.github/ISSUE_TEMPLATE/**'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
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
- 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
- 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
- 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; 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: 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
run: |
# jq -n handles JSON escaping (newlines, quotes, etc.) for us.
payload=$(jq -n \
--arg legacy "$LEGACY_URL" \
--arg modern "$MODERN_URL" \
--arg changes "$CHANGELOG" \
'{content: "**New Android build**\nStandard Build (Recommended): \($legacy)\nPlay Store Build (Android 11+ — built for the latest Android, so **no security warning** about an outdated target. No D drive access and no custom game support; glibc not supported, external storage location moved.): \($modern)\n\nChanges:\n\($changes)"}')
curl -H 'Content-Type: application/json' -d "$payload" "$DISCORD_WEBHOOK_URL"