A fast, lightweight, and scriptable CLI for Google Play Console. Automate your Android app workflows from your terminal.
| Problem | Solution |
|---|---|
| Manual Play Console work | Automate everything from CLI |
| Slow, heavy tooling | Single Go binary, instant startup |
| Poor scripting support | JSON output, explicit flags, clean exit codes |
| Complex release workflows | High-level commands like release, promote, rollout |
- Why gplay?
- Quick Start
- Commands
- Output Formats
- Design Philosophy
- Installation
- Authentication
- Configuration
- CI/CD Integration
- Security
- Contributing
- Agent Skills
- License
# Via Homebrew (recommended)
brew tap tamtom/tap
brew install tamtom/tap/gplay
# Install script (macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bash
# Build from source
git clone https://github.com/tamtom/play-console-cli.git
cd play-console-cli
make build
./gplay --helpgplay checks for updates on startup and shows upgrade hints. Disable with --no-update or GPLAY_NO_UPDATE=1.
Step 1: Create a Google Cloud Project
- Go to Google Cloud Console
- Create a new project or select an existing one
- Note your project ID
Step 2: Enable the API
- Go to APIs & Services > Library
- Search for "Google Play Android Developer API"
- Click Enable
Step 3: Create a Service Account
- Go to IAM & Admin > Service Accounts
- Click Create Service Account
- Give it a name (e.g., "gplay-cli")
- Click Create and Continue, then Done
- Click on the created service account
- Go to Keys > Add Key > Create new key > JSON
- Save the downloaded JSON file securely
Step 4: Grant Access in Play Console
- Go to Google Play Console
- Go to Users and permissions > Invite new users
- Enter the service account email (from the JSON file, looks like
name@project.iam.gserviceaccount.com) - Set permissions (Admin or specific app access)
- Click Invite user
Step 5: Login with gplay
gplay auth login --service-account /path/to/service-account.json
# Verify it works
gplay auth doctor- JSON output is default for easy parsing; add
--prettywhen debugging - Use
--paginateto automatically fetch all pages - Sort with
--sort(prefix-for descending):--sort -uploadedDate - Use
--limit+--nextfor manual pagination control
# Edit lifecycle
gplay edits create --package com.example.app
gplay edits list --package com.example.app
gplay edits validate --package com.example.app --edit <id>
gplay edits commit --package com.example.app --edit <id>
# Upload artifacts
gplay bundles upload --package com.example.app --edit <id> --file app.aab
gplay apks upload --package com.example.app --edit <id> --file app.apk
# Manage tracks
gplay tracks list --package com.example.app --edit <id>
gplay tracks get --package com.example.app --edit <id> --track production
gplay tracks update --package com.example.app --edit <id> --track internal --json @release.json# One-command release (creates edit, uploads, updates track, commits)
gplay release --package com.example.app --track internal --bundle app.aab
# With release notes and staged rollout
gplay release --package com.example.app --track production --bundle app.aab \
--release-notes @notes.json --rollout 10
# Promote between tracks
gplay promote --package com.example.app --from internal --to beta
# Manage staged rollout
gplay rollout update --package com.example.app --track production --rollout 50
gplay rollout halt --package com.example.app --track production
gplay rollout resume --package com.example.app --track production
gplay rollout complete --package com.example.app --track production# Listings
gplay listings list --package com.example.app --edit <id>
gplay listings get --package com.example.app --edit <id> --locale en-US
gplay listings update --package com.example.app --edit <id> --locale en-US --json @listing.json
# Images
gplay images list --package com.example.app --edit <id> --locale en-US --type phoneScreenshots
gplay images upload --package com.example.app --edit <id> --locale en-US --type phoneScreenshots --file screenshot.png
# App details
gplay details get --package com.example.app --edit <id>
gplay details update --package com.example.app --edit <id> --contact-email dev@example.com# In-app products
gplay iap list --package com.example.app
gplay iap create --package com.example.app --sku premium_upgrade --json @product.json
gplay iap update --package com.example.app --sku premium_upgrade --json @product.json
gplay iap batch-update --package com.example.app --json @products.json
# Subscriptions
gplay subscriptions list --package com.example.app
gplay subscriptions create --package com.example.app --json @subscription.json
# Base plans
gplay baseplans activate --package com.example.app --product-id sub_premium --base-plan monthly
gplay baseplans deactivate --package com.example.app --product-id sub_premium --base-plan monthly
# Offers
gplay offers list --package com.example.app --product-id sub_premium --base-plan monthly
gplay offers create --package com.example.app --product-id sub_premium --base-plan monthly --json @offer.json
# Price conversion
gplay pricing convert --package com.example.app --json @price.json# Verify purchases
gplay purchases products get --package com.example.app --product-id premium --token <token>
gplay purchases products acknowledge --package com.example.app --product-id premium --token <token>
gplay purchases subscriptions get --package com.example.app --token <token>
# Orders
gplay orders get --package com.example.app --order-id <id>
gplay orders refund --package com.example.app --order-id <id> --revoke
# External transactions (EU compliance)
gplay external-transactions create --package com.example.app --json @transaction.json# List and filter reviews
gplay reviews list --package com.example.app
gplay reviews list --package com.example.app --paginate
# Reply to reviews
gplay reviews get --package com.example.app --review-id <id>
gplay reviews reply --package com.example.app --review-id <id> --text "Thank you!"# Manage testers
gplay testers list --package com.example.app --edit <id> --track internal
gplay testers update --package com.example.app --edit <id> --track internal --emails user@example.com
# Internal app sharing (quick sharing without review)
gplay internal-sharing upload-bundle --package com.example.app --file app.aab
gplay internal-sharing upload-apk --package com.example.app --file app.apk# Export metadata to FastLane format
gplay sync export-listings --package com.example.app --dir ./fastlane/metadata/android
# Import metadata from FastLane format
gplay sync import-listings --package com.example.app --dir ./fastlane/metadata/android
# Compare local metadata with Play Store
gplay sync diff-listings --package com.example.app --dir ./fastlane/metadata/android
# Validate before upload
gplay validate listing --dir ./fastlane/metadata/android --locale en-US
gplay validate screenshots --dir ./fastlane/metadata/android/en-US/images
gplay validate bundle --file app.aab# Bash
gplay completion bash > /etc/bash_completion.d/gplay
# Zsh
gplay completion zsh > "${fpath[1]}/_gplay"
# Fish
gplay completion fish > ~/.config/fish/completions/gplay.fish
# PowerShell
gplay completion powershell >> $PROFILE| Format | Flag | Use Case |
|---|---|---|
| JSON (minified) | default | Scripting, automation |
| JSON (pretty) | --pretty |
Debugging |
| Table | --output table |
Terminal display |
| Markdown | --output markdown |
Documentation |
# Parse with jq
gplay tracks list --package com.example.app | jq '.tracks[].track'
# Human-readable
gplay reviews list --package com.example.app --output table# Good - self-documenting
gplay reviews list --package com.example.app --output table
# Avoid - cryptic flags (not supported)
# gplay reviews -p com.example.app -o tableAll commands output minified JSON by default for easy parsing:
gplay tracks list --package com.example.app | jq '.tracks[] | select(.track == "production")'Everything is flag-based for automation:
# Non-interactive (CI/CD safe)
gplay edits delete --package com.example.app --edit <id> --confirmbrew tap tamtom/tap
brew install tamtom/tap/gplaycurl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bashSpecify version:
GPLAY_VERSION=1.0.0 curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bashgit clone https://github.com/tamtom/play-console-cli.git
cd play-console-cli
make build
make install # Installs to /usr/local/binService accounts are required for the Google Play Android Developer API.
Google Cloud Console → Create Project → APIs & Services → Library
→ Search "Google Play Android Developer API" → Enable
IAM & Admin → Service Accounts → Create Service Account
→ Name it (e.g., "gplay-cli") → Create → Done
→ Click the account → Keys → Add Key → Create new key → JSON
→ Save the JSON file securely (never commit to git!)
Play Console → Users and permissions → Invite new users
→ Paste service account email (from JSON: "client_email" field)
→ Set permissions (Admin, or per-app access)
→ Invite user
# Option A: Login command (saves to profile)
gplay auth login --service-account /path/to/service-account.json
# Option B: Environment variable
export GPLAY_SERVICE_ACCOUNT=/path/to/service-account.json
# Verify setup
gplay auth doctor| Variable | Description |
|---|---|
GPLAY_SERVICE_ACCOUNT |
Path to service account JSON |
GPLAY_PACKAGE |
Default package name |
GPLAY_PROFILE |
Active profile name |
GPLAY_TIMEOUT |
Request timeout (e.g., 90s, 2m) |
GPLAY_UPLOAD_TIMEOUT |
Upload timeout (e.g., 5m, 10m) |
GPLAY_NO_UPDATE |
Disable update checks (set to 1) |
GPLAY_DEBUG |
Enable debug logging (1 or api) |
GPLAY_MAX_RETRIES |
Max retries for failed requests |
GPLAY_RETRY_DELAY |
Base delay between retries |
Global: ~/.gplay/config.yaml
Local (takes precedence): ./.gplay/config.yaml
default_package: com.example.app
timeout: 120s
upload_timeout: 5m
max_retries: 3
debug: false# Add profiles for different accounts/apps
gplay auth login --profile work --service-account /path/to/work-sa.json
gplay auth login --profile personal --service-account /path/to/personal-sa.json
# Switch default profile
gplay auth switch --profile work
# Check current status
gplay auth status
# Use specific profile for a command
GPLAY_PROFILE=personal gplay tracks list --package com.example.appname: Deploy to Play Store
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up gplay
run: |
curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Build app
run: ./gradlew bundleRelease
- name: Deploy to internal track
env:
GPLAY_SERVICE_ACCOUNT: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
run: |
gplay release \
--package com.example.app \
--track internal \
--bundle app/build/outputs/bundle/release/app-release.aabdeploy:
stage: deploy
image: ubuntu:latest
before_script:
- curl -fsSL https://raw.githubusercontent.com/tamtom/play-console-cli/main/install.sh | bash
- export PATH="$HOME/.local/bin:$PATH"
script:
- gplay release --package $PACKAGE_NAME --track internal --bundle app.aab
variables:
GPLAY_SERVICE_ACCOUNT: $PLAY_SERVICE_ACCOUNT- Never commit service account keys to version control
- Use environment variables or secrets management in CI/CD
- Limit service account permissions to only what's needed
- Rotate keys regularly
- Use separate service accounts for different environments
Credentials are stored in config with file path reference only (not the key content).
make tools # installs gofumpt + golangci-lint
make format
make lint
make test
make build
./gplay --helpContributions are welcome! Please read CONTRIBUTING.md for details.
- Agents.md - Guidelines for AI agents (CLI usage, structure, patterns)
- CONTRIBUTING.md - Contribution guidelines
Use gplay with AI coding agents for assisted Android publishing workflows. Compatible with any agent that supports the Agent Skills format.
npx add-skill tamtom/gplay-cli-skills| Skill | Description |
|---|---|
gplay-cli-usage |
Guidance for running gplay commands (flags, pagination, output, auth) |
gplay-release-flow |
End-to-end release workflows for internal, beta, and production tracks |
gplay-gradle-build |
Build, sign, and package Android apps with Gradle before uploading |
gplay-metadata-sync |
Metadata and localization sync (including FastLane format) |
gplay-rollout-management |
Staged rollout orchestration and monitoring |
gplay-review-management |
Review monitoring, filtering, and automated responses |
gplay-iap-setup |
In-app products, subscriptions, base plans, and offers |
gplay-purchase-verification |
Server-side purchase verification |
gplay-testers-orchestration |
Beta testing groups and tester management |
gplay-signing-setup |
Android app signing, keystores, and Play App Signing |
Skills repository: github.com/tamtom/gplay-cli-skills
MIT License - see LICENSE for details.
Built with Go and the ffcli framework