gpc-ci-integration
GPC CI Integration
When to use
Use this skill when the task involves:
- Setting up GPC in GitHub Actions, GitLab CI, Bitbucket Pipelines, or CircleCI
- Automating Play Store releases from CI/CD
- Configuring environment variables for CI authentication
- Using GPC's JSON output for scripting and automation
- Implementing vitals-gated rollouts in CI
- Building release pipelines with upload → promote → monitor flows
- Using
--dry-runfor safe CI testing
Inputs required
- CI platform (GitHub Actions, GitLab CI, Bitbucket, CircleCI, or generic)
- Auth method (usually service account via env var)
- Release workflow: upload only, upload + promote, or full pipeline
- Whether vitals gating is desired
- Package name of the Android app
Procedure
0) CI environment behavior
GPC auto-detects CI environments:
- Output: Defaults to JSON when stdout is not a TTY (piped or CI)
- Interactive: Prompts are disabled automatically when
CI=true - Colors: Disabled in non-TTY environments
- Plugin-CI: Writes GitHub Actions step summaries when
$GITHUB_STEP_SUMMARYis available
Environment variables for CI override:
GPC_NO_INTERACTIVE=1 # Explicitly disable prompts
GPC_NO_COLOR=1 # Explicitly disable colors
GPC_OUTPUT=json # Force JSON output
1) GitHub Actions
Minimal — upload to internal track:
name: Upload to Play Store
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build AAB
run: ./gradlew bundleRelease
- name: Upload to Play Store
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
GPC_APP: com.example.app
run: |
npm install -g @gpc-cli/cli
gpc releases upload app/build/outputs/bundle/release/app-release.aab \
--track internal \
--changes-not-sent-for-review
Full pipeline — upload, check vitals, promote:
name: Release Pipeline
on:
workflow_dispatch:
inputs:
track:
description: 'Target track'
default: 'beta'
rollout:
description: 'Rollout percentage'
default: '100'
jobs:
release:
runs-on: ubuntu-latest
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.PLAY_SERVICE_ACCOUNT }}
GPC_APP: com.example.app
steps:
- uses: actions/checkout@v4
- name: Install GPC
run: npm install -g @gpc-cli/cli
- name: Preflight compliance check
run: gpc preflight app-release.aab --fail-on error --json
- name: Upload release
run: |
gpc releases upload app-release.aab \
--track ${{ inputs.track }} \
--rollout ${{ inputs.rollout }} \
--changes-not-sent-for-review \
--mapping-type PROGUARD \
--device-tier-config default
- name: Error if in review
run: gpc releases status --error-if-in-review
- name: Check vitals
if: inputs.track == 'production'
run: |
gpc vitals crashes --threshold 2.0
gpc vitals anr --threshold 0.47
- name: Release status
if: always()
run: gpc releases status --output markdown >> $GITHUB_STEP_SUMMARY
- name: Generate GitHub Release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gpc changelog generate | gh release create ${{ github.ref_name }} -F -
# Requires GPC v0.9.61+. --strict flag available to fail CI on jargon.
Read:
references/github-actions.md
2) GitLab CI
release:
image: node:20
stage: deploy
variables:
GPC_SERVICE_ACCOUNT: $PLAY_SERVICE_ACCOUNT
GPC_APP: com.example.app
script:
- npm install -g @gpc-cli/cli
- gpc releases upload app-release.aab --track internal --changes-not-sent-for-review
only:
- tags
3) Bitbucket Pipelines
pipelines:
tags:
'v*':
- step:
name: Upload to Play Store
image: node:20
script:
- npm install -g @gpc-cli/cli
- gpc releases upload app-release.aab --track internal --changes-not-sent-for-review
deployment: production
4) CircleCI
jobs:
release:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run:
name: Upload to Play Store
command: |
npm install -g @gpc-cli/cli
gpc releases upload app-release.aab --track internal --changes-not-sent-for-review
environment:
GPC_APP: com.example.app
5) Using standalone binary (no Node.js)
For minimal CI images without Node.js:
- name: Install GPC binary
run: curl -fsSL https://raw.githubusercontent.com/yasserstudio/gpc/main/scripts/install.sh | bash
- name: Upload
run: gpc releases upload app-release.aab --track internal
6) JSON output for scripting
GPC auto-outputs JSON in CI (non-TTY). Parse with jq:
JUnit output caveat:
--output junitis available but testcasenameattributes use generic identifiers (item-1,item-2) for some commands (tracks list,releases status). Prefer--output json | jqfor reliable CI parsing. Use--output junitonly if your test reporter specifically requires JUnit XML format.
# Get version code from upload result
VERSION=$(gpc releases upload app.aab --track beta | jq -r '.data.versionCode')
# Check if vitals are OK
CRASH_RATE=$(gpc vitals crashes --output json | jq -r '.data.crashRate')
# Conditional promotion
if (( $(echo "$CRASH_RATE < 2.0" | bc -l) )); then
gpc releases promote --from beta --to production --rollout 10
fi
7) Exit codes for CI logic
| Code | Meaning | CI Action |
|---|---|---|
0 |
Success | Continue |
1 |
General error | Fail job |
2 |
Usage error (bad arguments) | Fix command |
3 |
Authentication error | Check secrets |
4 |
API error (rate limit, permission) | Retry or fix permissions |
5 |
Network error | Retry |
6 |
Threshold breach (vitals) | Block promotion |
10 |
Plugin error | Check plugin config |
- name: Check vitals
run: gpc vitals crashes --threshold 2.0
continue-on-error: false # Exit code 6 fails the job
8) Vitals-gated rollout pattern
- name: Upload to beta
run: |
gpc publish app.aab --track beta \
--changes-not-sent-for-review \
--mapping-type PROGUARD
- name: Wait for crash data
run: sleep 3600 # Wait 1 hour for crash data
- name: Gate on vitals
run: |
gpc vitals crashes --threshold 2.0
gpc vitals anr --threshold 0.47
- name: Promote to production
run: gpc releases promote --from beta --to production --rollout 10
Gate Play Store release notes on character budget (v0.9.62+)
- name: Verify all locales fit Play Store 500-char budget
run: |
gpc changelog generate --target play-store \
--locales auto \
--app com.example.app \
--strict
# --strict exits 1 if any locale overflows; collects all overflows in one report.
Translate release notes on every tag (v0.9.63+)
- name: Generate + translate Play Store release notes
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# Or OPENAI_API_KEY / GOOGLE_GENERATIVE_AI_API_KEY / AI_GATEWAY_API_KEY
run: |
gpc changelog generate --target play-store \
--locales auto \
--app com.example.app \
--ai \
--strict \
--format json > release-notes.json
# --strict exits 1 if any locale fails to translate or overflows 500 chars.
# --format json emits the `ai` block (provider, model, tokensIn, tokensOut,
# plus runId + costUsd on the Gateway path) for log aggregation.
Write translated notes into a Play Store draft (v0.9.64+)
- name: Write translated release notes into Play Store draft
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
gpc changelog generate --target play-store \
--locales auto \
--ai \
--apply \
--track production
# --apply writes the result into the latest draft release on the track.
# Requires a draft release to exist on the target track.
# Exits with RELEASE_NO_DRAFT (code 1) if no draft found.
9) Dry-run for testing pipelines
Test your CI pipeline without making real changes:
- name: Test release pipeline (dry-run)
run: |
gpc releases upload app.aab --track beta --dry-run
gpc releases promote --from beta --to production --rollout 10 --dry-run
9a) Handling rejected apps in CI
When Google Play rejects an app update, gpc releases status reports the rejection reason. Use --error-if-in-review to detect and handle in-review or rejected states in your pipeline:
- name: Check for rejection
id: review-check
run: gpc releases status --error-if-in-review
continue-on-error: true
- name: Handle rejection
if: steps.review-check.outcome == 'failure'
run: |
echo "Release was rejected or is still in review."
echo "Check the Play Console for details."
gpc releases status --output json | jq '.data.releases[] | select(.status == "rejected")'
exit 1
The --error-if-in-review flag exits with code 4 if any release on the target track is in inReview or rejected status. Use this before uploading a new version to avoid EDIT_CONFLICT errors when a previous submission is still pending review.
10) Markdown output for GitHub step summaries
gpc releases status --output markdown >> $GITHUB_STEP_SUMMARY
gpc vitals overview --output markdown >> $GITHUB_STEP_SUMMARY
11) Supply chain security in CI
GPC's own CI uses 12 protection layers. When integrating GPC into your pipeline, follow these practices:
# Pin GPC version (don't rely on @latest in production)
- run: npm install -g @gpc-cli/cli@0.9.50
# Or use the standalone binary (no npm supply chain risk)
- run: curl -fsSL https://raw.githubusercontent.com/yasserstudio/gpc/main/scripts/install.sh | bash
# Pin GitHub Actions to commit SHAs
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
For Socket.dev scanning on your own repo, add socket ci to your workflow:
- name: Socket Security Scan
run: |
npm install -g socket@latest
socket ci --repo your-repo
env:
SOCKET_SECURITY_API_TOKEN: ${{ secrets.SOCKET_SECURITY_API_TOKEN }}
12) APK uploads
GPC auto-detects the file format and uses the correct API endpoint:
# AAB upload (recommended)
- run: gpc releases upload app-release.aab --track internal
# APK upload (auto-detected)
- run: gpc releases upload app-release.apk --track internal
# Draft release (not visible to users until explicitly released)
- run: gpc releases upload app-release.aab --track production --status draft
13) Retry and timeout configuration
env:
GPC_MAX_RETRIES: '5'
GPC_TIMEOUT: '60000'
GPC_BASE_DELAY: '2000'
GPC_MAX_DELAY: '120000'
GPC_RATE_LIMIT: '50'
Use --retry-log to debug transient failures:
gpc releases upload app.aab --track beta --retry-log retries.log
Verification
- CI job completes with exit code 0
gpc releases status(in subsequent step) confirms release is on expected track- GitHub Actions step summary shows release details
- Vitals check exits 0 (below threshold) or 6 (above threshold) as expected
Failure modes / debugging
| Symptom | Likely Cause | Fix |
|---|---|---|
AUTH_INVALID in CI |
Secret not set or wrong format | Verify PLAY_SERVICE_ACCOUNT secret contains valid JSON |
Permission denied |
Service account lacks Play Console access | Grant access in Play Console → Settings → API access |
| Timeout on upload | Large AAB + slow CI network | Increase GPC_TIMEOUT |
| Rate limited | Too many API calls | Increase GPC_BASE_DELAY, reduce parallelism |
| Exit code 6 | Vitals threshold breached | Review crash/ANR data, fix issues before promoting |
EDIT_CONFLICT |
Parallel runs editing same app | Serialize release jobs or use job concurrency limits |
IN_REVIEW or REJECTED |
Previous submission pending or rejected | Use --error-if-in-review before uploading; resolve rejection in Play Console first |
| Changes auto-submitted for review | Edit committed without opt-out flag | Add --changes-not-sent-for-review to upload/push commands |
Read:
references/troubleshooting.md
Related skills
- gpc-setup: Initial authentication and configuration
- gpc-release-flow: Release commands and rollout management
- gpc-vitals-monitoring: Vitals metrics and review management
- gpc-metadata-sync: Store listing automation
More from yasserstudio/gpc-skills
gpc-sdk-usage
Use when building applications that programmatically interact with the Google Play Developer API using GPC's TypeScript SDK packages. Make sure to use this skill whenever the user mentions @gpc-cli/api, @gpc-cli/auth, PlayApiClient, createApiClient, resolveAuth, Google Play API client, TypeScript SDK, programmatic access, API client, HTTP client, rate limiter, pagination, edit lifecycle in code, Node.js Google Play, server-side Play Store, backend integration — even if they don't explicitly say 'SDK.' Also trigger when someone wants to build a backend service, custom dashboard, automation script, or any TypeScript/JavaScript application that interacts with Google Play programmatically rather than through the CLI. For CLI usage, see other gpc-* skills. For building plugins, see gpc-plugin-development.
12gpc-release-flow
Use when uploading, releasing, promoting, or managing rollouts on Google Play. Make sure to use this skill whenever the user mentions gpc releases, upload AAB, upload APK, staged rollout, promote to production, halt rollout, gpc publish, release notes, track management, internal testing, beta release, production rollout, version code, rollout percentage, gpc bundles, bundle list, bundle wait, wait for bundle processing, in-app update priority, retain version codes, versioned changelogs, or wants to ship an Android app to any Play Store track. Also trigger when someone asks about the Google Play edit lifecycle, release validation, or how to do a phased rollout — even if they don't mention GPC by name. For metadata and listings, see gpc-metadata-sync. For CI/CD integration, see gpc-ci-integration.
12gpc-security
Use when dealing with GPC credential security, secret management, audit logging, or access control. Make sure to use this skill whenever the user mentions credentials, service account key, secret rotation, key rotation, credential storage, audit log, audit trail, security best practices, .gpcrc.json security, secrets in CI, GPC_SERVICE_ACCOUNT safety, keychain, token cache, credential leak, key compromise, secure deployment — even if they don't explicitly say 'security.' Also trigger when someone asks about where GPC stores credentials, how to rotate service account keys, how to audit who did what with GPC, how to securely pass credentials in CI/CD, or how to handle a compromised service account key. For auth setup, see gpc-setup. For CI configuration, see gpc-ci-integration.
12gpc-multi-app
Use when managing multiple Google Play apps with GPC. Make sure to use this skill whenever the user mentions multiple apps, multi-app, monorepo, white-label, batch operations, bulk upload, several apps, --app flag, app switching, profiles for different apps, fleet management, app portfolio, multiple package names — even if they don't explicitly say 'multi-app.' Also trigger when someone has more than one Android app and wants to manage them efficiently, when they need different configurations per app, when they're running the same command across multiple apps, or when they have a monorepo with multiple Android modules. For single-app setup, see gpc-setup. For CI automation, see gpc-ci-integration.
11gpc-setup
Use when setting up GPC (Google Play Console CLI): authentication with service accounts, OAuth, or Application Default Credentials; configuration files (.gpcrc.json, env vars, XDG paths); auth profiles; running gpc doctor; troubleshooting auth errors. Make sure to use this skill whenever the user mentions gpc auth, service account setup, gpc config, gpc doctor, GPC_SERVICE_ACCOUNT, gpc auth login, Google Play API credentials, Play Console authentication, gpc setup, gpc setup wizard, one-command onboarding, or wants to install/configure GPC — even if they don't explicitly say 'setup.' Also trigger when someone is troubleshooting auth failures, token expiration, keychain issues, or proxy/network configuration for GPC.
11gpc-monetization
Use when managing in-app purchases, subscriptions, pricing, or Real-Time Developer Notifications in Google Play. Make sure to use this skill whenever the user mentions gpc subscriptions, gpc iap, gpc purchases, gpc pricing, gpc rtdn, in-app products, base plans, subscription offers, one-time products, consumable products, purchase verification, purchase acknowledgement, purchase token, subscription cancellation, subscription deferral, voided purchases, refunds, regional pricing, currency conversion, price migration, SKU management, monetization, revenue, billing, subscription analytics, churn, trial conversion, subscriber count, RTDN, Real-Time Developer Notifications, Pub/Sub notifications, subscription events, purchase events — even if they don't explicitly say 'monetization.' Also trigger when someone wants to create or update subscriptions, manage base plan lifecycle (activate/deactivate), set up introductory offers, verify server-side purchases, handle refunds, convert prices across regions, sync IAP products from files, migrate subscribers to new prices, view subscription analytics, decode Pub/Sub notification payloads, or check RTDN topic configuration. For release management, see gpc-release-flow. For CI automation, see gpc-ci-integration.
11