google-play-cli

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: MIT

README

Latest Release GitHub Stars Go Version License Status

gplay

Every team shipping an Android app eventually hits the same wall: Fastlane supply drags a Ruby runtime into your CI image, output meant for humans, and generic exit codes that make retry logic guesswork. gplay is what you'd build today if you started fresh — one static binary, no runtime, JSON output that matches the Google Play Developer API verbatim, semantic exit codes, safe production defaults.

Status: pre-1.0. v0.1.0 ships the MVP surface — auth, apps, releases, and tracks. Reviews land next. Breaking changes are still possible before v1.0 — see docs/BACKLOG.md for what's intentionally out of scope.

Why

  • Standalone Go binary. No Ruby, no Node, no Python — one file in your CI image.
  • Built for CI and agents. TTY-aware output (table by default, json in pipes), explicit flags, semantic exit codes for retry decisions.
  • API-faithful. --output json returns the raw Google Play Developer API response shape — no custom envelope to learn. The Google docs are the schema docs.
  • Safe by default on production. Uploading or promoting to the production track creates a draft release unless you explicitly --complete or --staged <fraction>. See ADR-0002.

Install

All install methods are live as of v0.1.0: go install, Homebrew, the install script, and pre-built binaries for Linux, macOS, and Windows on the releases page.

# go install
go install github.com/PollyGlot/google-play-cli/cmd/gplay@latest

# Homebrew
brew install PollyGlot/tap/gplay

# Install script
curl -fsSL https://raw.githubusercontent.com/PollyGlot/google-play-cli/main/install.sh | sh

Quick start

# Point gplay at a Google Cloud service account JSON.
gplay auth login --service-account ./service_account.json

# List configured accounts and see which one is active.
gplay auth list
gplay auth status

# Verify the SA actually has access to your app.
gplay auth doctor --package com.example.myapp

# Bootstrap a project-local config (cascading: project → user → defaults).
gplay init

Full command reference: gplay --help (or gplay <subcommand> --help).

Planned for v0.1 stable

The Fastlane-replacement surface lands incrementally on the road to v0.1.0. These commands are not yet implemented in the current pre-release:

# Upload an AAB to the internal track.
gplay releases upload app.aab \
  --package com.example.myapp \
  --track internal \
  --release-notes-dir ./whatsnew

# Promote the latest internal build to beta.
gplay releases promote --package com.example.myapp --from internal --to beta

# Read the most recent reviews (API exposes the last 7 days only).
gplay reviews list --package com.example.myapp --stars 1-2

See docs/BACKLOG.md for the full roadmap and what is intentionally out of scope.

How it's set up

The repo is documentation-first by design. Before writing significant code, the decisions are pinned in place so contributors and agents converge:

  • CLAUDE.md — project context and roadmap.
  • AGENTS.md — instructions for AI agents working in this repo. Reads CLAUDE.md, CONTEXT.md, DESIGN.md before generating code.
  • CONTEXT.md — glossary of canonical terms (Edit, Account, Project, ...). Use them verbatim.
  • docs/DESIGN.md — CLI conventions across commands (auth precedence, exit codes, output format, verbosity, edit lifecycle).
  • docs/BACKLOG.md — explicitly out-of-scope features.
  • docs/CI_CD.md — how to wire gplay into a CI pipeline (GitHub Actions example).
  • docs/adr/ — Architecture Decision Records.

Skills repo (planned)

Agent skills that drive gplay from natural-language prompts will live in a companion repo: PollyGlot/google-play-cli-skills. Each skill is a folder with a SKILL.md file that documents the intent, the gplay commands it runs, and the safety rails it enforces.

Contributing

See CONTRIBUTING.md. TL;DR: open an issue first for anything bigger than a typo, branch from main, open a PR.

License

MIT — © 2026 Pavlo Trinko and contributors.

Not affiliated with Google

gplay is an independent open-source project. It uses the public Google Play Developer API and is not endorsed by, affiliated with, or sponsored by Google LLC. "Google Play" is a trademark of Google LLC.

Directories

Path Synopsis
cmd
gplay command
commands
apps/addcmd
Package addcmd implements `gplay apps add`: register an Android package under the active Account, with a cheap edits.insert+delete access probe (skippable via --no-verify) so typos and missing per-app permission grants are caught at registration time rather than weeks later in CI.
Package addcmd implements `gplay apps add`: register an Android package under the active Account, with a cheap edits.insert+delete access probe (skippable via --no-verify) so typos and missing per-app permission grants are caught at registration time rather than weeks later in CI.
apps/infocmd
Package infocmd implements `gplay apps info`: a read-only sanity check on what the active service account sees for a given app.
Package infocmd implements `gplay apps info`: a read-only sanity check on what the active service account sees for a given app.
apps/initcmd
Package initcmd implements `gplay init`: pin a package name to the current repo by writing .gplay/config.json (committed) and an adjacent .gplay/.gitignore.
Package initcmd implements `gplay init`: pin a package name to the current repo by writing .gplay/config.json (committed) and an adjacent .gplay/.gitignore.
apps/listcmd
Package listcmd implements `gplay apps list`: print every Android package registered under the active Account, marking the one pinned by the current repo's .gplay/config.json.
Package listcmd implements `gplay apps list`: print every Android package registered under the active Account, marking the one pinned by the current repo's .gplay/config.json.
apps/removecmd
Package removecmd implements `gplay apps remove`: drop an Android package from the active Account's local registry.
Package removecmd implements `gplay apps remove`: drop an Android package from the active Account's local registry.
auth/doctor
Package doctor implements `gplay auth doctor`: ordered diagnostic checks (per docs/DESIGN.md §1) that catch credential misconfiguration before any other command tries to talk to the API.
Package doctor implements `gplay auth doctor`: ordered diagnostic checks (per docs/DESIGN.md §1) that catch credential misconfiguration before any other command tries to talk to the API.
auth/list
Package list implements `gplay auth list`: print every registered Account with the active one marked.
Package list implements `gplay auth list`: print every registered Account with the active one marked.
auth/login
Package login implements `gplay auth login`: register a service-account JSON as a named Account in the keystore and mark it active in the config.
Package login implements `gplay auth login`: register a service-account JSON as a named Account in the keystore and mark it active in the config.
auth/logout
Package logout implements `gplay auth logout <name>`: remove a registered Account from both the config and the keystore.
Package logout implements `gplay auth logout <name>`: remove a registered Account from both the config and the keystore.
auth/status
Package status implements `gplay auth status`: print which Account is active, the underlying client_email, the keystore backend in use, and (when applicable) the on-disk credential path.
Package status implements `gplay auth status`: print which Account is active, the underlying client_email, the keystore backend in use, and (when applicable) the on-disk credential path.
releases/list
Package list implements `gplay releases list`: a read-only listing of every release currently attached to a track (draft, inProgress, halted, completed).
Package list implements `gplay releases list`: a read-only listing of every release currently attached to a track (draft, inProgress, halted, completed).
releases/promote
Package promote implements `gplay releases promote`: the CLI glue that parses --from/--to plus the status overrides (per ADR-0002), resolves --package, and hands a PromoteOpts payload to internal/releases/orchestrator.
Package promote implements `gplay releases promote`: the CLI glue that parses --from/--to plus the status overrides (per ADR-0002), resolves --package, and hands a PromoteOpts payload to internal/releases/orchestrator.
releases/rollout
Package rollout implements the staged-rollout state machine as four sibling commands — `gplay releases rollout / halt / resume / complete`.
Package rollout implements the staged-rollout state machine as four sibling commands — `gplay releases rollout / halt / resume / complete`.
releases/upload
Package upload implements `gplay releases upload`: the CLI glue that resolves --package, parses the status flags (per ADR-0002), and hands an Opts payload to internal/releases/orchestrator.
Package upload implements `gplay releases upload`: the CLI glue that resolves --package, parses the status flags (per ADR-0002), and hands an Opts payload to internal/releases/orchestrator.
tracks/list
Package list implements `gplay tracks list`: a read-only, cross-track listing of every track configured for a package — the four standard tracks (internal, alpha, beta, production) plus any custom closed tracks the service account can see — with a one-line summary of the top release on each.
Package list implements `gplay tracks list`: a read-only, cross-track listing of every track configured for a package — the four standard tracks (internal, alpha, beta, production) plus any custom closed tracks the service account can see — with a one-line summary of the top release on each.
tracks/status
Package status implements `gplay tracks status`: a read-only, deep view of a single track tuned for the "is something wrong right now?" question.
Package status implements `gplay tracks status`: a read-only, deep view of a single track tuned for the "is something wrong right now?" question.
internal
apps/registry
Package registry is the pure-data registry of Android package names known to each gplay Account.
Package registry is the pure-data registry of Android package names known to each gplay Account.
auth/doctor
Package doctor runs ordered diagnostic checks against a resolved service-account credential and reports a structured result per check.
Package doctor runs ordered diagnostic checks against a resolved service-account credential and reports a structured result per check.
auth/keystore
Package keystore stores service-account JSON credentials by name.
Package keystore stores service-account JSON credentials by name.
auth/resolver
Package resolver picks the credential the next API call will use.
Package resolver picks the credential the next API call will use.
auth/serviceaccount
Package serviceaccount loads and validates Google Cloud service-account JSON files.
Package serviceaccount loads and validates Google Cloud service-account JSON files.
auth/token
Package token mints OAuth2 access tokens for the Google Play Developer API from a parsed service account.
Package token mints OAuth2 access tokens for the Google Play Developer API from a parsed service account.
config
Package config owns gplay's cascading configuration model.
Package config owns gplay's cascading configuration model.
exit
Package exit maps typed errors to the semantic exit codes documented in docs/DESIGN.md §9.
Package exit maps typed errors to the semantic exit codes documented in docs/DESIGN.md §9.
kernel
Package kernel owns the per-invocation boot sequence shared by every gplay command: build the Boot once in cmd/gplay/main.go, the cobra layer captures the request-shaped Inputs, and kernel.Run resolves Account / Project / Format once before handing a populated RunContext to the command's business function.
Package kernel owns the per-invocation boot sequence shared by every gplay command: build the Boot once in cmd/gplay/main.go, the cobra layer captures the request-shaped Inputs, and kernel.Run resolves Account / Project / Format once before handing a populated RunContext to the command's business function.
output
Package output owns Format selection and rendering dispatch for gplay commands.
Package output owns Format selection and rendering dispatch for gplay commands.
output/outputtest
Package outputtest is the test-only seam for internal/output.
Package outputtest is the test-only seam for internal/output.
play/api
Package api owns the shared low-level concerns of every internal/play/* module: the canonical androidpublisher base URLs, the per-response body-size caps, and the HTTP status → gplay exit-code mapping plus the API error-envelope parser.
Package api owns the shared low-level concerns of every internal/play/* module: the canonical androidpublisher base URLs, the per-response body-size caps, and the HTTP status → gplay exit-code mapping plus the API error-envelope parser.
play/bundles
Package bundles uploads an AAB to a specific Edit via the edits.bundles.upload endpoint.
Package bundles uploads an AAB to a specific Edit via the edits.bundles.upload endpoint.
play/details
Package details reads app-level metadata.
Package details reads app-level metadata.
play/edits
Package edits owns the Google Play Edit transactional lifecycle.
Package edits owns the Google Play Edit transactional lifecycle.
play/tracks
Package tracks reads and updates the release configuration of Google Play tracks within an open Edit.
Package tracks reads and updates the release configuration of Google Play tracks within an open Edit.
releases/notes
Package notes loads release notes from CLI input — either a single text string (assigned to the app's default language) or a directory of per-locale files (`<locale>.txt`) with an optional `default.txt` fallback for the default language.
Package notes loads release notes from CLI input — either a single text string (assigned to the app's default language) or a directory of per-locale files (`<locale>.txt`) with an optional `default.txt` fallback for the default language.
releases/orchestrator
Package orchestrator owns the choreography of `gplay releases upload`: open an Edit, upload the AAB, attach the resulting versionCode to the target track, and commit the Edit.
Package orchestrator owns the choreography of `gplay releases upload`: open an Edit, upload the AAB, attach the resulting versionCode to the target track, and commit the Edit.
transport
Package transport exposes the HTTP middleware gplay layers on top of the oauth2 client.
Package transport exposes the HTTP middleware gplay layers on top of the oauth2 client.
walkup
Package walkup walks up from a starting directory looking for a file, mirroring git's `.git/` discovery.
Package walkup walks up from a starting directory looking for a file, mirroring git's `.git/` discovery.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL