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.
Prerequisites
Section titled “Prerequisites”- Install gplay — one static binary, via Homebrew or install script
- Authenticate —
gplay setup --autodoes the whole service-account dance for you - A built AAB (see your Gradle setup or CI pipeline)
The one-command release
Section titled “The one-command release”gplay release --package com.example.app --track internal --bundle app.aabThat 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”gplay release --package com.example.app --track production \ --bundle app.aab \ --release-notes @notes.json \ --rollout 0.1Two things worth knowing:
--rolloutis a fraction between 0.0 and 1.0 —0.1means 10% of users. (Not10!)--release-notestakes a JSON file with per-locale notes, or plain text that’s auto-assigned toen-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:
gplay release-notes generateWatch and expand the rollout
Section titled “Watch and expand the rollout”# 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 everyonegplay rollout complete --package com.example.app --track productionPair this with gplay vitals crashes to gate each expansion on real crash data.
Promote instead of re-uploading
Section titled “Promote instead of re-uploading”Once a build has soaked on internal or beta, don’t upload it again — promote the exact same artifact:
gplay promote --package com.example.app --from beta --to production --rollout 0.1Try everything safely first
Section titled “Try everything safely first”Every write command supports --dry-run, which logs the HTTP requests it would make without executing them:
gplay --dry-run release --package com.example.app --track production --bundle app.aabThis 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.
The same flow in CI
Section titled “The same flow in CI”# 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.aabNo Ruby, no Gradle plugin configuration — the same binary and the same command you ran locally.
Next steps
Section titled “Next steps”- Quickstart guide — the 5-minute tour
- Command reference — every command and flag
- Use gplay with AI agents — let your agent run the release