Phase 4

Publish on Google Play

Signing, AAB, Play Console, testing tracks, rollout

1 day of work + 14 days of testing0/10 done

The full Android release path. Work through it in order — the keystore step in particular is irreversible, and getting it wrong means you can never update your app again under the same listing. Once your keys are saved in the build console, the 'Store page' tab does the last part for you: fill in the title, descriptions and pictures, then press 'Send app and store page to Google Play' and the machine builds, signs and sends everything in one go. Google still reviews it, and the account, fees, data safety form and tester rules below remain yours to complete.

01

Set version name and version code

FieldMeaningRule
versionNameWhat users see: 1.0.0Any string; semantic versioning is conventional
versionCodeInternal integer: 1Must increase with EVERY upload, forever. Never reuse.
android/app/build.gradle
android {
    namespace "com.example.myapp"
    compileSdk 35

    defaultConfig {
        applicationId "com.example.myapp"
        minSdk 23
        targetSdk 35
        versionCode 1
        versionName "1.0.0"
    }
}
02

Create your upload keystore

Generate your upload keystore — back it up immediately

Run this from your project root. Store the file, the alias my-app-upload and both passwords in a password manager before you do anything else.

Create the keystore
keytool -genkey -v \
  -keystore my-app-upload.keystore \
  -alias my-app-upload \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000
Keystore file
my-app-upload.keystore
Key alias
my-app-upload
Validity
10000 days

Answer the prompts with real details (name, organisation, city, two-letter country code). Validity of 10000 days is standard — a keystore that expires mid-life is unrecoverable.

03

Wire signing into Gradle without committing secrets

android/keystore.properties (gitignored)
storeFile=../../my-app-upload.keystore
storePassword=YOUR_STORE_PASSWORD
keyAlias=my-app-upload
keyPassword=YOUR_KEY_PASSWORD
android/app/build.gradle
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    signingConfigs {
        release {
            if (keystorePropertiesFile.exists()) {
                storeFile file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
            }
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                          'proguard-rules.pro'
        }
    }
}
04

Build a signed Android App Bundle

Play requires an AAB (.aab), not an APK. Google generates per-device APKs from it. You still build an APK when you want to sideload for testing.

Command line
npm run build
npx cap sync android
cd android
./gradlew clean
./gradlew bundleRelease

# Output:
# android/app/build/outputs/bundle/release/app-release.aab
Or from Android Studio
Build → Generate Signed App Bundle / APK → Android App Bundle
→ choose your keystore → release → Finish
Test the release build on a real device first
./gradlew assembleRelease
adb install -r app/build/outputs/apk/release/app-release.apk
05

Create the app in Play Console

  1. Play Console → Create app.
  2. App name (30 characters max — this is what shows on the store), default language, App or Game, Free or Paid.
  3. Accept the developer programme and US export declarations.
  4. Free vs Paid is permanent. You can make a paid app free, never the reverse.
06

Complete the app content declarations

DeclarationWhat it asksWatch out for
Privacy policyPublic URLMust be reachable and actually about this app
App accessDo you need login to review?Provide working demo credentials or review fails
AdsDoes the app show ads?Declaring 'no' while shipping an ad SDK is a suspension
Content ratingIARC questionnaireAnswer honestly; a wrong rating gets the app pulled
Target audienceAge rangesAnything under 13 triggers Families policy requirements
Data safetyEverything you collect and shareMust match your actual SDKs and permissions
Government appsAre you a government entity?Usually no
Financial featuresLoans, payments, crypto?Extra documentation if yes
Health appsHealth-related features?Extra declarations if yes
07

Prepare the store listing

Store listing helper

Write once, copy into both consoles. Counters use the stricter of the two store limits.

App title (Play & App Store)
0/30
Short description (Play)
0/80

Shown above the fold. Lead with the benefit, not the technology.

Subtitle (App Store)
0/30
Full description (Play limit 4000)
0/4000

First two lines matter most. Use short paragraphs and a feature list. No competitor names, no fake claims.

Promotional text (App Store)
0/170

Editable without shipping a new build — good for announcements.

Keywords (App Store)
0/100

Comma separated, no spaces after commas. Do not repeat words already in your title.

StoreAssetSize (px)FormatNotes
PlayApp icon512 × 512PNG, 32-bitNo alpha shown; uploaded in Console
PlayFeature graphic1024 × 500PNG/JPGRequired. Avoid small text
PlayPhone screenshots1080 × 1920 (min 320px side)PNG/JPG2 minimum, 8 maximum
Play7" tablet1200 × 1920PNG/JPGNeeded for tablet featuring
Play10" tablet1600 × 2560PNG/JPGNeeded for tablet featuring
PlayPromo videoYouTube URLOptional
App StoreApp icon1024 × 1024PNG, no alphaRejected if transparent
App StoreiPhone 6.9"1320 × 2868PNG/JPGRequired
App StoreiPhone 6.5"1242 × 2688PNG/JPGRequired
App StoreiPad 13"2064 × 2752PNG/JPGRequired if iPad supported
BothSplash source2732 × 2732PNGArtwork inside centre 1200px
  • Screenshots must show your actual app — no marketing mock-ups that hide the UI, no device frames that make text unreadable.
  • You need at least 2 phone screenshots; supply 4–8 for a credible listing.
  • To be featured on tablets and Chromebooks, add 7-inch and 10-inch tablet screenshots.
  • The feature graphic is used in the store header and in any promotion — no small text, it gets cropped.
08

Upload to internal testing first

Never upload straight to production. Internal testing is available immediately, accepts up to 100 testers by email, and skips the review queue — it is your smoke test for signing, versioning and the actual store install path.

  1. Testing → Internal testing → Create new release.
  2. Upload app-release.aab. Confirm Play App Signing when prompted.
  3. Write release notes (what changed — users read these).
  4. Create an email list of testers, save, and copy the opt-in link.
  5. Open the link on a real phone with a tester account, accept, install from Play, and use the app.
09

Run the closed test (and the 12-tester requirement)

If your Play account is a personal account created after November 2023, this step is mandatory and time-gated: at least 12 testers opted in continuously for 14 days before you can apply for production access.

  1. Testing → Closed testing → create a track and a tester list of 12+ real Google accounts.
  2. Send everyone the opt-in link and confirm each one installs the app — an opt-in without an install may not count.
  3. Tell testers not to leave the programme; the 14 days must be continuous.
  4. Ship at least one update during the period and collect written feedback.
  5. After 14 days, Play Console shows an Apply for production button. Answer its questions about what you learned from testing.
10

Roll out to production

  1. Production → Create new release → upload the AAB (with a higher versionCode than any previous upload).
  2. Choose countries and regions.
  3. Set a staged rollout — start at 10–20%. You can halt a staged rollout; you cannot un-publish a 100% release from users who already have it.
  4. Review the summary, send for review.
  5. First review usually takes hours to a few days; later updates are typically faster.