apple testflight distribute: a build's groups read per group (GET /v1/betaGroups/{id}/relationships/builds) instead of GET /v1/betaGroups?filter[builds]=, which App Store Connect refuses with 400 although the spec declares it; internal all-builds groups reported as already available and never sent the build; a re-run adds nothing; configured groups missing on App Store Connect point at groups sync, unknown ones list what exists; APPLE_LIVE_REJECTED (refused by storebound api too), tests/asc-query-guard.test.ts checks every App Store Connect GET with a query in cli/ against the spec's declared parameters, and the fake App Store Connect answers 400 to undeclared or live-refused parameters (pitfall 42)

This commit is contained in:
CRTkafa 2026-10-13 06:03:16 +08:00
parent f741c15829
commit bba46b5c7f
13 changed files with 354 additions and 14 deletions

View file

@ -549,3 +549,18 @@ that fails without the fix (see CONTRIBUTING.md).
`storebound console plan play-app-content --all` walks every card and ends with that one owner list.
- **Guard:** `declarationSaveAllowed`, `publishingControl`, `flowAllowed` (`cli/lib/console-forms.ts`), the plans'
`buttons.final` "Send changes for review", `console fill`'s declaration Save; `tests/console-play-plans.test.ts`.
## 42. A filter the spec declares, refused live (TestFlight distribute)
- **Symptom:** `apple testflight distribute --build 1 --group Team --yes` printed the build state, then failed:
`GET /v1/betaGroups?filter[app]=…&filter[builds]=… -> 400`. Before the groups existed it said `unknown group
"Team" ()`.
- **Cause:** Apple's OpenAPI spec declares `filter[builds]` on `GET /v1/betaGroups`, but App Store Connect answers 400;
the spec has no GET of a build's groups. An internal group with all builds already has every build and refuses
one added by hand.
- **Do:** read a build's groups per group (`GET /v1/betaGroups/{id}/relationships/builds`); skip internal all-builds
groups ("already available"). A configured group missing on App Store Connect: `storebound apple testflight groups
sync` first. Never use a query parameter that is not declared for the operation (`storebound api list`), and add
one refused live to `APPLE_LIVE_REJECTED` (`cli/api/client.ts`).
- **Guard:** `tests/asc-query-guard.test.ts` (every App Store Connect GET with a query in `cli/` against the spec and
`APPLE_LIVE_REJECTED`), the fake App Store Connect's 400 for such parameters, `unknownGroupMessage`;
`tests/idempotency.test.ts` (distribute), `tests/testflight.test.ts`.

View file

@ -60,7 +60,12 @@ beta app localization before a Beta App Review submission, and fields cannot be
## 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.
`apple_testflight_distribute`, internal groups only). Groups with `allBuilds: true` get every build automatically:
distribute reports "already available to <group> (internal, all builds)" and sends nothing (App Store Connect
refuses adding a build to such a group). Internal groups without all builds get the build like external ones.
A re-run adds nothing (it reads each group's builds first).
- A group in `apple.testflight.groups` that is not on App Store Connect yet: run `storebound apple testflight groups
sync` first (distribute and testers say so); a name in neither lists the groups that exist.
- 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`,