fix(review): don't block app-version submit on a non-version review in progress#44
fix(review): don't block app-version submit on a non-version review in progress#44fjqtt wants to merge 1 commit into
Conversation
…n progress create_review_submission raised ReviewAlreadyInProgressError whenever app.get_in_progress_review_submission returned anything. Spaceship filters that call only by review state (WAITING_FOR_REVIEW/IN_REVIEW/UNRESOLVED_ISSUES) and platform, never by item type, so an items-only submission in review (e.g. an In-App Event, custom product page, or experiment) blocks submitting an app version - even though App Store Connect allows an app-version submission to coexist with an items-only submission. Inspect the in-progress submission's items and only raise when it actually contains an appStoreVersion item (a real version in review, incl. a rejected one in UNRESOLVED_ISSUES); otherwise proceed and submit the version as a separate review submission. Mirrors the appStoreVersion-item classification that tramlinehq#33 added to the ready-submission path.
|
@fjqtt Good catch 👍🏼 On the change: I do remember handling the non-version items (experiments/CPP/events) to report back before submission (when prepare is clicked in Tramline), but it seems like that's only for reporting (
So this change makes sense. But, due to how Apple APIs and Spacechip is implemented, I've generally tried to reduce API calls we make per path. Fastlane's abstractions are not always efficient in this manner. For example, we could simply used We have historically hand-written pieces of Spaceship functions that are inefficiently written, so I'm wondering if we can do something like this: In in_progress = in_progress_review_submission_with_items
if in_progress
raise ReviewAlreadyInProgressError if any_app_store_version_item?(in_progress[:items])
log "In-progress review submission has no app version item; proceeding with a separate version
submission",
{submission_id: in_progress[:submission]["id"]}
enddef in_progress_review_submission_with_items
states = [
api::ReviewSubmission::ReviewSubmissionState::WAITING_FOR_REVIEW,
api::ReviewSubmission::ReviewSubmissionState::IN_REVIEW,
api::ReviewSubmission::ReviewSubmissionState::UNRESOLVED_ISSUES
].join(",")
bodies = api.get_review_submissions(
app_id: app.id,
filter: {state: states, platform: IOS_PLATFORM},
includes: "items"
).all_pages.map(&:body)
submission = bodies.flat_map { |body| body["data"] || [] }.first
return unless submission
included = bodies.flat_map { |body| body["included"] || [] }
item_ids = (submission.dig("relationships", "items", "data") || []).map { |d| d["id"] }
items = included.select { |inc| inc["type"] == "reviewSubmissionItems" && item_ids.include?(inc["id"])
}
{submission:, items:}
end # True if any of the submission's items carries an appStoreVersion linkage.
def any_app_store_version_item?(items)
items.any? { |item| item.dig("relationships", "appStoreVersion", "data") }
endNormally, I wouldn't care about an extra API call, but Apple's APIs are really slow, sometimes taking up to 5 minutes to complete a single call (this is the reason why we have comments describing number of API calls for every public facing method). The aforementioned change should ideally be cheaper and faster overall. I would need to test this with a live ASC tenant. Give me sometime to confirm, if you are able to validate this, happy to merge this in. In summary, the conceptual change is solid. Relatedly, I believe there's another latent bug with Relatedly, relatedly, your point about accidentally bundling draft app versions seem accurate. But I'm curious, isn't that what will happen if you do it from the ASC portal anyway? That is, if you have a draft app-version and an in-progress item review, creating a review for the draft version will bundle it in ASC as well, right? If yes, then I would argue that behaviour is symmetrical? |
Problem
AppStore::Connect#create_review_submissionblocks submitting an app version whenever any review submission is in progress:But Spaceship's
get_in_progress_review_submissionfilters only by review state (WAITING_FOR_REVIEW,IN_REVIEW,UNRESOLVED_ISSUES) and platform — it never looks at what the submission contains (app.rb). So an items-only review submission (an In-App Event, custom product page, or product-page experiment) that is in review will make this check truthy and hard-fail an app-version submission — even though the two are allowed to coexist.App Store Connect explicitly allows this:
— Overview of submitting for review
The "already in progress" stop is a client-side guard, not an Apple API rejection — fastlane's own
delivercarries the identical guard (deliver/lib/deliver/submit_for_review.rb), and its design note even states the assumption "There can only be one open submission per platform per app", which contradicts the two-submission rule above. We hit this in production: an In-App Event was in review, and submitting the app version failed withreview_in_progresseven though the version had nothing to do with the event.Fix
Inspect the in-progress submission's items and only raise when it actually contains an
appStoreVersionitem:UNRESOLVED_ISSUES) → still raises, unchanged.The new
review_submission_has_app_store_version_item?helper reuses the existingget_review_submission_itemsand mirrors the per-item iteration already used byget_other_ready_review_items. This extends the same "classify byappStoreVersionitem, don't block on non-version items" logic that #33 introduced for the ready-submission path to the in-progress check.Scope / notes
get_review_submission_itemscall happens only when an in-progress submission exists.get_ready_app_store_version_itemuntouched, but FWIW it looks like it digs the wrong level —responses.dig(0, "relationships", …)reads the first page body's top-level relationships rather than iteratingdata[].relationshipslikeget_other_ready_review_itemsdoes — so theSubmissionWithItemsExistErrorguard on the ready path may never fire. Happy to fix that in a follow-up if you agree.standardrb(passes) +bundler-audit; there's no unit-test harness forconnect.rb, so this PR has no automated test.ruby -cis clean.Validation
Verified against Apple's docs + fastlane source that this is a client-side guard, not an Apple API constraint. Not yet exercised against a live ASC sandbox for the specific path of PATCHing
submitted: trueon a version submission while an items-only submission is concurrently in review. Note also a separate, pre-existing failure mode (not addressed here): a draft item (not yet in its own in-review submission) can get auto-bundled into the new version submission and rejected — see fastlane #19603. Reviewers with a sandbox that has an in-review In-App Event would be ideal to confirm.