Zum Inhalt springen

play-console-setup

Type Skill
Plugin awl-android · v0.0.19
Invoke /awl-android:play-console-setup
Source plugins/awl-android/skills/play-console-setup/SKILL.md

Use when setting up a new app in Google Play Console — app creation, store listing, graphics, data safety, privacy policy, age/content rating, declarations, internal/closed testing setup, first AAB upload, or “new client app in the play store”.

Trigger phrases: new client app in the play store

Turns the initial Play Console click-through (~2h of forms) into: fill one manifest file, run this skill (~15 min, human-in-the-loop for submits).

Division of labor (Google provides no API for app creation or most declarations):

Step Phase
Create app, privacy policy URL, content rating questionnaire, app content declarations Browser (Claude in Chrome, user reviews each submit)
Store listing texts, graphics, data safety, testers, first AAB to closed testing API (scripts/play_api.py)

First: confirm internal vs closed testing with the user (see the comparison table below) — it changes what the manifest needs (internal skips store listing, feature graphic, category, and countries).

Repo scan first (when run inside or pointed at the app repo — the normal case): dispatch a read-only subagent per references/repo-scan.md. It extracts package name, app name, locales, permissions, and SDK dependencies, and maps them to data-safety candidates with evidence — including whether data actually leaves the device (permission alone ≠ collected). Pre-fill the manifest from its findings and review its open questions with the user.

Then copy manifest-template.yaml next to the client project (e.g. playstore/manifest.yaml), merge in the scan results, and fill the rest (listing texts, assets, privacy policy URL) with the user. Prefer a previous client’s manifest as starting point for the texts. Collect asset files (icon 512×512, feature graphic 1024×500, ≥2 phone screenshots).

Data safety — per app, not one-size-fits-all (some apps collect location, some don’t):

  1. Fill data_safety.collects from the repo scan’s confirmed candidates. Without a repo available, derive it manually the same way: AndroidManifest.xml permissions (e.g. ACCESS_FINE_LOCATIONlocation_precise) and dependencies (Firebase Analytics → analytics_device_ids, Crashlytics → crash_logs). List findings to the user and confirm.
  2. Point data_safety.base_csv at an archetype in archetypes/ (blank-template.csv, account-auth.csv, firebase-base.csv) or a CSV exported from a similar app, then edit its rows to match collects. See references/data-safety-csv.md for the schema (question IDs, true/empty responses, per-type usage blocks) and the fast iteration loop. Set every data type NOT in collects to not-collected — never leave a stale answer from the base.
  3. Write the result to data_safety.csv, then push it via play_api.py datasafety and iterate against its precise validation errors (missing ephemeral answer, deletion-URL requirement, etc. — all documented in the reference). When it prints accepted, show the user a summary of what changed vs. the base before moving on. The API is more reliable than the browser importer (the Chrome file-upload tool no longer accepts host paths).

The archetypes/ dir holds reusable base CSVs. When you build one for a new app shape (e.g. firebase-location.csv), contribute it back to this skill in the claude-code repo (plugin installs are read-only caches — local edits get wiped on update).

Credentials: per-client service account JSON — created via the awl-android:play-console-service-account skill, stored in 1Password (AWL-App Publishing vault). The account needs access to the new app (grant in Play Console → Users and permissions, or it inherits if account-wide).

The ONLY step that must precede everything else. Follow references/browser-phase.md § Create app. User reviews and clicks the final “Create app”. Then ensure the service account has permissions on the new app.

Run from the directory containing the manifest (uses uv; deps inline):

Terminal-Fenster
scripts/play_api.py --key sa.json --manifest manifest.yaml listings # texts + contact details
scripts/play_api.py --key sa.json --manifest manifest.yaml images # icon, feature graphic, screenshots
scripts/play_api.py --key sa.json --manifest manifest.yaml datasafety # POST data safety CSV
scripts/play_api.py --key sa.json --manifest manifest.yaml tracks # list track names (find the closed track)
scripts/play_api.py --key sa.json --manifest manifest.yaml aab # upload first AAB as DRAFT release + testers

Notes:

  • Commits auto-retry with changesNotSentForReview=true — expected for unpublished apps.
  • First AAB via API is uploaded as a draft release. If the commit still fails for a brand-new app, fall back to uploading the AAB manually in the browser phase (drag & drop) — the restriction is on review submission, not upload.
  • If datasafety fails (endpoint occasionally rejects new apps), fall back to Console → App content → Data safety → Import from CSV — the user does the import (the Chrome file-upload tool no longer accepts host paths); tell them where the CSV is.
  • aab sets testers via google_groups only — the API takes no individual emails. An email tester list must be set by the user in the Console (track → Testers).

Follow references/browser-phase.md § App content (plus § Closed-testing track setup — countries/regions, category — if targeting closed testing). Fill each form from the manifest’s content_rating and declarations sections. Stop before every final submit and let the user review — never submit a questionnaire yourself.

Show the user the Console dashboard checklist. Remaining manual steps: review data safety (if CSV-imported), promote the draft release, roll out testing, invite testers. Ongoing publishing then goes through the existing CI pipeline.

Internal vs closed testing — pick the right target

Abschnitt betitelt „Internal vs closed testing — pick the right target“

They have very different requirements. Confirm which the user wants up front.

Internal testing Closed testing
Google review None — live in minutes Required — every release is reviewed
Store listing Not required Full listing required, incl. feature graphic (1024×500)
App category + contact Not required Required (Store settings → App category)
Countries/regions Not required Required on the track (≥1)
Testers Email list / Google Group Email list / Google Group
Testers cap 100 larger

For a private/dev test, internal testing is the light path — it skips review, store listing, feature graphic, category, and countries. Only go to closed testing when the user needs review-track parity or a bigger audience. Promote internal→closed via the release’s Promote release menu (reuses the same AAB).

To move a prepared release into review: Publishing overview → Submit N changes for review (runs ~15 min of automated “quick checks” first). Sending for review is always the user’s action.

  • Feature graphic (1024×500) is only flagged as missing when you reach a full store listing / closed testing — not for internal. The images API command uploads it (featureGraphic key); generate one if the client has none.
  • App category + contact details is a separate “Set up your app” task that the listings/images API does not complete — set the category in the browser (Store settings). Contact email does come from listings.
  • Sign-in details (“App access”): closed/production review needs credentials that give reviewers full access. Apps gated behind OTP/2FA with no reusable test account can’t satisfy this honestly and will fail review — another reason internal testing fits such apps.
  • Deep links to /publishing-overview and /app-content bounce to the account home. Navigate via the in-app left nav (Policy and programmes → App content; the Publishing overview nav item) instead.
  • Content rating / target-audience wizards: click Save to commit before the Next/stepper enables. Selecting only “18 and over” skips the child-safety sub-steps.
  • uv (script deps are inline: google-auth, requests, pyyaml) — or pip install google-auth requests pyyaml and run with python3
  • Service account JSON with androidpublisher access to the app
  • Claude in Chrome connected, user logged into Play Console
  • No API creates an app — browser only.
  • Content rating + app content declarations — browser only.
  • Sending the first release for review is always a human action in the Console.
  • ToS: run against the client’s own developer account with a per-client service account; never one central credential across client accounts (Publishing API ToS forbids acting on behalf of a third party’s account).