Skip to content

leszko11/google-play-console-cli

Repository files navigation

gpc

Google Play Console from your terminal.
Ship Android apps, manage releases, sync listings, handle monetization — no browser required.

Latest Release CI Status Go 1.24+ API Coverage 136/136 MIT License

QuickstartInstallWhat Can It DoCommon Workflowsgpc vs Raw APIsDocs


Why gpc?

Working with Google Play Console usually means clicking through a slow web UI or wrestling with raw REST APIs, JSON payloads, and transactional edit sessions. gpc wraps all of that into a single binary with human-friendly commands, sane defaults, and first-class CI/CD support.

  • One binary, zero runtime deps — download and go
  • 136/136 Android Publisher discovery endpoints covered — plus Play reporting, billing, and games workflows
  • CI-native — JSON output by default in non-TTY, explicit flags for everything, no interactive prompts
  • Multi-profile auth — switch between service accounts in one command
  • Dry-run everything — preview any destructive operation before committing

Inspired by Rudrank Riyam's App-Store-Connect-CLI.


Quickstart

# Install
brew install leszko11/tap/gpc

# Authenticate
gpc auth init --service-account /path/to/service-account.json

# Generate a release workspace from the current Play state
gpc release init \
  --package-name com.example.app \
  --dir ./play

# Check the release inputs before committing
gpc release verify \
  --package-name com.example.app \
  --track internal \
  --aab ./app.aab \
  --notes-file ./play/changelog/internal/en-US.txt

# Run the full non-production release flow
gpc release full \
  --manifest ./play/release.yaml \
  --confirm

For public apps that are not initialized in Play yet, gpc release init generates the local workspace and a play/MANUAL_FIRST_UPLOAD.md bridge for the first Console upload.


Command Discovery

Use --help at every level:

gpc --help
gpc audit --help
gpc auth --help
gpc bootstrap --help
gpc appinit --help
gpc init --help
gpc apps --help
gpc app-recoveries --help
gpc changelog --help
gpc custom-apps --help
gpc edits --help
gpc tracks --help
gpc apks --help
gpc bundles --help
gpc deobfuscation --help
gpc deploy --help
gpc diff --help
gpc drift --help
gpc doctor --help
gpc e2e --help
gpc release --help
gpc rollback --help
gpc screenshots --help
gpc setup --help
gpc status --help
gpc reviews --help
gpc reports --help
gpc orders --help
gpc external-transactions --help
gpc device-tier-configs --help
gpc system-apks --help
gpc generated-apks --help
gpc games --help
gpc subscriptions --help
gpc monetization --help
gpc migrate --help
gpc notify --help
gpc products --help
gpc publish --help
gpc iap --help
gpc listing --help
gpc purchases --help
gpc users --help
gpc validate --help
gpc workflow --help
gpc grants --help
gpc health --help
gpc internal-sharing --help
gpc integrity --help
gpc watch --help
gpc update --help
gpc completion --help

Install

Homebrew

brew install leszko11/tap/gpc

Go install

go install github.com/leszko11/google-play-console-cli@latest

GitHub Releases

Download the archive for your platform from Releases, then verify with the published checksums.

VERSION=v0.5.0
curl -LO "https://github.com/leszko11/google-play-console-cli/releases/download/${VERSION}/gpc_${VERSION}_darwin_arm64.tar.gz"
curl -LO "https://github.com/leszko11/google-play-console-cli/releases/download/${VERSION}/gpc_${VERSION}_checksums.txt"
shasum -a 256 --check gpc_${VERSION}_checksums.txt
tar -xzf "gpc_${VERSION}_darwin_arm64.tar.gz"
mv gpc /usr/local/bin/gpc

Docker

docker run --rm -v ~/.gpc:/home/gpc/.gpc ghcr.io/leszko11/gpc apps list

Shell Completion

# Bash
gpc completion bash > ~/.local/share/bash-completion/completions/gpc

# Zsh
mkdir -p ~/.zfunc && gpc completion zsh > ~/.zfunc/_gpc

# Fish
gpc completion fish > ~/.config/fish/completions/gpc.fish
Platform Architecture Format
macOS arm64, amd64 tar.gz
Linux arm64, amd64 tar.gz
Windows amd64 zip

Command Discovery

gpc --help
gpc audit --help
gpc auth --help
gpc bootstrap --help
gpc appinit --help
gpc init --help
gpc apps --help
gpc app-recoveries --help
gpc changelog --help
gpc custom-apps --help
gpc edits --help
gpc tracks --help
gpc apks --help
gpc bundles --help
gpc deobfuscation --help
gpc deploy --help
gpc diff --help
gpc drift --help
gpc doctor --help
gpc e2e --help
gpc release --help
gpc rollback --help
gpc screenshots --help
gpc setup --help
gpc status --help
gpc reviews --help
gpc reports --help
gpc orders --help
gpc external-transactions --help
gpc device-tier-configs --help
gpc system-apks --help
gpc generated-apks --help
gpc games --help
gpc subscriptions --help
gpc monetization --help
gpc migrate --help
gpc notify --help
gpc products --help
gpc publish --help
gpc iap --help
gpc listing --help
gpc purchases --help
gpc users --help
gpc validate --help
gpc workflow --help
gpc grants --help
gpc health --help
gpc internal-sharing --help
gpc integrity --help
gpc watch --help
gpc update --help
gpc completion --help

What Can It Do

gpc covers the full surface of Google Play Console operations across 6 Google API families.

Releases & Publishing

Command Description
deploy End-to-end: upload bundle → update track → validate → commit
release alpha One-command staging release with build verification
release full Vitals-gated staged rollout with --auto-halt-on-regression
release rehearse Read-only release readiness report before release full
release promote Promote releases between tracks
release rollback plan Read-only incident planner before halting a rollout
rollback Revert a track to previous release
publish alpha/production Composite shortcut with built-in bundle processing wait
validate Pre-submission gate for listings, assets, and edit validation

Store Content

Command Description
listing sync Sync local listing directory to Play Console
screenshots sync Batch sync screenshot directories per locale
changelog sync Push release notes from local files
edits listings CRUD for localized store listings
edits images Upload, list, delete store images
diff listing Preview listing drift before syncing
drift report Roll up live-vs-local drift across listings, screenshots, changelogs, products, subscriptions, and optional track intent

Monetization

Command Description
subscriptions Full lifecycle: create, update, archive, sync with base plans and offers
products One-time products with purchase options and offer management
monetization setup Manifest-driven provisioning
monetization sync Directory-driven sync from YAML manifests
iap Legacy in-app product management
purchases Validate, acknowledge, consume, defer, revoke, refund
orders Query and refund Play Billing orders

Analytics & Reporting

Command Description
reports vitals Crash rate, ANR rate, and custom metric queries
reports anomalies Anomaly detection alerts
reports errors Error issue and report search
reports financial Cloud Storage financial report download and normalization
reports summary Operator dashboard: visibility, anomalies, vitals freshness
reviews triage Group reviews into pending-reply and replied buckets

Account & Access

Command Description
users Manage developer account users (create, update, delete)
grants Per-app permission grants
auth profiles Multi-identity service account management

Everything Else

Command Description
bootstrap / appinit Export and re-apply app details, listings, screenshots, products, and subscriptions
init Local-first scaffold for .gpc.yaml, play/, and workflow files
setup --auto One-shot GCP + auth + workspace provisioning
workflow run Declarative multi-step automation from .gpc/workflow.yml
notify Webhook, Slack, and Discord notification delivery
doctor Diagnostic pass for auth, access, and fixture health
games Play Games Services: achievements, events, leaderboards
migrate fastlane diff Preview Fastlane listing and changelog drift against live Play
migrate fastlane import Import Fastlane metadata into gpc workspace layout
integrity decode Decode Android Integrity API tokens
update Self-update to latest release
Full command reference (180+ subcommands)

Use --help at every level:

gpc --help
gpc auth --help
gpc edits --help
gpc subscriptions offers --help

See docs/COMMANDS.md for the complete auto-generated reference.


Common Workflows

Scaffold a repo before connecting Play

gpc init \
  --package-name com.example.app \
  --dir ./play

gpc init is local-only. It creates the standard play/ workspace, .gpc.yaml, play/release.yaml, play/appinit.yaml, and .gpc/workflow.yml without requiring auth or calling Play APIs.

Use gpc init when you want to adopt the repo layout first. Use gpc bootstrap or gpc release init only when you want to read live Play state.

CI/CD: Deploy on merge

# Non-TTY defaults to JSON output. Explicit flags for automation safety.
gpc deploy \
  --package-name "$PACKAGE_NAME" \
  --service-account "$SA_PATH" \
  --aab ./app/build/outputs/bundle/release/app-release.aab \
  --track internal \
  --status completed \
  --release-notes-text "$COMMIT_MSG" \
  --output json \
  --confirm

Connect an existing Play app

gpc release init \
  --package-name com.example.app \
  --dir ./play

gpc doctor --package-name com.example.app

release init exports the current Play state into ./play, writes .gpc.yaml, and generates .gpc/workflow.yml.

Audit workspace drift before sync or release

gpc drift report \
  --package-name com.example.app \
  --dir ./play \
  --track internal \
  --output table

Use drift report for the operator-level rollup. Use diff listing, diff track, or the surface-specific sync commands when you need the exact low-level change set for one area.

It also writes ./play/bootstrap-state.json, which records the last known package readiness and whether an internal draft bootstrap release already exists.

First public app upload bridge

gpc release init \
  --package-name com.example.app \
  --dir ./play

If the package is not initialized yet, gpc does not pretend it can complete that step. It writes ./play/MANUAL_FIRST_UPLOAD.md with:

  • what gpc can already prepare locally
  • the exact Play Console steps that must still be done on the web
  • the CLI limitations for public apps
  • the rerun command after that first upload

Staged rollout with vitals gating

gpc release full \
  --package-name com.example.app \
  --manifest ./release.yaml \
  --vitals-gate 'crashRate<2.0,anrRate<0.5' \
  --vitals-wait 24h \
  --auto-halt-on-regression \
  --confirm

Rehearse a release without writing anything

gpc release rehearse \
  --package-name com.example.app \
  --manifest ./play/release.yaml \
  --probe-track \
  --vitals-gate 'crashRate<2.0,anrRate<0.5'

release rehearse loads the release manifest, runs readiness checks, previews the live track against the planned release metadata, and returns one report with blockers, warnings, planned steps, and the next command.

Plan a rollback before halting a rollout

gpc release rollback plan \
  --package-name com.example.app \
  --track production \
  --vitals-gate 'crashRate<2.0,anrRate<0.5'

release rollback plan is read-only. It inspects the live track through a transient edit, summarizes the active release and previous completed release, and tells you whether gpc rollback --confirm is the supported next step.

Repeat internal or alpha releases

gpc release init --package-name com.example.app --dir ./play
gpc release full --manifest ./play/release.yaml --dry-run
gpc release full --manifest ./play/release.yaml --confirm

release full applies app details, listing metadata, screenshots, products, subscriptions, uploads the artifact, and runs post-release checks. If Play still treats the package as a draft app, release full seeds the bootstrap release first and then continues.

If ./play/bootstrap-state.json or the internal track already shows a draft bootstrap release, reruns reuse that state and recheck readiness before attempting another upload.

Web vs CLI

Surface Tasks
Web only Create or initialize a public Play app entry, upload the first public-app artifact, wait for Play processing to clear draft bootstrap
CLI only Export Play state, sync local listing/screenshots/products/subscriptions, verify release inputs, run non-production release orchestration
Either Review release metadata, inspect track state, rerun readiness checks after Play finishes processing

Sync store listings from local files

# Preview first
gpc diff listing --package-name com.example.app --dir ./store/listing --delete-missing

# Apply
gpc listing sync --package-name com.example.app --dir ./store/listing --confirm

Multi-locale release notes

cat <<'EOF' > release-notes.txt
<en-US>
Bug fixes and stability improvements.
</en-US>
<pl-PL>
Poprawki bledow i ulepszenia stabilnosci.
</pl-PL>
<de-DE>
Fehlerbehebungen und Stabilitaetsverbesserungen.
</de-DE>
EOF

gpc deploy --package-name com.example.app --aab ./app.aab \
  --track production --status inProgress \
  --release-notes-file release-notes.txt --confirm

Preview Fastlane metadata before migrating

gpc migrate fastlane diff \
  --package-name com.example.app \
  --from-dir ./fastlane \
  --track production \
  --version-code 123 \
  --output table

Manage subscriptions from YAML

# Dry-run to preview changes
gpc monetization sync \
  --package-name com.example.app \
  --manifest ./monetization.yaml \
  --dry-run

# Apply with activation
gpc monetization sync \
  --package-name com.example.app \
  --manifest ./monetization.yaml \
  --confirm --activate

Switch between accounts

gpc auth init --profile work --service-account /path/to/work.json
gpc auth init --profile personal --service-account /path/to/personal.json

gpc auth switch --profile work
gpc --profile personal apps list   # one-off override without switching

Declarative workflow automation

# .gpc/workflow.yml
version: 1
vars:
  packageName: com.example.app
  slackWebhook: https://hooks.slack.com/services/...
steps:
  - id: deploy-internal
    run: >
      deploy --package-name ${packageName} --aab ./app.aab
      --track internal --status completed --confirm
  - id: notify-team
    needs: [deploy-internal]
    run: >
      notify slack --url ${slackWebhook}
      --event release.completed
      --message "Internal build deployed"
gpc workflow run --var packageName=com.example.app --confirm

gpc vs Raw Google Play APIs

Without gpc, every Play Console operation requires managing OAuth tokens, constructing JSON payloads, handling edit transactions, and chaining multiple API calls. The left-hand snippets below are simplified examples of that manual HTTP plumbing for comparison only. When using gpc, you run the command on the right.

Deploy a bundle

Manual API flow (5+ requests)gpc (1 command)
# 1. Create edit
curl -X POST .../edits \
  -H "Authorization: Bearer $TOKEN"

# 2. Upload bundle
curl -X POST .../edits/$EDIT/bundles \
  -H "Content-Type: application/octet-stream" \
  --data-binary @app.aab

# 3. Update track
curl -X PUT .../edits/$EDIT/tracks/internal \
  -d '{"releases":[{"versionCodes":["42"],
       "status":"completed"}]}'

# 4. Validate edit
curl -X POST .../edits/$EDIT:validate

# 5. Commit edit
curl -X POST .../edits/$EDIT:commit
gpc deploy \
  --package-name com.example.app \
  --aab ./app.aab \
  --track internal \
  --status completed \
  --confirm

Manage subscriptions

Manual API flowgpc
# Resolve regions version first
curl .../monetization/convertRegionPrices

# Create subscription
curl -X POST \
  .../monetization/subscriptions \
  -d '{ 130 lines of JSON... }'

# Activate base plan
curl -X POST \
  .../basePlans/$BP:activate

# Create offer with more JSON...
curl -X POST \
  .../basePlans/$BP/offers \
  -d '{ 80 lines of JSON... }'
# Regions version auto-resolved
gpc monetization sync \
  --package-name com.example.app \
  --manifest ./monetization.yaml \
  --confirm --activate

Android Publisher coverage at a glance

Metric Count
Total discovery endpoints 136
Implemented endpoints 136
Missing endpoints 0
Detected service method IDs 136
Unmatched service method IDs 0

Full endpoint mapping: docs/openapi/COVERAGE.md


Configuration

Global Flags

--package-name       App package name
--service-account    Path to service account JSON
--profile            Auth profile override
--output             Output format: json, table, markdown, yaml
--fields             JSON field projection (comma-separated)
--timeout            API request timeout (default: 30s)
--pretty             Pretty-print JSON output
--strict-auth        Fail on mixed credential sources
--debug              Enable debug logging

Environment Variables

GPC_PACKAGE_NAME=com.example.app      # Default package
GPC_SERVICE_ACCOUNT_PATH=/path/to.json # Default credentials
GPC_DEFAULT_OUTPUT=json                # Default output format
GPC_PROFILE=work                       # Default profile
GPC_STRICT_AUTH=1                      # Strict source policy
GPC_BYPASS_KEYCHAIN=1                  # Disable keychain
GPC_CONFIG_PATH=~/.gpc/config.json     # Config location

Output Behavior

Context Default Format
Interactive TTY table
Non-interactive / pipe json
--output flag Explicit override
GPC_DEFAULT_OUTPUT Explicit override

Auth

gpc uses Google service account credentials with a multi-profile system.

# Initialize (default: managed file-based storage)
gpc auth init --service-account /path/to/sa.json

# Or use OS keychain
gpc auth init --service-account /path/to/sa.json --storage keychain

# Check status
gpc auth status

# Multiple profiles
gpc auth init --profile ci --service-account /path/to/ci-sa.json
gpc auth switch --profile ci
gpc auth profiles list

Credential resolution order:

  1. --service-account flag
  2. GPC_SERVICE_ACCOUNT_PATH env
  3. Persisted profile backend (file or keychain)

Full auth documentation: docs/AUTH.md


Build & Development

make build      # Build binary to ./build/gpc
make test       # Run tests
make lint       # go vet
make format     # gofmt
make coverage   # Generate coverage report
make dev        # Full CI pipeline locally

Docs

Document Description
COMMANDS.md Auto-generated command reference
AUTH.md Authentication model and credential sources
CI.md CI/CD examples (GitHub Actions, GitLab, CircleCI, Bitrise)
API_NOTES.md Google Play API caveats and gotchas
TESTING.md Smoke test documentation
RELEASING.md Release process
openapi/COVERAGE.md API endpoint coverage report
llms.txt AI agent entrypoint

License

MIT © 2026 Lukasz Lech


Built with ff and google.golang.org/api

About

A fast, lightweight, and scriptable CLI for Google Play Console. Automate your Android app workflows from your IDE/terminal.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages