Skip to content

How to release an Android app to Google Play from the terminal

Publishing to Google Play traditionally means clicking through the Play Console web UI: create a release, drag in an AAB, paste release notes, pick a rollout percentage, review, confirm. It works — but it’s slow, unscriptable, and impossible to automate.

Under the hood, though, every one of those clicks maps to the Google Play Developer API’s edit-session model. gplay wraps that whole model into commands you can run from your terminal or CI. Here’s the complete flow.

  • Install gplay — one static binary, via Homebrew or install script
  • Authenticategplay setup --auto does the whole service-account dance for you
  • A built AAB (see your Gradle setup or CI pipeline)
Terminal window
gplay release --package com.example.app --track internal --bundle app.aab

That single command creates an edit session, uploads the bundle, assigns the version to the internal track, and commits the edit. If any step fails, nothing is applied — edits are atomic.

Production, with release notes and a staged rollout

Section titled “Production, with release notes and a staged rollout”
Terminal window
gplay release --package com.example.app --track production \
--bundle app.aab \
--release-notes @notes.json \
--rollout 0.1

Two things worth knowing:

  • --rollout is a fraction between 0.0 and 1.00.1 means 10% of users. (Not 10!)
  • --release-notes takes a JSON file with per-locale notes, or plain text that’s auto-assigned to en-US.

An example notes.json:

[
{ "language": "en-US", "text": "Bug fixes and performance improvements." },
{ "language": "de-DE", "text": "Fehlerbehebungen und Leistungsverbesserungen." }
]

You can even generate the notes from your git history:

Terminal window
gplay release-notes generate
Terminal window
# Where is the rollout right now?
gplay rollout status --package com.example.app --track production
# Expand 10% → 50%
gplay rollout update --package com.example.app --track production --rollout 0.5
# Crash spike? Halt immediately.
gplay rollout halt --package com.example.app --track production
# All good — ship to everyone
gplay rollout complete --package com.example.app --track production

Pair this with gplay vitals crashes to gate each expansion on real crash data.

Once a build has soaked on internal or beta, don’t upload it again — promote the exact same artifact:

Terminal window
gplay promote --package com.example.app --from beta --to production --rollout 0.1

Every write command supports --dry-run, which logs the HTTP requests it would make without executing them:

Terminal window
gplay --dry-run release --package com.example.app --track production --bundle app.aab

This is also what makes gplay safe to hand to an AI agent or a new CI pipeline — you can see exactly what would happen before it does.

# GitHub Actions
- name: Release to internal
env:
GPLAY_SERVICE_ACCOUNT: ${{ secrets.PLAY_SA_JSON_PATH }}
GPLAY_PACKAGE: com.example.app
run: gplay release --track internal --bundle app/build/outputs/bundle/release/app-release.aab

No Ruby, no Gradle plugin configuration — the same binary and the same command you ran locally.