feat: build and sign Android releases on tag push via Forgejo
Some checks failed
Release APK / build (push) Failing after 40s

Reads the release keystore from env vars in CI, falling back to the
debug keys locally. Adds fastlane metadata for F-Droid/Obtainium and
a .forgejo workflow that builds, signs, and publishes the APK on
pushing a vX.Y.Z+N tag.
This commit is contained in:
randogoth 2026-10-14 10:54:00 +03:00
parent f386ef2c5b
commit 7e171862a5
8 changed files with 86 additions and 6 deletions

View file

@ -0,0 +1,62 @@
name: Release APK
on:
push:
tags: ["v*"]
jobs:
build:
runs-on: android
steps:
- uses: actions/checkout@v4
- name: Extract version
run: |
VERSION=$(grep '^version:' app/pubspec.yaml | sed 's/version: //')
echo "VERSION_CODE=$(echo "$VERSION" | grep -oP '(?<=\+)\d+')" >> $GITHUB_ENV
echo "VERSION_NAME=$(echo "$VERSION" | grep -oP '^[^+]+')" >> $GITHUB_ENV
- name: Decode keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > app/android/app/release.jks
echo "KEYSTORE_PATH=$GITHUB_WORKSPACE/app/android/app/release.jks" >> $GITHUB_ENV
- name: Build release APK
env:
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
# Host-mode runners share ~/.gradle (including the daemon) across
# unrelated projects; a warm daemon from another build can poison
# this one. Keep caches shared, just don't attach to a daemon.
GRADLE_OPTS: -Dorg.gradle.daemon=false
run: |
cd app
env -u GITHUB_TOKEN -u GH_TOKEN -u JAVA_HOME \
devbox run -- flutter build apk --release
- name: Create release and upload APK
env:
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
APK="mews-${{ env.VERSION_NAME }}.apk"
cp app/build/app/outputs/flutter-apk/app-release.apk "$APK"
BODY=$(python3 -c "
import json
print(json.dumps(open('app/fastlane/metadata/android/en-US/changelogs/${{ env.VERSION_CODE }}.txt').read().strip()))
")
RELEASE_ID=$(curl -sf -X POST \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
"$GITHUB_SERVER_URL/api/v1/repos/$GITHUB_REPOSITORY/releases" \
-d "{\"tag_name\":\"$GITHUB_REF_NAME\",\"name\":\"$GITHUB_REF_NAME\",\"body\":$BODY}" \
| python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')
curl -sf -X POST \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/vnd.android.package-archive" \
"$GITHUB_SERVER_URL/api/v1/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets?name=$APK" \
--data-binary @"$APK"

View file

@ -23,21 +23,28 @@ android {
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "page.mews.mews"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
create("release") {
storeFile = System.getenv("KEYSTORE_PATH")?.let { file(it) }
storePassword = System.getenv("STORE_PASSWORD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
// Falls back to the debug keys locally, so `flutter run --release`
// keeps working without a keystore on hand.
signingConfig = if (System.getenv("KEYSTORE_PATH") != null)
signingConfigs.getByName("release") else signingConfigs.getByName("debug")
}
}
}

1
app/fastlane/Fastfile Normal file
View file

@ -0,0 +1 @@
default_platform(:android)

View file

@ -0,0 +1 @@
First release.

View file

@ -0,0 +1,7 @@
The Mews Browser is a reader for Mews pages, Gemini capsules, and Spartan
sites. It's local-first: pages, bookmarks, subscriptions, and reading
settings live in a local database, and network access only revalidates the
cache.
The reader controls presentation, not the page author, so every site reads
consistently in the typeface, size, and color you choose.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View file

@ -0,0 +1 @@
A local-first reader for Mews pages, Gemini capsules, and Spartan sites.

View file

@ -0,0 +1 @@
The Mews Browser