← All docs Games for Group · Android first release (historical)

Publishing Android for the first time

Superseded — historical record only

⚠️ SUPERSEDED — historical record only. Android has since shipped (Play internal testing) and the blockers below are resolved (the app record exists; release signing now uses a real upload key via plugins/withAndroidUploadSigning.js, not debug signing). The living Android release flow is releasing.html §5 — follow that, not this. Kept only for the first-time context.

The iOS side is automated (see memory project-ios-release-pipeline). Android has never shipped, so it needs a one-time setup. Three things block it today:

  1. No Play Console app record — needs Karim's Google account.
  2. Release builds are signed with the DEBUG keystore. android/app/build.gradle:112-115 — release { signingConfig signingConfigs.debug }, with the template's own warning still in place. Play rejects debug-signed uploads. This is the real blocker.
  3. Play wants an .aab (Android App Bundle), not the .apk we build for emulator testing. And eas.json's submit.production.android is {} — no track configured.

What only Karim can do

These need a human with the Google account — no API key can substitute (same shape as the iOS "ASC app record needs an Apple ID" limitation).

#StepNotes
1 Google Play Console account — https://play.google.com/console One-time $25 fee. Skip if the account already exists.
2 Create the app — "Create app" → name Games for Group, language, "App" (not Game — or Game if you prefer the category), Free The package name com.karimdev.gamesforgroup is set on first upload, not here. It is permanent once uploaded.
3 Accept the Play App Signing terms when prompted Recommended: let Google hold the app signing key; you keep only an upload key. If the upload key is ever lost, Google can reset it. Losing a self-managed app signing key means you can never update the app again.
4 Fill the mandatory declarations Privacy policy URL, content rating questionnaire, target audience, data safety, ads declaration. Play blocks release until these are done — they take longer than the build.

What we decide together — signing

Pick one before any real build:

Option A — EAS manages the keystore (simplest). eas build --platform android --profile production generates and stores an upload keystore in your Expo account, and eas submit can push it to Play. Costs EAS cloud quota (the same 15/month pool you're protecting for other apps).

Option B — local keystore, zero quota (matches the iOS pipeline). Generate an upload key once, keep it in the login keychain / a password manager, wire it into android/app/build.gradle via ~/.gradle/gradle.properties (never commit it), and build ./gradlew bundleRelease locally. Free, but the key is yours to back up — lose it and you cannot ship updates.

Recommendation: Option B, to stay consistent with the no-quota iOS route — but pair it with Play App Signing (step 3), which removes the catastrophic-loss risk: Google holds the real signing key, and a lost upload key can be reset.

What Claude can do once steps 1–3 are done

The order that works

Karim: Play account → create app → accept Play App Signing → declarations
  ↓
Claude: keystore + signingConfig + versionCode
  ↓
Claude: ./gradlew bundleRelease  → app-release.aab
  ↓
Karim (first time only): upload the .aab by hand in Play Console → Internal testing
  ↓  (this first upload is what locks in the package name)
Claude: wire a Play service account → future uploads are automated

The first upload must be manual — Play's API cannot create the initial release for a brand-new app, exactly like ASC's app-record limitation on iOS. After that it can be scripted.

Sanity checks before shipping

Games for Group · Publishing Android for the first time (historical) — superseded by releasing.html §5.