fix(ios): normalize App Store build upload state

This commit is contained in:
joshavant
2026-07-23 18:26:29 -05:00
parent b7d77b0f21
commit 0558831b92
2 changed files with 17 additions and 2 deletions
+13 -2
View File
@@ -1256,6 +1256,17 @@ def app_store_build_uploads(app_id:, short_version: nil)
.flat_map(&:to_models)
end
def app_store_build_upload_state(upload)
# Apple's buildUploads API wraps the scalar state in a StateDetail object
# alongside diagnostics; normalize that owner contract at the adapter edge.
detail = upload.state
UI.user_error!("Invalid App Store build upload state payload: expected a StateDetail object.") unless detail.is_a?(Hash)
state = detail["state"].to_s.strip
UI.user_error!("Invalid App Store build upload state payload: missing state.") unless env_present?(state)
state
end
def release_source_clean?
stdout, _stderr, status = Open3.capture3(
"git",
@@ -1295,7 +1306,7 @@ def resolve_ios_release_plan!(release_version: nil, app_store_revision: nil, bui
{
buildNumber: upload.cf_build_version.to_s,
shortVersion: upload.cf_build_short_version_string.to_s,
state: upload.state.to_s
state: app_store_build_upload_state(upload)
}
end,
explicitBuildNumber: env_present?(build_number.to_s) ? build_number.to_s : nil,
@@ -1394,7 +1405,7 @@ def resolve_release_build_number(api_key:, short_version:, explicit_build_number
app = app_store_connect_target_app
uploads = app_store_build_uploads(app_id: app.id, short_version: short_version)
unknown_states = uploads.map { |upload| upload.state.to_s }.uniq - IOS_BUILD_UPLOAD_STATES
unknown_states = uploads.map { |upload| app_store_build_upload_state(upload) }.uniq - IOS_BUILD_UPLOAD_STATES
unless unknown_states.empty?
UI.user_error!("Unknown App Store build upload states for #{short_version}: #{unknown_states.join(', ')}.")
end
@@ -157,9 +157,13 @@ describe("iOS Fastlane release upload gates", () => {
const fastfile = readFastfile();
const planner = functionBody(fastfile, "resolve_ios_release_plan!");
const planLane = laneBody(fastfile, "release_plan");
const uploadState = functionBody(fastfile, "app_store_build_upload_state");
expect(planner).toContain("get_app_store_versions");
expect(planner).toContain("app_store_build_uploads");
expect(planner).toContain("app_store_build_upload_state(upload)");
expect(uploadState).toContain('detail["state"]');
expect(uploadState).toContain("expected a StateDetail object");
expect(planner).toContain("does not match canonical root version");
expect(planner).toContain('File.join(repo_root, "scripts", "ios-release-plan.ts")');
expect(planLane).toContain("resolve_ios_release_plan!");