Beta groups from apple.testflight.groups (created when missing, never changed), testers from a CSV in .storebound/ (masked in logs, confirmation before Apple emails invitations, --remove / --invite), What to Test per locale from the App Store listing (whatToTest or whatsNew), Test Information and Beta App Review details, builds by exact number to groups, Beta App Review submission behind --submit-review and a confirmation. Pure planners in cli/lib/testflight.ts, shared CSV / table / JSON:API helpers. MCP: apple_testflight_status, _groups, _what_to_test, _info, _distribute (internal groups only). Skill testflight.
79 lines
5.6 KiB
Markdown
79 lines
5.6 KiB
Markdown
---
|
|
name: testflight
|
|
description: Run TestFlight for a mobile game through the App Store Connect API - beta groups (internal / external, public links), testers from a CSV that never enters git, adding a build by its exact number to groups, "What to Test" per locale from the release notes, Test Information, and the Beta App Review submission the owner confirms. Use when the user wants testers on a build, sets up beta groups, writes What to Test, or asks why external testers do not see a build.
|
|
---
|
|
|
|
# TestFlight
|
|
|
|
CLI: `storebound apple testflight <status | groups | testers | what-to-test | info | distribute>` (or `bunx storebound`
|
|
in a project that has it). Every write has `--dry`; run it first and show the plan. API references are cited at the top
|
|
of `cli/lib/testflight.ts` (developer.apple.com/documentation/appstoreconnectapi: beta groups, beta testers, beta build
|
|
localizations, beta app localizations, beta app review submissions).
|
|
|
|
## Prerequisites
|
|
- The build is uploaded and processed (`storebound apple status`, `VALID`), with export compliance answered
|
|
(`storebound apple encryption --build N`, export-compliance skill). A build missing it shows
|
|
`MISSING_EXPORT_COMPLIANCE` and nobody can test it.
|
|
- API key role Admin or App Manager.
|
|
|
|
## 1. Groups (config, no emails)
|
|
```ts
|
|
apple: {
|
|
testflight: {
|
|
groups: [
|
|
{ name: 'Team', internal: true, allBuilds: true }, // App Store Connect users of your team, no review
|
|
{ name: 'Friends' }, // external, by email, Beta App Review first
|
|
{ name: 'Public', publicLink: true, publicLinkLimit: 500 },
|
|
],
|
|
description: { en: 'Match tiles, clear 60 levels.', tr: '...' }, // Beta App Description per language id
|
|
reviewNotes: 'No login needed. IAPs are sandbox purchases.',
|
|
},
|
|
},
|
|
```
|
|
`storebound apple testflight groups --dry`, then without `--dry`. Groups are matched by name; storebound never renames,
|
|
changes or deletes a group.
|
|
|
|
## 2. Testers (CSV in .storebound/, never in git)
|
|
- Columns: `email,first_name,last_name,groups` (groups separated by `;`). Default path `.storebound/testers.csv`
|
|
(gitignored); the config refuses a path outside `.storebound/`. Never paste tester emails into chat, docs, issues or
|
|
commits; storebound masks them in every log line (`j***@example.com`).
|
|
- `storebound apple testflight testers --dry` shows: new testers, testers added to more groups, (with `--remove`)
|
|
testers who leave a managed group. The real run **asks first**: Apple emails each new tester an invitation once the
|
|
group has a build. `--invite` (re)sends invitations to testers still `NOT_INVITED` / `INVITED` (asks again).
|
|
- Internal groups only take App Store Connect users (Users and Access); add people there first.
|
|
- Testers are an owner action: not an MCP tool. An agent prepares the CSV format and the dry run, the owner runs it.
|
|
|
|
## 3. What to Test
|
|
- `storebound whats-new` drafts release notes into `store/appstore.md` (`### whatsNew` per locale). For testers you can
|
|
add a `### whatToTest` block per locale: it wins over `whatsNew` for TestFlight.
|
|
- `storebound apple testflight what-to-test --build N --dry`, then for real. `--text "..." --locale en-US` sets one
|
|
text instead. Pick the build by the exact number you uploaded, never "the latest"; `--version x.y.z` when the same
|
|
build number exists for two versions.
|
|
- Write it for testers: what changed, what to try, known issues. Short; it is read on a phone. Apple documents no
|
|
maximum; storebound stops at 4000 characters (assumption, see the README's unverified list).
|
|
|
|
## 4. Test Information (needed for external testing)
|
|
`storebound apple testflight info --dry`: Beta App Description per locale (`apple.testflight.description`), feedback
|
|
email (`app.contactEmail`), privacy policy and marketing URL, and the Beta App Review contact (from
|
|
`.storebound/credentials.json` `reviewContact`) plus notes (4000 characters max). Apple requires a description on every
|
|
beta app localization before a Beta App Review submission, and fields cannot be cleared once set.
|
|
|
|
## 5. Distribute
|
|
- Internal: `storebound apple testflight distribute --build N --group Team --dry`, then for real (MCP:
|
|
`apple_testflight_distribute`, internal groups only). Groups with `allBuilds: true` get every build automatically.
|
|
- External: same command with an external group; it asks first. External testers only get the build after **Beta App
|
|
Review**: add `--submit-review` (asks again) or submit in App Store Connect. The first build of a version is
|
|
reviewed; later builds of the same version are often approved quickly. Beta review states: `WAITING_FOR_REVIEW`,
|
|
`IN_REVIEW`, `APPROVED`, `REJECTED` (`storebound apple testflight status` shows internal / external build states).
|
|
- The Beta App Review submission is public-facing and the owner's call: never through MCP; an agent explains and the
|
|
owner confirms in the terminal.
|
|
|
|
## Gotchas
|
|
- Builds expire after 90 days in TestFlight; upload a new one (`storebound apple next-build`).
|
|
- Up to 100 internal testers and 10,000 external testers per app (TestFlight overview in App Store Connect Help:
|
|
https://developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview).
|
|
- A public link (`publicLink: true`) lets anyone with it join, up to `publicLinkLimit` (1-10000). Share it only where
|
|
the owner wants; it still needs the approved build.
|
|
- External testers of a game with IAP buy with sandbox accounts automatically (no charge); say so in What to Test.
|
|
- Rejected beta review: read the message in App Store Connect > TestFlight, fix, upload a new build, submit again
|
|
(review-rejections skill for the tone of the reply).
|