Skip to content

Commit 7157246

Browse files
authored
Added configurable upload timeout to firebase_app_distribution_action (#287)
* Added configurable upload timeout to firebase_app_distribution_action * Bump version to 0.3.8.
1 parent 7500c18 commit 7157246

File tree

4 files changed

+43
-23
lines changed

4 files changed

+43
-23
lines changed

lib/fastlane/plugin/firebase_app_distribution/actions/firebase_app_distribution_action.rb

+19-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class FirebaseAppDistributionAction < Action
1515
extend Auth::FirebaseAppDistributionAuthClient
1616
extend Helper::FirebaseAppDistributionHelper
1717

18+
DEFAULT_UPLOAD_TIMEOUT_SECONDS = 300
19+
1820
def self.run(params)
1921
params.values # to validate all inputs before looking for the ipa/apk/aab
2022

@@ -42,7 +44,9 @@ def self.run(params)
4244
validate_aab_setup!(aab_info)
4345
end
4446

45-
release_name = fad_api_client.upload(app_name, binary_path, platform.to_s)
47+
upload_timeout = get_upload_timeout(params)
48+
49+
release_name = fad_api_client.upload(app_name, binary_path, platform.to_s, upload_timeout)
4650

4751
if binary_type == :AAB && aab_info && !aab_info.certs_provided?
4852
updated_aab_info = fad_api_client.get_aab_info(app_name)
@@ -135,6 +139,14 @@ def self.get_binary_path(platform, params)
135139
end
136140
end
137141

142+
def self.get_upload_timeout(params)
143+
if params[:upload_timeout]
144+
return params[:upload_timeout]
145+
else
146+
return DEFAULT_UPLOAD_TIMEOUT_SECONDS
147+
end
148+
end
149+
138150
def self.validate_aab_setup!(aab_info)
139151
if aab_info && aab_info.integration_state != AabInfo::AabState::INTEGRATED && aab_info.integration_state != AabInfo::AabState::UNAVAILABLE
140152
case aab_info.integration_state
@@ -242,7 +254,12 @@ def self.available_options
242254
FastlaneCore::ConfigItem.new(key: :service_credentials_file,
243255
description: "Path to Google service account json",
244256
optional: true,
245-
type: String)
257+
type: String),
258+
FastlaneCore::ConfigItem.new(key: :upload_timeout,
259+
description: "The amount of seconds before the upload will timeout, if not completed",
260+
optional: true,
261+
default_value: DEFAULT_UPLOAD_TIMEOUT_SECONDS,
262+
type: Integer)
246263
]
247264
end
248265

lib/fastlane/plugin/firebase_app_distribution/client/firebase_app_distribution_api_client.rb

+6-4
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,12 @@ def get_aab_info(app_name)
106106
# app_name - Firebase App resource name
107107
# binary_path - Absolute path to your app's aab/apk/ipa file
108108
# platform - 'android' or 'ios'
109+
# timeout - The amount of seconds before the upload will timeout, if not completed
109110
#
110111
# Throws a user_error if the binary file does not exist
111-
def upload_binary(app_name, binary_path, platform)
112+
def upload_binary(app_name, binary_path, platform, timeout)
112113
response = connection.post(binary_upload_url(app_name), read_binary(binary_path)) do |request|
113-
request.options.timeout = 300 # seconds
114+
request.options.timeout = timeout # seconds
114115
request.headers[AUTHORIZATION] = "Bearer " + @auth_token
115116
request.headers[CONTENT_TYPE] = APPLICATION_OCTET_STREAM
116117
request.headers[CLIENT_VERSION] = client_version_header_value
@@ -130,16 +131,17 @@ def upload_binary(app_name, binary_path, platform)
130131
# args
131132
# app_name - Firebase App resource name
132133
# binary_path - Absolute path to your app's aab/apk/ipa file
134+
# timeout - The amount of seconds before the upload will timeout, if not completed
133135
#
134136
# Returns the release_name of the uploaded release.
135137
#
136138
# Crashes if the number of polling retries exceeds MAX_POLLING_RETRIES or if the binary cannot
137139
# be uploaded.
138-
def upload(app_name, binary_path, platform)
140+
def upload(app_name, binary_path, platform, timeout)
139141
binary_type = binary_type_from_path(binary_path)
140142

141143
UI.message("⌛ Uploading the #{binary_type}.")
142-
operation_name = upload_binary(app_name, binary_path, platform)
144+
operation_name = upload_binary(app_name, binary_path, platform, timeout)
143145

144146
upload_status_response = get_upload_status(operation_name)
145147
MAX_POLLING_RETRIES.times do
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Fastlane
22
module FirebaseAppDistribution
3-
VERSION = "0.3.7"
3+
VERSION = "0.3.8"
44
end
55
end

spec/firebase_app_distribution_api_client_spec.rb

+17-16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
let(:fake_binary_contents) { "Hello World" }
88
let(:fake_binary) { double("Binary") }
99
let(:headers) { { 'Authorization' => 'Bearer auth_token' } }
10+
let(:upload_timeout) { 300 }
1011

1112
let(:api_client) { Fastlane::Client::FirebaseAppDistributionApiClient.new("auth_token") }
1213
let(:stubs) { Faraday::Adapter::Test::Stubs.new }
@@ -105,14 +106,14 @@
105106
}
106107
]
107108
end
108-
api_client.upload_binary(app_name, fake_binary_path, "android")
109+
api_client.upload_binary(app_name, fake_binary_path, "android", upload_timeout)
109110
end
110111

111112
it 'crashes when given an invalid binary_path' do
112113
expect(File).to receive(:open)
113114
.with("invalid_binary.apk", "rb")
114115
.and_raise(Errno::ENOENT.new("file not found"))
115-
expect { api_client.upload_binary(app_name, "invalid_binary.apk", "android") }
116+
expect { api_client.upload_binary(app_name, "invalid_binary.apk", "android", upload_timeout) }
116117
.to raise_error("#{ErrorMessage.binary_not_found('APK')}: invalid_binary.apk")
117118
end
118119
end
@@ -185,7 +186,7 @@
185186

186187
it 'uploads the app binary then returns the release name' do
187188
expect(api_client).to receive(:upload_binary)
188-
.with(app_name, fake_binary_path, "android")
189+
.with(app_name, fake_binary_path, "android", upload_timeout)
189190
.and_return(operation_name)
190191
.at_most(:once)
191192
expect(api_client).to receive(:get_upload_status)
@@ -197,13 +198,13 @@
197198
.and_return(upload_status_response_success)
198199
.at_most(:once)
199200

200-
result = api_client.upload(app_name, fake_binary_path, "android")
201+
result = api_client.upload(app_name, fake_binary_path, "android", upload_timeout)
201202
expect(result).to eq(release_name)
202203
end
203204

204205
it 'uploads the app binary for an existing unmodified binary' do
205206
expect(api_client).to receive(:upload_binary)
206-
.with(app_name, fake_binary_path, "android")
207+
.with(app_name, fake_binary_path, "android", upload_timeout)
207208
.and_return(operation_name)
208209
.at_most(:once)
209210
expect(api_client).to receive(:get_upload_status)
@@ -215,13 +216,13 @@
215216
.and_return(upload_status_response_release_unmodified)
216217
.at_most(:once)
217218

218-
result = api_client.upload(app_name, fake_binary_path, "android")
219+
result = api_client.upload(app_name, fake_binary_path, "android", upload_timeout)
219220
expect(result).to eq(release_name)
220221
end
221222

222223
it 'uploads the app binary for an existing updated binary' do
223224
expect(api_client).to receive(:upload_binary)
224-
.with(app_name, fake_binary_path, "android")
225+
.with(app_name, fake_binary_path, "android", upload_timeout)
225226
.and_return(operation_name)
226227
.at_most(:once)
227228
expect(api_client).to receive(:get_upload_status)
@@ -233,7 +234,7 @@
233234
.and_return(upload_status_response_release_updated)
234235
.at_most(:once)
235236

236-
result = api_client.upload(app_name, fake_binary_path, "android")
237+
result = api_client.upload(app_name, fake_binary_path, "android", upload_timeout)
237238
expect(result).to eq(release_name)
238239
end
239240

@@ -242,15 +243,15 @@
242243
stub_const("Fastlane::Client::FirebaseAppDistributionApiClient::MAX_POLLING_RETRIES", max_polling_retries)
243244

244245
expect(api_client).to receive(:upload_binary)
245-
.with(app_name, fake_binary_path, "android")
246+
.with(app_name, fake_binary_path, "android", upload_timeout)
246247
.and_return(operation_name)
247248
expect(api_client).to receive(:get_upload_status)
248249
.with(operation_name)
249250
.and_return(upload_status_response_in_progress)
250251
.exactly(max_polling_retries + 1).times # adding 1 for initial call
251252

252253
expect do
253-
api_client.upload(app_name, fake_binary_path, "android")
254+
api_client.upload(app_name, fake_binary_path, "android", upload_timeout)
254255
end.to raise_error
255256
end
256257

@@ -259,7 +260,7 @@
259260
stub_const("Fastlane::Client::FirebaseAppDistributionApiClient::MAX_POLLING_RETRIES", max_polling_retries)
260261

261262
expect(api_client).to receive(:upload_binary)
262-
.with(app_name, fake_binary_path, "android")
263+
.with(app_name, fake_binary_path, "android", upload_timeout)
263264
.and_return(operation_name)
264265
.at_most(:once)
265266
# return in_progress for a couple polls
@@ -271,33 +272,33 @@
271272
.with(operation_name)
272273
.and_return(upload_status_response_success)
273274

274-
result = api_client.upload(app_name, fake_binary_path, "android")
275+
result = api_client.upload(app_name, fake_binary_path, "android", upload_timeout)
275276
expect(result).to eq(release_name)
276277
end
277278

278279
it 'crashes after failing to upload with status error' do
279280
expect(api_client).to receive(:upload_binary)
280-
.with(app_name, fake_binary_path, "android")
281+
.with(app_name, fake_binary_path, "android", upload_timeout)
281282
.and_return(operation_name)
282283
expect(api_client).to receive(:get_upload_status)
283284
.with(operation_name)
284285
.and_return(upload_status_response_error)
285286
.at_most(:once)
286287

287-
expect { api_client.upload(app_name, fake_binary_path, "android") }
288+
expect { api_client.upload(app_name, fake_binary_path, "android", upload_timeout) }
288289
.to raise_error("#{ErrorMessage.upload_binary_error('APK')}: #{upload_status_response_error.error_message}")
289290
end
290291

291292
it 'crashes after failing to upload with status unspecified' do
292293
expect(api_client).to receive(:upload_binary)
293-
.with(app_name, fake_binary_path, "android")
294+
.with(app_name, fake_binary_path, "android", upload_timeout)
294295
.and_return(operation_name)
295296
expect(api_client).to receive(:get_upload_status)
296297
.with(operation_name)
297298
.and_return(upload_status_response_status_unspecified)
298299
.at_most(:once)
299300

300-
expect { api_client.upload(app_name, fake_binary_path, "android") }
301+
expect { api_client.upload(app_name, fake_binary_path, "android", upload_timeout) }
301302
.to raise_error(ErrorMessage.upload_binary_error("APK"))
302303
end
303304
end

0 commit comments

Comments
 (0)