mirror of
https://github.com/tiennm99/loto.git
synced 2026-10-13 06:15:44 +00:00
feat(android)!: replace the Capacitor wrapper with a native Kotlin/Compose app
Fresh Kotlin 2.2 + Jetpack Compose app at feature parity with web/ (game logic, settings contract, voice semantics ported one-to-one with twinned tests; 104 unit + 9 instrumentation tests). Fully offline: VIBRATE is the only permission; Media3's ACCESS_NETWORK_STATE is stripped. Voice clips mount from web/static/audio at build time. Same applicationId, signing env contract, and Play alpha track; versionCode 7 / 0.2.0. CI Android job is Gradle-only (lint, test, debug + R8 release APK) and the release workflow fails fast on an unbumped versionCode. BREAKING CHANGE: WebView localStorage (settings, in-progress round) is not migrated; wrapper users start clean.
This commit is contained in:
1 parent
8f9b03ca05
commit
e314ae01c8
126 files changed
+6390
-2275
No files matched your search
@@ -23,23 +23,43 @@ jobs:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
# Full history + tags for the versionCode guard below.
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: ./.github/actions/setup-web
|
||||
|
||||
# ci.yml does not run on tags, so this is the only gate before signing.
|
||||
- name: Test web
|
||||
run: npm test
|
||||
working-directory: web
|
||||
|
||||
# Base "" — the APK loads the bundle from the domain root.
|
||||
- name: Build web
|
||||
run: npm run build
|
||||
working-directory: web
|
||||
# Play rejects an upload whose versionCode is not higher than the last
|
||||
# one, but only after the whole build has run — fail fast instead.
|
||||
# Compares this tag's versionCode against the previous v*.*.* tag,
|
||||
# reading the wrapper-era path for tags that predate the native app.
|
||||
- name: Guard against an unbumped versionCode
|
||||
run: |
|
||||
set -eu
|
||||
current=$(grep -oP 'versionCode = \K\d+' android/app/build.gradle.kts)
|
||||
echo "versionCode at ${GITHUB_REF_NAME}: $current"
|
||||
prev_tag=$(git tag --list 'v*.*.*' --sort=-v:refname | grep -Fvx "${GITHUB_REF_NAME}" | head -n1 || true)
|
||||
if [ -z "$prev_tag" ]; then
|
||||
echo "No previous release tag; skipping comparison."
|
||||
exit 0
|
||||
fi
|
||||
prev=$(git show "$prev_tag:android/app/build.gradle.kts" 2>/dev/null | grep -oP 'versionCode = \K\d+' || true)
|
||||
if [ -z "$prev" ]; then
|
||||
# Wrapper-era layout (Capacitor project under android/android/).
|
||||
prev=$(git show "$prev_tag:android/android/app/build.gradle" 2>/dev/null | grep -oP 'versionCode \K\d+' || true)
|
||||
fi
|
||||
if [ -z "$prev" ]; then
|
||||
echo "::warning::Could not read versionCode at $prev_tag; skipping comparison."
|
||||
exit 0
|
||||
fi
|
||||
echo "versionCode at $prev_tag: $prev"
|
||||
if [ "$current" -le "$prev" ]; then
|
||||
echo "::error::versionCode $current at ${GITHUB_REF_NAME} must be greater than $prev at $prev_tag. Bump it in android/app/build.gradle.kts before tagging."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: ./.github/actions/setup-android
|
||||
|
||||
- name: Sync web bundle into the native project
|
||||
run: npm run sync
|
||||
# ci.yml does not run on tags, so this is the only gate before signing.
|
||||
- name: Lint and test
|
||||
run: ./gradlew :app:lint :app:test
|
||||
working-directory: android
|
||||
|
||||
- name: Decode keystore
|
||||
@@ -48,7 +68,7 @@ jobs:
|
||||
run: printf '%s' "$KEYSTORE_BASE64" | base64 --decode > "$GITHUB_WORKSPACE/keystore.p12"
|
||||
|
||||
- name: Build signed AAB + APK
|
||||
working-directory: android/android
|
||||
working-directory: android
|
||||
env:
|
||||
LOTO_KEYSTORE_PATH: ${{ github.workspace }}/keystore.p12
|
||||
LOTO_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
||||
@@ -60,8 +80,8 @@ jobs:
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
files: |
|
||||
android/android/app/build/outputs/apk/release/*.apk
|
||||
android/android/app/build/outputs/bundle/release/*.aab
|
||||
android/app/build/outputs/apk/release/*.apk
|
||||
android/app/build/outputs/bundle/release/*.aab
|
||||
|
||||
# Auto-publish to Google Play (gated on the service-account secret).
|
||||
# Skips silently if PLAY_SERVICE_ACCOUNT_JSON is not configured, so
|
||||
@@ -89,8 +109,8 @@ jobs:
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
|
||||
packageName: com.miti99.loto
|
||||
releaseFiles: android/android/app/build/outputs/bundle/release/*.aab
|
||||
releaseFiles: android/app/build/outputs/bundle/release/*.aab
|
||||
tracks: alpha
|
||||
status: completed
|
||||
# Bumps versionCode automatically? No — must be incremented
|
||||
# manually in android/android/app/build.gradle before tagging.
|
||||
# versionCode is bumped manually in android/app/build.gradle.kts
|
||||
# before tagging; the guard step above catches a forgotten bump.
|
||||
@@ -3,9 +3,11 @@
|
||||
# The web app is built twice and only twice — once per base path — and every
|
||||
# consumer downloads an artifact instead of rebuilding:
|
||||
#
|
||||
# build (root, base "") -> deploy-firebase, preview-firebase, android-debug
|
||||
# build (root, base "") -> deploy-firebase, preview-firebase
|
||||
# build (gh, base /loto) -> deploy-pages
|
||||
#
|
||||
# The Android app is native Kotlin/Compose and builds independently of the
|
||||
# web bundle (it mounts web/static/audio straight from the checkout).
|
||||
# Tags are handled by android-release.yml, which builds standalone.
|
||||
|
||||
name: ci
|
||||
@@ -154,28 +156,20 @@ jobs:
|
||||
entryPoint: web
|
||||
|
||||
android-debug:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: web-build
|
||||
# capacitor.config.json declares `webDir: "../web/build"`.
|
||||
path: web/build
|
||||
- uses: ./.github/actions/setup-android
|
||||
# `npm run build` would rebuild web/; the bundle is already here.
|
||||
- name: Sync web bundle into the native project
|
||||
run: npm run sync
|
||||
# assembleRelease runs R8 with no secrets needed (unsigned without
|
||||
# LOTO_KEYSTORE_PATH) so a missing keep rule fails CI, not the tag.
|
||||
- name: Lint, test and assemble debug + release APKs
|
||||
run: ./gradlew :app:lint :app:test :app:assembleDebug :app:assembleRelease
|
||||
working-directory: android
|
||||
- name: Assemble debug APK
|
||||
run: ./gradlew :app:assembleDebug
|
||||
working-directory: android/android
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: app-debug.apk
|
||||
path: android/android/app/build/outputs/apk/debug/*.apk
|
||||
path: android/app/build/outputs/apk/debug/*.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
Reference in new issue
Block a user