ci(android): optimize release build to single pass with ABI splits and universal APK, pre-install platform SDKs, and increase timeout
Build Android APK / Build Release APKs (push) Failing after 14m39s

This commit is contained in:
2026-09-17 22:02:50 +02:00
parent c655ba713b
commit b7b6c4a2ab
2 changed files with 60 additions and 13 deletions
+43 -10
View File
@@ -25,6 +25,7 @@ jobs:
build-android: build-android:
name: Build Release APKs name: Build Release APKs
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 180
permissions: permissions:
contents: write contents: write
container: container:
@@ -118,8 +119,8 @@ jobs:
# the NDK Flutter expects up front and swap in Ubuntu's native arm64 llvm-strip. # the NDK Flutter expects up front and swap in Ubuntu's native arm64 llvm-strip.
NDK_VERSION="$(sed -nE 's/.*ndkVersion: String = "([^"]+)".*/\1/p' "${FLUTTER_ROOT:-/sdks/flutter}/packages/flutter_tools/gradle/src/main/kotlin/FlutterExtension.kt")" NDK_VERSION="$(sed -nE 's/.*ndkVersion: String = "([^"]+)".*/\1/p' "${FLUTTER_ROOT:-/sdks/flutter}/packages/flutter_tools/gradle/src/main/kotlin/FlutterExtension.kt")"
[ -n "$NDK_VERSION" ] || { echo "::error::Could not determine Flutter's NDK version"; exit 1; } [ -n "$NDK_VERSION" ] || { echo "::error::Could not determine Flutter's NDK version"; exit 1; }
echo "Installing NDK $NDK_VERSION ..." echo "Installing NDK $NDK_VERSION and Android SDK platforms 34 & 35 ..."
yes | sdkmanager --install "ndk;${NDK_VERSION}" > /dev/null yes | sdkmanager --install "platforms;android-34" "platforms;android-35" "ndk;${NDK_VERSION}" > /dev/null
NDK_BIN="${ANDROID_HOME:-/opt/android-sdk-linux}/ndk/${NDK_VERSION}/toolchains/llvm/prebuilt/linux-x86_64/bin" NDK_BIN="${ANDROID_HOME:-/opt/android-sdk-linux}/ndk/${NDK_VERSION}/toolchains/llvm/prebuilt/linux-x86_64/bin"
for tool in llvm-strip llvm-objcopy; do for tool in llvm-strip llvm-objcopy; do
mv "$NDK_BIN/$tool" "$NDK_BIN/$tool.x86_64" mv "$NDK_BIN/$tool" "$NDK_BIN/$tool.x86_64"
@@ -162,21 +163,53 @@ jobs:
flutter analyze flutter analyze
flutter test flutter test
- name: Build Universal Release APK - name: Build Release APKs (Split-per-ABI & Universal)
run: flutter build apk --release
- name: Build Split-per-ABI Release APKs
run: flutter build apk --release --split-per-abi
- name: Organize Artifacts
run: | run: |
flutter build apk --release --split-per-abi
mkdir -p release-apks mkdir -p release-apks
# Copy universal APK # Locate universal APK generated by AGP splits
for f in \
build/app/outputs/flutter-apk/app-universal-release.apk \
build/app/outputs/flutter-apk/*universal*.apk \
android/app/build/outputs/apk/release/app-universal-release.apk \
android/app/build/outputs/apk/release/*universal*.apk \
build/app/outputs/flutter-apk/app-release.apk \
android/app/build/outputs/apk/release/app-release.apk; do
if [ -f "$f" ]; then
echo "Found universal APK at $f"
cp "$f" release-apks/oggauer-gemeindetrommler-universal.apk
break
fi
done
# Fallback: if universal APK was not created by split build, build it explicitly
if [ ! -f release-apks/oggauer-gemeindetrommler-universal.apk ]; then
echo "Universal APK not found from split build; running fallback universal build..."
flutter build apk --release
if [ -f build/app/outputs/flutter-apk/app-release.apk ]; then if [ -f build/app/outputs/flutter-apk/app-release.apk ]; then
cp build/app/outputs/flutter-apk/app-release.apk release-apks/oggauer-gemeindetrommler-universal.apk cp build/app/outputs/flutter-apk/app-release.apk release-apks/oggauer-gemeindetrommler-universal.apk
elif [ -f android/app/build/outputs/apk/release/app-release.apk ]; then elif [ -f android/app/build/outputs/apk/release/app-release.apk ]; then
cp android/app/build/outputs/apk/release/app-release.apk release-apks/oggauer-gemeindetrommler-universal.apk cp android/app/build/outputs/apk/release/app-release.apk release-apks/oggauer-gemeindetrommler-universal.apk
fi fi
fi
- name: Organize Artifacts
run: |
mkdir -p release-apks
# Copy universal APK if not already in release-apks
if [ ! -f release-apks/oggauer-gemeindetrommler-universal.apk ]; then
for f in \
build/app/outputs/flutter-apk/app-universal-release.apk \
build/app/outputs/flutter-apk/*universal*.apk \
android/app/build/outputs/apk/release/app-universal-release.apk \
android/app/build/outputs/apk/release/*universal*.apk \
build/app/outputs/flutter-apk/app-release.apk \
android/app/build/outputs/apk/release/app-release.apk; do
if [ -f "$f" ]; then
cp "$f" release-apks/oggauer-gemeindetrommler-universal.apk
break
fi
done
fi
# Copy split APKs # Copy split APKs
for apk in build/app/outputs/flutter-apk/*.apk android/app/build/outputs/apk/release/*.apk; do for apk in build/app/outputs/flutter-apk/*.apk android/app/build/outputs/apk/release/*.apk; do
[ -f "$apk" ] || continue [ -f "$apk" ] || continue
+15 -1
View File
@@ -34,10 +34,24 @@ android {
buildTypes { buildTypes {
release { release {
// TODO: Add your own signing config for the release build. // TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
} }
splits {
abi {
enable true
reset()
include "arm64-v8a", "armeabi-v7a", "x86_64"
universalApk true
}
}
}
afterEvaluate {
tasks.named('assembleRelease').configure {
dependsOn 'packageReleaseUniversalApk'
}
} }
kotlin { kotlin {