diff --git a/app/libs/deployments/app_store_connect/release.rb b/app/libs/deployments/app_store_connect/release.rb index 8f8cd1446..49609240c 100644 --- a/app/libs/deployments/app_store_connect/release.rb +++ b/app/libs/deployments/app_store_connect/release.rb @@ -6,6 +6,8 @@ class Release ExternalReleaseNotInTerminalState = Class.new(StandardError) ReleaseNotFullyLive = Class.new(StandardError) + RETRYABLE_FAILURE_REASONS = [:attachment_upload_in_progress] + def self.kickoff!(deployment_run) new(deployment_run).kickoff! end @@ -132,8 +134,8 @@ def submit_for_review! result = provider.submit_release(build_number, release_version) unless result.ok? - run.fail_with_error(result.error) - return + return run.update(failure_reason: result.error.reason) if result.error.reason.in? RETRYABLE_FAILURE_REASONS + return run.fail_with_error(result.error) end run.submit_for_review! diff --git a/app/libs/installations/apple/app_store_connect/error.rb b/app/libs/installations/apple/app_store_connect/error.rb index 15b9ffb4f..815fc210e 100644 --- a/app/libs/installations/apple/app_store_connect/error.rb +++ b/app/libs/installations/apple/app_store_connect/error.rb @@ -70,6 +70,11 @@ class Apple::AppStoreConnect::Error < Installations::Error resource: "release", code: "version_already_exists", decorated_reason: :version_already_exists + }, + { + resource: "release", + code: "attachment_upload_in_progress", + decorated_reason: :attachment_upload_in_progress } ] diff --git a/config/locales/en.yml b/config/locales/en.yml index 7a8a5731a..a89c68dcb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -52,6 +52,7 @@ en: build_not_submittable: "the build not being submittable" build_mismatch: "the build not matching the release that exists in store" review_in_progress: "a review already being in progress" + attachment_upload_in_progress: "store version is not in a valid state to submit for review, attachment uploads still in progress" review_submission_exists: "a release already being added for review in the store" phased_release_not_found: "the release not being phased release enabled" release_already_exists: "a release already being present in the store" diff --git a/spec/libs/deployments/app_store_connect/release_spec.rb b/spec/libs/deployments/app_store_connect/release_spec.rb index b2c5551d6..ad720f456 100644 --- a/spec/libs/deployments/app_store_connect/release_spec.rb +++ b/spec/libs/deployments/app_store_connect/release_spec.rb @@ -353,22 +353,33 @@ context "when failure" do let(:run) { create_deployment_run_for_ios(:started, deployment_traits: [:with_app_store, :with_production_channel], step_trait: :release) } let(:error) { Installations::Apple::AppStoreConnect::Error.new({"error" => {"resource" => "build", "code" => "not_found"}}) } + let(:retryable_error) { Installations::Apple::AppStoreConnect::Error.new({"error" => {"resource" => "release", "code" => "attachment_upload_in_progress"}}) } before do allow(providable_dbl).to receive(:submit_release).and_return(GitHub::Result.new { raise error }) end it "marks the deployment run as failed when failure" do + allow(providable_dbl).to receive(:submit_release).and_return(GitHub::Result.new { raise error }) described_class.submit_for_review!(run) expect(run.reload.failed?).to be(true) end it "adds the reason of failure to deployment run" do + allow(providable_dbl).to receive(:submit_release).and_return(GitHub::Result.new { raise error }) described_class.submit_for_review!(run) expect(run.reload.failure_reason).to eq("build_not_found") end + + it "does not mark the deployment run as failed when the failure is retryable" do + allow(providable_dbl).to receive(:submit_release).and_return(GitHub::Result.new { raise retryable_error }) + described_class.submit_for_review!(run) + + expect(run.reload.failed?).to be(false) + expect(run.reload.failure_reason).to eq("attachment_upload_in_progress") + end end end