storebound/skills/appstore-first-release/SKILL.md
CRT 25bc761a53 Skills: release management, preflight, rejections, originality, compliance, ASO, release notes
- New: review-rejections, portfolio-originality, release-management, store-preflight,
  privacy-manifest, export-compliance, aso-basics, whats-new
- Updated: explicit build numbers, first availability UI fallback, phased + manual release by
  default, IAP versions in review submissions (API 4.4.1, reported, verify), IAP description 45,
  privacy manifest cross-links, tool-neutral CLI instructions
- docs/agents-core.md: shared rules for every agent
2026-10-10 21:03:10 +08:00

6.9 KiB

name description
appstore-first-release Step-by-step first (and later) App Store release of a mobile game - App Store Connect API key, bundle id, app record, signing and xcodebuild archive/upload with the API key, TestFlight, version + listing text in many locales, screenshots, age rating, App Privacy, review details, in-app purchases with the first version, and submitting for review. Use when the user wants to publish, release, upload or set up an iOS game/app on the App Store or TestFlight, or hits App Store Connect API errors.

App Store: first release

The CLI is storebound (on PATH while the plugin is enabled; otherwise bunx storebound in a project that has it, or bun <toolchain>/cli/index.ts; agents can also use the storebound mcp tools). Config: storebound.config.ts; credentials: ASC_KEY_ID, ASC_ISSUER_ID, ASC_P8 (env or .storebound/credentials.json, gitignored). All commands are idempotent and have --dry. Run storebound check first.

Ask the owner before submitting for review, releasing, or canceling a submission. The final "Submit for Review" of a first version is the owner's click. Shared agent rules: docs/agents-core.md of the toolchain.

Steps (API = storebound, UI = App Store Connect / Xcode by hand)

  1. UI · API key. App Store Connect > Users and Access > Integrations > App Store Connect API > Team Keys > + (Admin or App Manager). Download AuthKey_<KEYID>.p8 once, keep it in ~/.appstoreconnect/private_keys/, note the Key ID and Issuer ID. The same key signs builds (-allowProvisioningUpdates).
  2. API · Bundle id. storebound apple bundle registers it (Certificates, Identifiers & Profiles).
  3. UI · App record. Apps > + > New App: iOS, name, primary language, the bundle id, SKU. No API for this. Then storebound apple status finds it (put the Apple ID in apple.appId to skip the lookup).
  4. Local · Info.plist. ITSAppUsesNonExemptEncryption with the true answer (export-compliance skill; NO only when the game uses nothing beyond OS / HTTPS encryption) so builds arrive answered; NSUserTrackingUsageDescription if ads use the IDFA; privacy policy reachable inside the app (guideline 5.1.1).
  5. Local · Build + upload (Mac, no Xcode account login needed, the API key does signing):
    K="-allowProvisioningUpdates -authenticationKeyPath $ASC_P8 -authenticationKeyID $ASC_KEY_ID -authenticationKeyIssuerID $ASC_ISSUER_ID"
    xcodebuild -project ios/App/App.xcodeproj -scheme App -configuration Release -destination generic/platform=iOS \
      -archivePath build/App.xcarchive MARKETING_VERSION=1.0.0 CURRENT_PROJECT_VERSION=3 $K archive
    xcodebuild -exportArchive -archivePath build/App.xcarchive -exportOptionsPlist ExportOptions.plist -exportPath build/export $K
    
    ExportOptions.plist: method app-store-connect, destination upload, teamID , signingStyle automatic. MARKETING_VERSION / CURRENT_PROJECT_VERSION overrides beat the project values. Take the build number from storebound apple next-build right before archiving and note it: every later step selects that exact build, never "the latest". Processing takes 5-30 min (storebound apple status shows VALID).
  6. UI · TestFlight. Create an internal group with "access to all builds" (hasAccessToAllBuilds) once: every new build reaches the testers automatically. Sandbox testers: Users and Access > Sandbox.
  7. API · Version + text. Fill store/appstore.md, then storebound apple listing --version 1.0.0 --build 3 (version, copyright, MANUAL release, the build with exactly that number, name / subtitle / privacy URL, description / keywords / promo / URLs). Then storebound apple release --phased on: manual release + phased release is the default for every version (release-management).
  8. API · Screenshots. store-screenshots skill, then storebound apple screenshots > .storebound/asc-shots.log 2>&1 & (6.9" + 6.5" per locale, MD5-idempotent).
  9. API · App info. storebound apple appinfo: categories, age rating declaration, content rights, Free price, all territories. The first availability record of a new app may be refused by the public API (an error on POST /v2/appAvailabilities); then set it once in App Store Connect > Pricing and Availability and re-run (later runs only read it).
  10. API · Review details. storebound apple review-details (contact from .storebound/credentials.json reviewContact, or --contact-from <Apple ID of another app of the team>; notes from the config).
  11. API + UI · In-app purchases. store-iap-setup skill. First IAPs go to review with this version.
  12. UI · App Privacy. store-declarations skill (nutrition labels), then Publish.
  13. Preflight. storebound validate --apple until it shows no blocker (store-preflight).
  14. UI · Submit. Version page > Add for Review (with the IAPs in the same draft submission) > Submit for Review (owner). Release type MANUAL means the owner presses "Release" after approval.
  15. Verify + wait. storebound apple status: version WAITING_FOR_REVIEW, IAPs WAITING_FOR_REVIEW, one review submission. storebound apple status --wait-review polls until approved (exit 0) or rejected (exit 1, review-rejections). Approved: the owner releases (release-management).

Gotchas

  • The app record cannot be created via API; the bundle id can.
  • First consumable / non-consumable IAPs must be submitted together with an app version, only from the IAP page ("Add for Review" puts them into the draft submission). The API (inAppPurchaseSubmissions) answers FIRST_*_MUST_BE_SUBMITTED_ON_VERSION. If the version was already submitted without them: cancel the review submission (storebound apple status --cancel-submission <id>, PATCH canceled: true), wait a minute, add the IAPs from their page, then resubmit.
  • App Privacy (data types, purposes, linked, tracking) is UI-only and must be published, not just saved.
  • Export compliance unanswered = "Missing Compliance": storebound apple encryption (export-compliance).
  • ITMS-91053 / 91061 privacy manifest emails after upload: privacy-manifest skill.
  • Screenshot sizes: 6.9" 1320 x 2868 (APP_IPHONE_67) is required; 6.5" 1284 x 2778 (APP_IPHONE_65) recommended. PNG without alpha. Up to 10 per set. Apple processes uploads async; failures show as FAILED later.
  • App Store icon (1024) must have no alpha channel (storebound icons writes rgb24).
  • Limits: name 30, subtitle 30, promotional text 170, keywords 100 bytes (UTF-8, no spaces after commas), description 4000. No "What's New" on a first version.
  • Guideline 5.1.1: the privacy policy link must be inside the app too (Settings > Privacy), not only in the listing.
  • xcodebuild with Capacitor needs a UTF-8 locale (export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8).
  • 500 / 503 from the API happen; storebound retries with backoff.