ci: route Android APK through Forgejo releases
All checks were successful
Forgejo Android APK / Build signed APK (push) Successful in 1m54s
All checks were successful
Forgejo Android APK / Build signed APK (push) Successful in 1m54s
This commit is contained in:
parent
2bbdb88ceb
commit
04659059d0
8 changed files with 107 additions and 10 deletions
|
|
@ -3,6 +3,8 @@ name: Forgejo Android APK
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- 'v*'
|
||||||
|
|
||||||
|
|
@ -61,6 +63,60 @@ jobs:
|
||||||
-Pandroid.injected.signing.key.password="$KEY_PASS" \
|
-Pandroid.injected.signing.key.password="$KEY_PASS" \
|
||||||
--no-daemon --stacktrace
|
--no-daemon --stacktrace
|
||||||
|
|
||||||
|
- name: Check Google Play secret
|
||||||
|
id: play_publish
|
||||||
|
run: |
|
||||||
|
if [[ "$GITHUB_REF" != refs/tags/v* ]]; then
|
||||||
|
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
||||||
|
elif [ -z "${GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64:-}" ]; then
|
||||||
|
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64 }}
|
||||||
|
|
||||||
|
- name: Build signed release App Bundle
|
||||||
|
if: steps.play_publish.outputs.enabled == 'true'
|
||||||
|
working-directory: mobile/android
|
||||||
|
env:
|
||||||
|
KS_PASS: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||||
|
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||||
|
KEY_PASS: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
./gradlew bundleRelease \
|
||||||
|
-Pandroid.injected.signing.store.file="$RUNNER_TEMP/pedscribe-release.jks" \
|
||||||
|
-Pandroid.injected.signing.store.password="$KS_PASS" \
|
||||||
|
-Pandroid.injected.signing.key.alias="$KEY_ALIAS" \
|
||||||
|
-Pandroid.injected.signing.key.password="$KEY_PASS" \
|
||||||
|
--no-daemon --stacktrace
|
||||||
|
|
||||||
|
- name: Install fastlane
|
||||||
|
if: steps.play_publish.outputs.enabled == 'true'
|
||||||
|
working-directory: mobile/android
|
||||||
|
run: |
|
||||||
|
gem install bundler -N
|
||||||
|
bundle install
|
||||||
|
|
||||||
|
- name: Upload bundle to Google Play (internal track)
|
||||||
|
if: steps.play_publish.outputs.enabled == 'true'
|
||||||
|
working-directory: mobile/android
|
||||||
|
env:
|
||||||
|
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64 }}
|
||||||
|
PLAY_TRACK: internal
|
||||||
|
run: |
|
||||||
|
test -n "$GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64"
|
||||||
|
|
||||||
|
CLEAN_PLAY_JSON_B64="${GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64#GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64=}"
|
||||||
|
printf '%s' "$CLEAN_PLAY_JSON_B64" | tr -d '\r\n' | base64 -d > fastlane/google-play-service-account.json
|
||||||
|
|
||||||
|
AAB=$(find app/build/outputs/bundle/release -name '*.aab' | head -1)
|
||||||
|
test -n "$AAB"
|
||||||
|
|
||||||
|
AAB_PATH="$AAB" bundle exec fastlane android publish_internal
|
||||||
|
|
||||||
|
rm -f fastlane/google-play-service-account.json
|
||||||
|
|
||||||
- name: Collect APK
|
- name: Collect APK
|
||||||
run: |
|
run: |
|
||||||
mkdir -p artifacts
|
mkdir -p artifacts
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ or Actions tab → **Version bump & release** → Run workflow → pick bump typ
|
||||||
|
|
||||||
| Workflow | Output |
|
| Workflow | Output |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `android-release.yml` | signed APK on GitHub release, `make_latest=true` |
|
| `.forgejo/workflows/android-apk.yml` | signed APK on Forgejo release (`pedscribe-<tag>.apk`), optional Google Play internal track upload |
|
||||||
| `docker-publish.yml` | `danielonyejesi/pediatric-ai-scribe-v3:{version,latest}` on Docker Hub (amd64) |
|
| `docker-publish.yml` | `danielonyejesi/pediatric-ai-scribe-v3:{version,latest}` on Docker Hub (amd64) |
|
||||||
|
|
||||||
## Local dev
|
## Local dev
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,13 @@ mobile/ # Capacitor wrapper
|
||||||
src/ # launcher (server-URL picker)
|
src/ # launcher (server-URL picker)
|
||||||
android/ # generated AS project + native Java
|
android/ # generated AS project + native Java
|
||||||
|
|
||||||
|
.forgejo/workflows/
|
||||||
|
android-apk.yml # signed APK on tag push; optional Play upload
|
||||||
|
docker-build.yml # Forgejo registry Docker image build
|
||||||
|
|
||||||
.github/workflows/
|
.github/workflows/
|
||||||
auto-version.yml # conventional-commits → semver bump → tag
|
auto-version.yml # conventional-commits → semver bump → tag
|
||||||
android-release.yml # signed APK on tag push
|
android-release.yml # legacy GitHub tag APK release path
|
||||||
docker-publish.yml # multi-arch image on tag push
|
docker-publish.yml # multi-arch image on tag push
|
||||||
version-bump.yml # manual dispatch override
|
version-bump.yml # manual dispatch override
|
||||||
build-apk.yml # legacy TWA APK
|
build-apk.yml # legacy TWA APK
|
||||||
|
|
|
||||||
|
|
@ -146,11 +146,11 @@ Container marked unhealthy after 5 failures.
|
||||||
|
|
||||||
## CI / CD
|
## CI / CD
|
||||||
|
|
||||||
Four workflows fire on tag push:
|
On push (and tag push), these workflows run (depending on runner/site):
|
||||||
|
|
||||||
| Workflow | Output | Runtime |
|
| Workflow | Output | Runtime |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `android-release.yml` | Signed APK attached to the GitHub release | ~8 min |
|
| `.forgejo/workflows/android-apk.yml` | Signed APK attached to the Forgejo release, plus optional Google Play internal track upload | ~8 min |
|
||||||
| `docker-publish.yml` | Multi-arch image (amd64 + arm64 via native runners) on Docker Hub | ~4 min |
|
| `docker-publish.yml` | Multi-arch image (amd64 + arm64 via native runners) on Docker Hub | ~4 min |
|
||||||
| `build-apk.yml` | Legacy TWA APK (optional second artifact) | ~2 min |
|
| `build-apk.yml` | Legacy TWA APK (optional second artifact) | ~2 min |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,12 @@ npx cap open android
|
||||||
|
|
||||||
## CI build (preferred)
|
## CI build (preferred)
|
||||||
|
|
||||||
Tag-triggered. Push any `vX.Y.Z` tag → `.github/workflows/android-release.yml`
|
Push-triggered. Any push to `main`/feature branches and any `vX.Y.Z` tag push
|
||||||
builds a signed APK on a GitHub runner and attaches it to the matching release.
|
→ `.forgejo/workflows/android-apk.yml` builds a signed APK on the Forgejo
|
||||||
|
runner.
|
||||||
|
|
||||||
|
Tagged builds additionally publish the artifact to the matching Forgejo release
|
||||||
|
as `pedscribe-<tag>.apk` so Obtainium can track updates.
|
||||||
|
|
||||||
Required repo secrets (set once, via Settings → Secrets and variables → Actions
|
Required repo secrets (set once, via Settings → Secrets and variables → Actions
|
||||||
or `gh secret set`):
|
or `gh secret set`):
|
||||||
|
|
@ -36,6 +40,14 @@ or `gh secret set`):
|
||||||
- `ANDROID_KEYSTORE_PASSWORD`
|
- `ANDROID_KEYSTORE_PASSWORD`
|
||||||
- `ANDROID_KEY_ALIAS` — `pedscribe`
|
- `ANDROID_KEY_ALIAS` — `pedscribe`
|
||||||
- `ANDROID_KEY_PASSWORD`
|
- `ANDROID_KEY_PASSWORD`
|
||||||
|
- `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64` — base64 of your Google Play service
|
||||||
|
account JSON (optional). If present, the same tag build also runs `bundleRelease`
|
||||||
|
and uploads the AAB to Play's `internal` track.
|
||||||
|
|
||||||
|
Optional Play Store flow:
|
||||||
|
- Service account must have permissions to edit releases on the app in Play.
|
||||||
|
- Build task is `bundleRelease`, tracked as `com.pedshub.scribe`.
|
||||||
|
- Upload lane is `fastlane/android publish_internal` (under `mobile/android/fastlane`).
|
||||||
|
|
||||||
Tag a release:
|
Tag a release:
|
||||||
|
|
||||||
|
|
@ -48,9 +60,10 @@ git commit -m "fix: ..." && git push # auto-version workflow bumps patch
|
||||||
scripts/release.sh X.Y.Z --push
|
scripts/release.sh X.Y.Z --push
|
||||||
```
|
```
|
||||||
|
|
||||||
APK lands at the GitHub release; `/releases/latest` link in the login page
|
APK lands on the Forgejo release. Obtainium can still track
|
||||||
resolves to it automatically. Obtanium subscribers (`github.com/<owner>/<repo>`)
|
`git.danvics.com/danvics/pediatric-ai-scribe-v3` releases automatically.
|
||||||
pick up the update on next poll.
|
Play Store upload is handled automatically for tagged builds only when
|
||||||
|
`GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_B64` is configured.
|
||||||
|
|
||||||
## Local build (fallback / debugging)
|
## Local build (fallback / debugging)
|
||||||
|
|
||||||
|
|
@ -116,4 +129,5 @@ user to uninstall + reinstall.
|
||||||
| `mobile/android/app/src/main/java/com/pedshub/scribe/MainActivity.java` | JS bridge + WebView mic permission |
|
| `mobile/android/app/src/main/java/com/pedshub/scribe/MainActivity.java` | JS bridge + WebView mic permission |
|
||||||
| `mobile/android/app/src/main/java/com/pedshub/scribe/AudioRecordingService.java` | foreground service for background recording |
|
| `mobile/android/app/src/main/java/com/pedshub/scribe/AudioRecordingService.java` | foreground service for background recording |
|
||||||
| `mobile/android/app/src/main/AndroidManifest.xml` | permissions, intents, backup rules |
|
| `mobile/android/app/src/main/AndroidManifest.xml` | permissions, intents, backup rules |
|
||||||
| `.github/workflows/android-release.yml` | CI build |
|
| `.forgejo/workflows/android-apk.yml` | CI build |
|
||||||
|
| `mobile/android/fastlane/Fastfile` | internal Play track upload lane |
|
||||||
|
|
|
||||||
2
mobile/android/fastlane/Appfile
Normal file
2
mobile/android/fastlane/Appfile
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
json_key_file('fastlane/google-play-service-account.json')
|
||||||
|
package_name('com.pedshub.scribe')
|
||||||
18
mobile/android/fastlane/Fastfile
Normal file
18
mobile/android/fastlane/Fastfile
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
default_platform(:android)
|
||||||
|
|
||||||
|
platform :android do
|
||||||
|
desc "Upload a signed release AAB to Google Play internal track"
|
||||||
|
lane :publish_internal do
|
||||||
|
upload_to_play_store(
|
||||||
|
package_name: 'com.pedshub.scribe',
|
||||||
|
json_key: 'fastlane/google-play-service-account.json',
|
||||||
|
aab: ENV['AAB_PATH'] || 'app/build/outputs/bundle/release/app-release.aab',
|
||||||
|
track: ENV['PLAY_TRACK'] || 'internal',
|
||||||
|
skip_upload_changelogs: true,
|
||||||
|
skip_upload_metadata: true,
|
||||||
|
skip_upload_images: true,
|
||||||
|
skip_upload_screenshots: true,
|
||||||
|
release_status: 'completed',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
3
mobile/android/fastlane/Gemfile
Normal file
3
mobile/android/fastlane/Gemfile
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'fastlane'
|
||||||
Loading…
Reference in a new issue