From 5e05ad192d95ac42dbbeb021f78eb21295254ef9 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sat, 29 Aug 2026 14:43:18 -0500 Subject: [PATCH] ci: align Githug-Android workflow with Android release pattern --- .gitea/workflows/android-build.yml | 138 +++++++++++++++++++++++++++++ app/build.gradle.kts | 16 +++- 2 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 .gitea/workflows/android-build.yml diff --git a/.gitea/workflows/android-build.yml b/.gitea/workflows/android-build.yml new file mode 100644 index 0000000..7e15732 --- /dev/null +++ b/.gitea/workflows/android-build.yml @@ -0,0 +1,138 @@ +name: Android build + +permissions: + contents: read + releases: write + +on: + push: + branches: + - '**' + pull_request: + release: + types: + - published + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 90 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java 17 + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: '17' + + - name: Install Android SDK command-line tools and packages + shell: bash + run: | + set -euxo pipefail + export ANDROID_SDK_ROOT="$HOME/.android/sdk" + export ANDROID_HOME="$ANDROID_SDK_ROOT" + mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools" + if [ ! -x "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then + tools_url="$(curl -fsSL https://developer.android.com/studio | grep -o 'https://dl.google.com/android/repository/commandlinetools-linux-[0-9][0-9]*_latest.zip' | head -n 1)" + test -n "$tools_url" + curl -fsSL -o /tmp/commandlinetools.zip "$tools_url" + rm -rf "$ANDROID_SDK_ROOT/cmdline-tools/latest" "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" + unzip -q /tmp/commandlinetools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools" + mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest" + fi + export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH" + set +o pipefail + yes | sdkmanager --licenses >/dev/null + set -o pipefail + sdkmanager \ + "platform-tools" \ + "platforms;android-35" \ + "build-tools;35.0.0" \ + "ndk;27.2.12479018" \ + "cmake;3.22.1" + + - name: Prepare optional release signing + if: github.event_name == 'release' + continue-on-error: true + env: + ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} + ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} + shell: bash + run: | + set -euo pipefail + missing=() + for key in ANDROID_KEYSTORE_BASE64 ANDROID_KEYSTORE_PASSWORD ANDROID_KEY_ALIAS ANDROID_KEY_PASSWORD; do + if [ -z "${!key:-}" ]; then + missing+=("$key") + fi + done + if [ ${#missing[@]} -gt 0 ]; then + printf -v missing_csv '%s, ' "${missing[@]}" + missing_csv="${missing_csv%, }" + echo "::error::Release signing secrets missing: ${missing_csv}. Continuing with unsigned/default-signed release AAB." + exit 1 + fi + mkdir -p .ci-secrets + printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 -d > .ci-secrets/release-keystore.jks + cat > keystore.properties < local.properties + + - name: Build debug APK + if: github.event_name != 'release' + shell: bash + run: | + set -euxo pipefail + export ANDROID_SDK_ROOT="$HOME/.android/sdk" + export ANDROID_HOME="$ANDROID_SDK_ROOT" + ./gradlew --no-daemon clean assembleDebug + + - name: Build release AAB + if: github.event_name == 'release' + shell: bash + run: | + set -euxo pipefail + export ANDROID_SDK_ROOT="$HOME/.android/sdk" + export ANDROID_HOME="$ANDROID_SDK_ROOT" + ./gradlew --no-daemon bundleRelease + + - name: Upload debug APK + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: debug-apk + path: app/build/outputs/apk/debug/*.apk + if-no-files-found: error + + - name: Attach release AAB to Gitea release + if: github.event_name == 'release' + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + shell: bash + run: | + set -euxo pipefail + release_id="$(python3 -c 'import json, os; print(json.load(open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8"))["release"]["id"])')" + aab="$(find app/build/outputs/bundle/release -name '*.aab' | head -n 1)" + curl --fail-with-body \ + --request POST \ + --header "Authorization: token ${GITEA_TOKEN}" \ + --form "attachment=@${aab}" \ + "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${release_id}/assets?name=$(basename "$aab")" diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f664117..13734af 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,10 +1,16 @@ import java.util.Properties -val keystoreProperties = Properties() val keystorePropertiesFile = rootProject.file("keystore.properties") +val keystoreProperties = Properties() if (keystorePropertiesFile.exists()) { keystorePropertiesFile.inputStream().use { keystoreProperties.load(it) } } +val hasReleaseSigning = listOf( + "storeFile", + "storePassword", + "keyAlias", + "keyPassword", +).all { !keystoreProperties.getProperty(it).isNullOrBlank() } plugins { id("com.android.application") @@ -34,9 +40,9 @@ android { } signingConfigs { - if (keystorePropertiesFile.exists()) { + if (hasReleaseSigning) { create("release") { - storeFile = file(keystoreProperties.getProperty("storeFile")) + storeFile = rootProject.file(keystoreProperties.getProperty("storeFile")) storePassword = keystoreProperties.getProperty("storePassword") keyAlias = keystoreProperties.getProperty("keyAlias") keyPassword = keystoreProperties.getProperty("keyPassword") @@ -45,9 +51,11 @@ android { } buildTypes { + debug { + } release { isMinifyEnabled = false - if (signingConfigs.findByName("release") != null) { + if (hasReleaseSigning) { signingConfig = signingConfigs.getByName("release") } proguardFiles(