- 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
6.9 KiB
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)
- UI · API key. App Store Connect > Users and Access > Integrations > App Store Connect API > Team Keys > +
(Admin or App Manager). Download
AuthKey_<KEYID>.p8once, keep it in~/.appstoreconnect/private_keys/, note the Key ID and Issuer ID. The same key signs builds (-allowProvisioningUpdates). - API · Bundle id.
storebound apple bundleregisters it (Certificates, Identifiers & Profiles). - UI · App record. Apps > + > New App: iOS, name, primary language, the bundle id, SKU. No API for this.
Then
storebound apple statusfinds it (put the Apple ID inapple.appIdto skip the lookup). - Local · Info.plist.
ITSAppUsesNonExemptEncryptionwith the true answer (export-complianceskill;NOonly when the game uses nothing beyond OS / HTTPS encryption) so builds arrive answered;NSUserTrackingUsageDescriptionif ads use the IDFA; privacy policy reachable inside the app (guideline 5.1.1). - Local · Build + upload (Mac, no Xcode account login needed, the API key does signing):
ExportOptions.plist: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 $Kmethodapp-store-connect,destinationupload,teamID,signingStyleautomatic.MARKETING_VERSION/CURRENT_PROJECT_VERSIONoverrides beat the project values. Take the build number fromstorebound apple next-buildright before archiving and note it: every later step selects that exact build, never "the latest". Processing takes 5-30 min (storebound apple statusshows VALID). - 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.
- API · Version + text. Fill
store/appstore.md, thenstorebound 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). Thenstorebound apple release --phased on: manual release + phased release is the default for every version (release-management). - API · Screenshots.
store-screenshotsskill, thenstorebound apple screenshots > .storebound/asc-shots.log 2>&1 &(6.9" + 6.5" per locale, MD5-idempotent). - 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). - API · Review details.
storebound apple review-details(contact from.storebound/credentials.jsonreviewContact, or--contact-from <Apple ID of another app of the team>; notes from the config). - API + UI · In-app purchases.
store-iap-setupskill. First IAPs go to review with this version. - UI · App Privacy.
store-declarationsskill (nutrition labels), then Publish. - Preflight.
storebound validate --appleuntil it shows no blocker (store-preflight). - 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.
- Verify + wait.
storebound apple status: version WAITING_FOR_REVIEW, IAPs WAITING_FOR_REVIEW, one review submission.storebound apple status --wait-reviewpolls 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) answersFIRST_*_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-manifestskill. - 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 iconswrites 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.
xcodebuildwith 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.