Skip to content

✨ feat(android): add Play Store TWA packaging - #37

Open
martinezharo wants to merge 3 commits into
mainfrom
t3/play-store-pwa-readiness
Open

martinezharo wants to merge 3 commits into
mainfrom
t3/play-store-pwa-readiness

Conversation

@martinezharo

Copy link
Copy Markdown
Owner

Summary

Adds the Android Trusted Web Activity wrapper needed to publish SendSelf on Google Play, and parks the work here so it can be resumed later.

Nothing is published by this PR: the Play Console account, the Play App Signing fingerprint, and the production deploy are still pending.

Included

  • apps/android: Gradle project targeting API 36 (minSdk 26), package com.fourli.sendself, App Links with autoVerify, adaptive/monochrome icons, branded splash, and notification delegation for the future Web Push work.
  • Android share sheet wired to the existing /share-target flow through the browser helper's METADATA_SHARE_TARGET.
  • Worker route for /.well-known/assetlinks.json, generated from android.config.json so the Android build and the Worker cannot drift.
  • Play listing artwork (512px icon, 1024×500 feature graphic, five 1080×1920 screenshots) and listing copy under apps/android/play/.
  • Chromium installability and Digital Asset Links coverage in e2e/pwa-installability.spec.ts.
  • .github/workflows/android.yml: debug APK + lint on PRs, signed release AAB on android-v* tags or manual dispatch.
  • docs/play-store.md: release sequence, Play Console declarations, costs, verification and troubleshooting.
  • pnpm android:icons, pnpm android:play-assets, pnpm android:fingerprint, pnpm android:debug, pnpm android:bundle.

Verification

  • pnpm lint, pnpm format:check, pnpm typecheck, pnpm build
  • pnpm test — 541 tests
  • pnpm test:e2e — 15 tests (installability reports 0 errors)
  • apps/android/gradlew -p apps/android assembleDebug lintDebug
  • apps/android/gradlew -p apps/android bundleRelease
  • bundletool validate and jarsigner -verify on the AAB
  • aapt2 dump permissions: only INTERNET and the AndroidX signature-level receiver permission

The AAB itself is a local build artifact and is not committed.

To resume

  1. Register the Google Play Console account (US$25 one-time; the only mandatory payment).
  2. Deploy the Worker so /.well-known/assetlinks.json is live.
  3. Upload the AAB from apps/android/app/build/outputs/bundle/release/app-release.aab, copy the Play App Signing SHA-256, then run pnpm android:fingerprint "AA:BB:…" and redeploy.
  4. Complete closed testing (12 testers / 14 days for a new personal account), the store listing, Data safety, content rating and the EU DSA declaration.

The upload key and its password are intentionally outside the repository. See apps/android/README.md. Web Push remains on the roadmap and is not a Play blocker.

Wrap the PWA in an Android Trusted Web Activity so it can be published on Google Play without a second client:

- Gradle project targeting API 36 with App Links, adaptive icons, a branded splash screen, and the Android share sheet wired to the existing /share-target flow.
- Serve /.well-known/assetlinks.json from the Worker using one shared android.config.json package id and certificate fingerprints.
- Play listing artwork and copy generated from the real app.
- CI for debug APKs and signed release AABs, plus a complete Play release guide.

The web service remains the only implementation: same origin, storage, passkeys and service worker.
android-actions/setup-android@v3 still asks sdkmanager for the removed 'tools' package, so use the runner's own cmdline-tools and install only the platform and build-tools this build needs.
A machine-level ignore rule for *.jar otherwise hides future wrapper updates.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
sendself 817722d Oct 20 2026, 04:39 PM

@oli-review oli-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Adds an Android Trusted Web Activity wrapper for the PWA: a Gradle project with App Links, adaptive icons, a branded splash and share-target metadata, a Worker route serving /.well-known/assetlinks.json from android.config.json, Play listing assets/copy, CI for debug and signed release builds, and release documentation.

Risk: medium

19 file(s) not reviewed
  • apps/android/app/src/main/res/drawable-nodpi/splash.png — generated or binary
  • apps/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png — generated or binary
  • apps/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png — generated or binary
  • apps/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png — generated or binary
  • apps/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png — generated or binary
  • apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png — generated or binary
  • apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png — generated or binary
  • apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png — generated or binary
  • apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png — generated or binary
  • apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png — generated or binary
  • apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png — generated or binary
  • apps/android/play/feature-graphic.png — generated or binary
  • apps/android/play/icon-512.png — generated or binary
  • apps/android/play/screenshots/01-first-run.png — generated or binary
  • apps/android/play/screenshots/02-create-space.png — generated or binary
  • apps/android/play/screenshots/03-chat.png — generated or binary
  • apps/android/play/screenshots/04-spaces.png — generated or binary
  • apps/android/play/screenshots/05-devices.png — generated or binary
  • pnpm-lock.yaml — generated or binary

Automated review — opencode-go/deepseek-v4.1-flash · 1 comment(s)

SENDSELF_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
SENDSELF_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
SENDSELF_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: ./gradlew bundleRelease --no-daemon

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 major — Increment versionCode in CI release builds

bundleRelease runs without -PsendselfVersionCode, and apps/android/gradle.properties does not define one, so every tag or manual dispatch produces an AAB with versionCode = 1. The first Play upload succeeds, but the next release is rejected for reusing the code; pass the version explicitly (for example from the android-v* tag or github.run_number) or add the property to gradle.properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant