apple resubmit: REJECTED review submission items are marked resolved before the submit (PATCH reviewSubmissionItems resolved: true; the version item by default, IAP / subscription items with --resolve-iaps), plan table 'mark resolved' rows; on 409 'not ready yet' the items are re-read and a REJECTED item out of scope stops the run at once naming it and how to resolve it, backoff only when none is left; an empty READY_FOR_REVIEW draft is never canceled (409 'not in cancellable state'): left as is, no cancel command, apple status labels it harmless and treats the cancel 409 as such; fake ASC blocks submit on REJECTED items and refuses to cancel empty drafts. Pitfall 30

This commit is contained in:
CRTkafa 2026-10-12 10:45:05 +08:00
parent 0da5ee9d01
commit 1724296e59
17 changed files with 291 additions and 78 deletions

View file

@ -399,11 +399,25 @@ that fails without the fix (see CONTRIBUTING.md).
was 409 `ITEM_PART_OF_ANOTHER_SUBMISSION`: the version was still in the rejected submission.
- **Cause:** a rejected submission stays open with UNRESOLVED_ISSUES and keeps its items (the REJECTED version, its
IAPs); storebound only looked for READY_FOR_REVIEW drafts, and read the 409's "already added" as a duplicate.
- **Do:** upload the fixed build, `storebound apple status` (shows the submission, its items and the command), then
`storebound apple resubmit --build <n>` (dry run, plan table) and after the owner's yes `--yes`. Expect "Version is
not ready to be submitted yet" for a few minutes after the build is attached: the command retries with backoff
(up to 10 min) and a re-run continues where it stopped.
- **Also seen (same day):** with build 2 VALID, APP_STORE_ELIGIBLE and attached, every `PATCH reviewSubmissions/{id}
submitted: true` answered 409 STATE_ERROR "Version is not ready to be submitted yet, please try again later" for
25 minutes, and the console's Resubmit and Add for Review buttons were disabled. Retrying never helps: the
appStoreVersion item was still REJECTED. `PATCH /v1/reviewSubmissionItems/{item id}` with
`{"data":{"type":"reviewSubmissionItems","id":"<item id>","attributes":{"resolved":true}}}` answered 200, the item
went to READY_FOR_REVIEW, and the submit then passed (WAITING_FOR_REVIEW). The 7 IAP items were READY_FOR_REVIEW.
An empty READY_FOR_REVIEW draft (0 items) cannot be canceled: `canceled: true` answers 409 "Resource is not in
cancellable state". It is harmless; leave it (a later run reuses it).
- **Do:** upload the fixed build, `storebound apple status` (shows the submission, its items, which are REJECTED and
not resolved, and the command), then `storebound apple resubmit --build <n>` (dry run, plan table with "mark
resolved" rows) and after the owner's yes `--yes`: it attaches the build, marks the REJECTED version item resolved,
then submits. REJECTED IAP / subscription items are marked resolved only with `--resolve-iaps` (after fixing what
App Review asked for). Right after a build is attached, "not ready yet" with nothing left REJECTED is retried with
backoff (up to 10 min) and a re-run continues where it stopped. Never offer a cancel command for an empty draft.
- **Guard:** `chooseSubmission` (cli/lib/review-submit.ts) reuses an open submission and never creates a second one;
`addItem` turns the 409 into a message naming the other submission (never the lag message: `isConflict` excludes
it), a draft created by the same run is canceled and the named one used; `submitWithRetry` (cli/apple/submission.ts);
`tests/resubmit.test.ts`.
it), a draft created by the same run is left as is (not cancellable) and the named one used; `resolveRejected` /
`toResolve` mark REJECTED items in scope resolved before the submit; `submitWithRetry` (cli/apple/submission.ts)
re-reads the items on "not ready", resolves those in scope and stops at once (naming the item and how to resolve
it) when one out of scope is left, backing off only when none is; `apple status` labels an empty draft "empty draft
(harmless; App Store Connect keeps it, not cancellable)" and treats the cancel 409 as harmless; the fake ASC blocks
the submit while an item is REJECTED and refuses to cancel an empty draft; `tests/resubmit.test.ts`.