Submitting to Google Play

Shipping Android: the Play Console record, testing tracks, the data safety form, and a staged rollout you can halt.

Syntaxeas submit --platform android --profile production

Android releases go through the Play Console. Create the app there, then upload an .aab. Play expects the first upload of a brand new app to be done by hand in the Console, because that is where you create the initial release; automated submission works from then on.

Automated submission

eas submit --platform android needs a Google service account key, uploaded once with eas credentials --platform android or referenced as serviceAccountKeyPath in the submit profile. The profile's track is one of internal, alpha, beta or production.

Tracks

Internal testing reaches a listed set of testers within minutes and is where you should live day to day. Closed and open testing are review-gated and slower. Production is reviewed and can take days.

Data safety

Play requires a declaration of what the app collects, what it shares, and whether data is encrypted in transit. It is checked against the app's behaviour, and a library you added counts as your collection.

Staged rollout

Set releaseStatus: "inProgress" with rollout as a fraction, for example 0.1, so a tenth of devices get the release. If crash reports rise you halt it in the Console. Play also enforces a minimum target API level each year; the value Expo SDK 57 ships meets the current one, so do not lower it.

Example

Example · tsx
// app.config.ts - the Android fields Play checks
import type { ConfigContext, ExpoConfig } from "expo/config";

export default ({ config }: ConfigContext): ExpoConfig => ({
  ...config,
  name: "Trailhead",
  slug: "trailhead",
  version: "1.2.0", // becomes versionName; the listing shows this
  android: {
    // The package name is permanent once a listing exists.
    package: "com.example.trailhead",
    // No versionCode here: appVersionSource is "remote", so EAS owns it.
    adaptiveIcon: {
      foregroundImage: "./assets/adaptive-icon.png",
      backgroundColor: "#0B3D2E",
    },
    permissions: ["android.permission.CAMERA"],
    // A dependency can merge in a permission you never asked for, and then you
    // have to declare it on the data safety form. Block what you do not use.
    blockedPermissions: [
      "android.permission.ACCESS_COARSE_LOCATION",
      "android.permission.RECORD_AUDIO",
    ],
  },
});

When to use it

  • Get a build to internal testers in minutes rather than waiting on review.
  • Roll a release out to ten percent of devices and halt it if crash-free sessions drop.
  • Answer the data safety form consistently with what the app sends.
  • Stop a dependency from adding a permission that would widen your privacy declaration.

More examples

Submit profiles for a test track and a staged production release

The preview profile pushes straight to internal testing and marks it live, because internal testers are not worth a manual step. The production profile starts at ten percent and stays inProgress until you raise it in the Console, which is the cheapest insurance against a crash that only happens on real devices.

Example · json
{
  "submit": {
    "preview": {
      "android": {
        "serviceAccountKeyPath": "./credentials/play-service-account.json",
        "track": "internal",
        "releaseStatus": "completed"
      }
    },
    "production": {
      "android": {
        "serviceAccountKeyPath": "./credentials/play-service-account.json",
        "track": "production",
        "releaseStatus": "inProgress",
        "rollout": 0.1,
        "changesNotSentForReview": false
      }
    }
  }
}

First release, then automated ones

Teams get stuck here more often than anywhere else in the release path: eas submit cannot create the first release of a listing. Do that one upload manually, confirm the app shows in internal testing, and every release afterwards is the single submit command.

Example · bash
# Build the bundle Play accepts (app-bundle is the default)
eas build --platform android --profile production

# First time only: download the .aab and create the release by hand in the
# Play Console, so the listing exists
eas build:list --platform android --limit 1

# After that, submission is one command
eas submit --platform android --profile production --latest

# Upload the service account key once; it is then stored with your credentials
eas credentials --platform android

Discussion

  • Be the first to comment on this lesson.