Skip to content

Instantly share code, notes, and snippets.

@alanchrt
Created June 24, 2026 19:37
Show Gist options
  • Select an option

  • Save alanchrt/692dd32611b23c5d2b8252465c2b7b2e to your computer and use it in GitHub Desktop.

Select an option

Save alanchrt/692dd32611b23c5d2b8252465c2b7b2e to your computer and use it in GitHub Desktop.
Google Play closed testing setup for Duramata Android

Google Play closed testing — manual setup steps

This change adds a Google Play closed testing (alpha track) build to the production CI lane. Each app.* release now runs two Android builds in parallel:

  • android-build → the existing internal build (production profile), unchanged, still installable by Expo/EAS testers via a direct link.
  • android-build-play → a new Play Store build (production-play profile) that auto-submits to the closed testing (alpha) track.

Neither job does anything useful until the one-time Google Play setup below is complete. Do the steps in order.

The equivalent iOS guide is testflight-setup.md.

1. Register a Google Play Developer account

  1. Go to play.google.com/apps/publish and sign in with a Google account owned by Mirascope.
  2. Pay the $25 one-time registration fee.
  3. Complete the developer profile (developer name, contact email, phone number).
  4. Wait for account verification — typically a few hours, up to 48 hr.

2. Create the app in Play Console

  1. Click Create app.
  2. Fill in:
    • App name: Duramata
    • Default language: English (United States)
    • App or game: App
    • Free or paid: Free
  3. Accept the declarations and click Create app.

The package name is com.duramata.mobile — set in app/app.config.ts, no changes needed.

Complete the minimum required sections for closed testing

Play Console requires these before any build can be promoted to the alpha track:

Section What to do
App content → Privacy policy Paste the Duramata privacy policy URL
App content → Content rating Complete the questionnaire (~5 min)
App content → Target audience Select the appropriate age group
Store listing (main) Short description, full description, ≥2 screenshots, 1 feature graphic (1024×500 px). App icon is pulled from the AAB automatically.
Pricing & distribution Confirm free; select countries (or "all countries")

You don't need a complete production store listing — just enough for Play's dashboard validation to pass. Fill in the rest before a production launch.

3. Complete the policy compliance checklist

Google Play reviews closed-testing builds against the same Developer Program Policies as production builds. Before sending the first release for review, confirm the items below. As of June 24, 2026, the primary policy surface for Duramata is:

Current compliance assessment

Duramata should not be submitted until the Required before Play review items below are complete. The biggest policy decision is payments: the app is free to install, but credits/pixels are digital value used for app functionality and cloud services. Google Play's baseline Payments policy requires Google Play's billing system for those Android in-app purchases unless an exception, eligible region, or enrolled alternative-billing/external-link program applies. For users in the United States, Google says that during the Epic injunction it will not prohibit developers from linking to transactions or using payment methods other than Google Play Billing. Treat that as US-specific unless Play Console policy/program enrollment confirms broader coverage.

Area Status Required before Play review
Payments / credits Region/program decision needed Web-purchase messaging without an in-app payment flow or link may be allowed for US users under the Epic injunction policy update. If the app is available outside the US, either use Google Play Billing for Android credit/pixel purchases, enroll in the applicable alternative-billing/external-link program for each country, or keep Android consume-only with no non-Play payment CTA in regions where external links are not permitted.
Free app disclosure Needs listing work Keep Free or paid: Free, but disclose in the store listing if meaningful app usage requires purchased credits/pixels. Make sure Android in-app copy matches the country availability/payment approach above.
Privacy policy / user data Needs Play Console completion Provide a public, non-PDF privacy policy URL in Play Console and in the app. It must name Duramata/Mirascope, provide a privacy contact, describe collected data, third-party sharing, secure handling, retention, and deletion.
Data safety Needs Play Console completion Fill the Data safety form consistently with the privacy policy and SDK behavior. Include account identifiers, email/phone auth data, usage data, generated content, payment/customer data, diagnostics, analytics, push tokens, and any third-party processors used by the app.
Account deletion Needs verification If Android lets users create an account, Play requires a discoverable in-app deletion request path and an outside-the-app web deletion URL in Play Console. Document any retained data and lawful retention reasons in the privacy policy.
AI-generated content Needs in-app reporting confirmation Duramata generates AI text/images/content from user prompts. The app must prevent restricted content generation where feasible and provide an in-app way to report or flag offensive AI-generated content without leaving the app.
User-generated content Needs moderation confirmation If user-created sprites, chats, files, shared content, or public/team-accessible content are visible to other users, require terms acceptance, prohibit objectionable content, and provide in-app reporting. Add blocking controls if direct user interaction or public UGC is available.
Content rating Needs Play Console completion Complete the IARC questionnaire accurately. Account for AI-generated content, UGC visibility, user interaction, purchases, and any mature content the model could generate or users could upload. Re-submit the questionnaire when those features change.
Store metadata Needs listing work Title must be 30 characters or fewer. Descriptions, screenshots, icon, and feature graphic must accurately describe Duramata and must not include misleading claims, ranking/performance claims, inappropriate imagery, or keyword stuffing.
Functionality / reviewer access Needs review credentials and smoke test The submitted build must install, launch, sign in, and demonstrate meaningful app functionality. Provide reviewer instructions and a test account if access is gated by waitlist, invitation, or sign-in.
Restricted categories Confirm not applicable Confirm the app does not provide regulated financial services, gambling, health/medical services, blockchain trading, illegal activity facilitation, or child-directed features. If any of these become product features, review the corresponding Play policy before shipping.

Payment implementation note

The current server capability model already rejects Android checkout with android_consume_only, so the Android app does not process payment in-app. The remaining policy question is the in-app instruction that users should buy credits on the web.

For US users, that instruction may be acceptable under Google's Epic injunction policy update. Confirm any applicable US external-link/alternative-billing program steps before review.

For non-US availability, do not assume the US rule applies. Either implement Google Play Billing, enroll in the applicable alternative/external-link program for each served country, or use neutral consume-only Android copy, for example:

Pixel purchases are not available in this Android build. Existing balances can still be used here.

For regions where external payment links are not permitted, do not include "Visit the web app," "Continue to Stripe," checkout URLs, web purchase instructions, or other calls to action that lead Android users to an external payment method for credits/pixels. If we want Android users to buy credits inside the app worldwide without regional complexity, implement Google Play Billing products for pixel packs and keep Play Console pricing, in-app pricing, and purchase fulfillment in sync.

4. Set up the Play API service account (for automated CI submissions)

EAS submits builds using a Google Cloud service account. One-time setup.

4a. Link a Cloud project

In Play Console → Setup → API access, click Link to a Google Cloud project. Create a new project if prompted.

4b. Create the service account

  1. On the linked project page, click Create new service account.
  2. Follow the link to Google Cloud Console → IAM → Service Accounts.
  3. Click Create Service Account:
    • Name: eas-submit
    • Leave the IAM role blank — access is granted in Play Console, not IAM.
  4. After creation, open the service account → KeysAdd Key → Create new key → JSON. Download the .json file.

4c. Grant Play Console access

Back in Play Console → Setup → API access, find eas-submit and click Grant access. Set the permission level to Release manager and save.

4d. Store the key as an EAS secret

cd app
bunx eas-cli@latest secret:create \
  --scope project \
  --name GOOGLE_SERVICE_ACCOUNT_KEY \
  --type file \
  --value /path/to/downloaded-key.json

Do not commit the JSON file. Delete the local copy after uploading. EAS looks for a secret named GOOGLE_SERVICE_ACCOUNT_KEY automatically when submitting Android builds — no further config is needed in eas.json.

5. Confirm CI auth

The android-build-play job uses EXPO_TOKEN from the GitHub production environment — the same secret used by all other EAS jobs. No new GitHub secret is needed; the service account key lives inside EAS.

6. Upload the first build manually (one-time)

The Play Store API rejects first-time uploads; the first build on any track must go through the Play Console web UI.

  1. Run a local build: cd app && bunx eas-cli@latest build --profile production-play --platform android
  2. Download the .aab from the EAS dashboard.
  3. In Play Console → Testing → Closed testing, open the alpha track (or create it if it doesn't exist yet).
  4. Click Create new release → Upload and select the .aab.
  5. Play Console will prompt you to enroll in Google Play App Signing — accept. Google re-signs the AAB for distribution and holds the distribution key; you retain the upload key (managed by EAS).
  6. Add release notes (e.g., "Early access build"), click Save, then Send for review.

Initial review takes 1–3 business days. After approval, CI submissions go directly to the track without manual review.

7. Add testers

In Play Console → Testing → Closed testing → Testers:

  • Email list — add individual Google account emails for a small known list.
  • Opt-in link — generate a shareable URL. Anyone with the link can join the test and install via the Play Store. Best for a semi-public early access rollout.

Testers click the link, opt in, and the app appears in their Play Store like any normal install — no security warnings, no developer mode required.

8. Cut the first automated release

After the manual first-upload approval is in place, publish an app.YYYY.MM.DD.N GitHub release. Two Android jobs run in parallel:

  • android-build produces the internal build for Expo/EAS testers (unchanged).
  • android-build-play builds the AAB and submits it to the alpha track as a draft (releaseStatus: "draft" in eas.json). Go to Play Console and promote the draft to In review to push it to testers.

Once you no longer want to manually promote each build, change releaseStatus from "draft" to "completed" in app/eas.jsonsubmit.production-play.android.

Verify

  1. Publish a test app.YYYY.MM.DD.N release → android-build-play runs alongside the other production jobs and completes successfully.
  2. EAS dashboard: the production-play build shows store distribution and its submission shows success.
  3. Play Console → Closed testing: the build appears as a draft release.
  4. Promote the draft → send for review; after approval a tester with the opt-in link can find and install Duramata from the Play Store.
  5. The existing android-build job still produces an internal artifact with an install link (no regression).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment