apple: release type (apple.releaseType, apple release --after-approval|--manual), device-family preflight, TestFlight invite needs an installable build
This commit is contained in:
parent
4763862178
commit
85cf494c0a
24 changed files with 899 additions and 18 deletions
|
|
@ -76,7 +76,7 @@ answers the compliance facts no file proves, all in one batch at the start.
|
|||
14. **Submit.** `storebound apple submit --build <n>` (dry run: the plan table with the build you uploaded, by its
|
||||
number, the version and the ready IAPs in one review submission), then the owner's yes for the same command with
|
||||
`--yes`; with IAPs `apple iap-submit --with-version --yes` does the same without attaching a build (step 11). In
|
||||
the desktop app the owner presses Releases > Submit for review (plan, then a system dialog). Release type MANUAL
|
||||
the desktop app the owner presses Releases > Submit for review (plan, then a system dialog). Release type MANUAL (or apple.releaseType: afterApproval | manual | scheduled; `apple release --after-approval | --manual | --scheduled <date>` changes it until the version is approved; for the first version of an app after-approval is the owner's step)
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,12 @@ presses release; you prepare, dry-run and report. `storebound mcp` deliberately
|
|||
already); the first-ever submission is the owner's (exit 3 `OWNER_STEP`, re-run with `--first-release` after the
|
||||
owner's yes). Wait: `storebound apple status --wait-review` (polls with backoff, exit 0 approved, 1 rejected,
|
||||
7 timeout; `--timeout 72h`). Rejected: `review-rejections` skill.
|
||||
4. Approved = PENDING_DEVELOPER_RELEASE. Release an update yourself: `storebound apple release --manual-release --yes`
|
||||
4. Release type: an update that should go live by itself is `afterApproval`. Set `apple.releaseType: afterApproval` in the
|
||||
config (`apple listing` applies it to a new version, `apple submit` sets it before submitting and its dry run shows
|
||||
`releaseType MANUAL -> AFTER_APPROVAL`), or on one version `storebound apple release --after-approval --yes`
|
||||
(`--manual` / `--scheduled <ISO date>` are the other two; allowed until App Review approves the version, exit 7 when it
|
||||
is that type already; pitfall 125). Without it an approved MANUAL version waits in PENDING_DEVELOPER_RELEASE.
|
||||
Approved = PENDING_DEVELOPER_RELEASE. Release an update yourself: `storebound apple release --manual-release --yes`
|
||||
(the first-ever release of an app is the owner's: `OWNER_STEP`) or the "Release This Version" button. With phased release on, automatic updates reach 1 %, 2 %, 5 %, 10 %, 20 %,
|
||||
50 %, 100 % over 7 days; anyone can still update manually from the store.
|
||||
5. During the rollout watch crashes / reviews. Problem: `storebound apple release --phased pause` (up to 30 days in
|
||||
|
|
|
|||
|
|
@ -1547,3 +1547,41 @@ that fails without the fix (see CONTRIBUTING.md).
|
|||
are not the user's and are not hits. A prebuilt vendored framework carries its own paths: rebuild it path-free.
|
||||
- **Never:** point a shared build folder at the default DerivedData, or run the privacy scan only after the upload.
|
||||
- **Guard:** `cli/lib/path-free.ts`, `tests/path-free.test.ts`, the hint when `--out` is outside the home folder.
|
||||
|
||||
## 125. Updates sat in Pending Developer Release: the version was created and submitted with release type MANUAL
|
||||
|
||||
- **Symptom:** an approved update did not go live; it waited in PENDING_DEVELOPER_RELEASE because `apple listing` created the
|
||||
version with releaseType MANUAL and `apple submit` never touched it.
|
||||
- **Do:** set `apple.releaseType: afterApproval` (or `manual` / `scheduled` with `apple.earliestReleaseDate`). `apple listing`
|
||||
creates new versions with it, `apple submit` / `apple resubmit` set it on the version before submitting when it differs
|
||||
(the dry run shows `releaseType MANUAL -> AFTER_APPROVAL`). On one version: `storebound apple release --after-approval --yes`
|
||||
(`--manual`, `--scheduled <ISO date>`; `--platform`, `--version`, `--json`; exit 7 when it already has that type). The type
|
||||
is editable until App Review approves the version; an approved one is released with `apple release --manual-release`.
|
||||
Unset: new versions are MANUAL and existing ones are left as they are. Updates are agent steps; `--after-approval` on the
|
||||
first version of an app puts it on sale by itself, so that is the owner's (exit 3 `OWNER_STEP`, `--first-release`).
|
||||
- **Never:** wait for an approval email and then look for the console button, or flip the type back with `apple listing` runs.
|
||||
- **Guard:** `cli/lib/release-type.ts`, `tests/apple-release-gaps.test.ts`.
|
||||
|
||||
## 126. iPhone-only build of an app whose live version runs on iPad: ITMS-90101 after a full archive
|
||||
|
||||
- **Symptom:** `storebound check` passed with `apple.ipad` false; the upload was refused after the archive with ITMS-90101 "This
|
||||
bundle does not support one or more of the devices supported by the previous app version" (TARGETED_DEVICE_FAMILY = 1).
|
||||
- **Do:** `storebound validate` and `apple build` read the live version (READY_FOR_SALE, else the newest that was) from App
|
||||
Store Connect: its build bundle (`deviceProtocols`, device models of `buildBundleFileSizes`) and its screenshot sets
|
||||
(`APP_IPAD_*`); any iPad signal means iPad. They compare it with TARGETED_DEVICE_FAMILY of the Release configuration in the
|
||||
Xcode project and with `apple.ipad`, and stop BEFORE the archive with the fix: `TARGETED_DEVICE_FAMILY = "1,2"` and
|
||||
`apple.ipad: true`. Offline `check` warns when the live families cannot be known. `--allow-device-gap` builds anyway.
|
||||
- **Never:** drop a device family the live version supports, or turn `apple.ipad` off to silence the screenshot check.
|
||||
- **Guard:** `cli/lib/device-families.ts`, `cli/apple/device-families.ts`, `tests/apple-release-gaps.test.ts`. The build bundle
|
||||
attribute names come from Apple's spec; which signal carries the iPad answer live is not recorded, hence the merge.
|
||||
|
||||
## 127. TestFlight invite on a new external group: 409 STATE_ERROR.TESTER_INVITE.NO_INSTALLABLE_BUILDS
|
||||
|
||||
- **Symptom:** `apple testflight testers --group <g> --invite --yes` created the tester but the invitation failed with 409
|
||||
NO_INSTALLABLE_BUILDS: the group had no build past Beta App Review yet.
|
||||
- **Do:** `--invite` first checks that a build of the tester's group is installable (external: BETA_APPROVED / IN_BETA_TESTING;
|
||||
internal: READY_FOR_BETA_TESTING / IN_BETA_TESTING). If not, the tester stays added, no invitation is sent and the run prints
|
||||
"tester added; the invite goes out when a build in <group> passes Beta App Review (re-run with --invite then)", exit 0. The
|
||||
409 itself is treated the same way. `apple testflight distribute --submit-review` prints the line for testers not invited yet.
|
||||
- **Never:** retry the invitation in a loop, or report the added tester as a failure.
|
||||
- **Guard:** `installableBuild` / `noInstallableBuildHint` in `cli/lib/testflight.ts`, `tests/apple-release-gaps.test.ts`.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,10 @@ changes or deletes a group.
|
|||
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).
|
||||
group has a build. `--invite` (re)sends invitations to testers still `NOT_INVITED` / `INVITED` (asks again) once a build of the tester's group is
|
||||
installable (an external group: past Beta App Review). Without one the tester is added, the invite is skipped and the run
|
||||
says "tester added; the invite goes out when a build in <group> passes Beta App Review (re-run with --invite then)" (exit 0;
|
||||
Apple's 409 `NO_INSTALLABLE_BUILDS` is handled the same way; `distribute --submit-review` prints the same line; pitfall 127).
|
||||
- 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.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue