fastlane-plugin-firebase_app_distribution 0.8.1 → 0.9.0.pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e6ae8a63559822e0869de05d3b6239991ef11e137cfcaab8632bfcb5ebc131b
4
- data.tar.gz: b4cc1e7840dc3a8a4b42bfeafa0da86d2ef6c6d2520dec19d1ac00bcb85a93f8
3
+ metadata.gz: 8db732cbcfd1540ca1762091006f5699b0f95c7daadf8a61e8d23b829a4f7203
4
+ data.tar.gz: fcbf5d87251a00ed68b3185871cc4999813e84bcd57540d5627633075a1658af
5
5
  SHA512:
6
- metadata.gz: c0ad2e974069de4be2bf38ca52f0d4c8d2a5569bb2e2673332207be9d417dd8aaf779bddf34ee04eb8b78e612a26d02a5c74668be6fc590b06470c60274a6f3d
7
- data.tar.gz: 50bd7ff6e1fef81db8a695f5e3c6239c0170842efb0db85c0e025f9362c5b47ded84b555718cfb661e14952c44725b33fb9af2f49a6321e7e5e1cd546f9806f9
6
+ metadata.gz: ca7ea18c1b4aeb7629e5fead3b71688a07cc856d21cfaa6eaac2439ff10b6d2109cc2f2bc22e376122448f652e7c2507619c06f815aabfc65a1e1c52f3db042f
7
+ data.tar.gz: 67411b623cfd368c0105409ba63b33d18d4e77ba78cd5248d8b39187774343e39237f780a4ddcee27ed446cdb588f273dc4f99caaf49c3f170b4b7c94e36a024
@@ -22,6 +22,8 @@ module Fastlane
22
22
  DEFAULT_UPLOAD_TIMEOUT_SECONDS = 300
23
23
  UPLOAD_MAX_POLLING_RETRIES = 60
24
24
  UPLOAD_POLLING_INTERVAL_SECONDS = 5
25
+ TEST_MAX_POLLING_RETRIES = 40
26
+ TEST_POLLING_INTERVAL_SECONDS = 30
25
27
 
26
28
  def self.run(params)
27
29
  params.values # to validate all inputs before looking for the ipa/apk/aab
@@ -37,11 +39,13 @@ module Fastlane
37
39
  binary_type = binary_type_from_path(binary_path)
38
40
 
39
41
  # TODO(lkellogg): This sets the send timeout for all POST requests made by the client, but
40
- # ideally the timeout should only apply to the binary upload
42
+ # ideally the timeout should only apply to the binary upload
41
43
  init_google_api_client(params[:debug], timeout)
42
44
  authorization = get_authorization(params[:service_credentials_file], params[:firebase_cli_token], params[:service_credentials_json_data], params[:debug])
43
45
  client = Google::Apis::FirebaseappdistributionV1::FirebaseAppDistributionService.new
44
46
  client.authorization = authorization
47
+ alpha_client = Google::Apis::FirebaseappdistributionV1alpha::FirebaseAppDistributionService.new
48
+ alpha_client.authorization = authorization
45
49
 
46
50
  # If binary is an AAB, get the AAB info for this app, which includes the integration state
47
51
  # and certificate data
@@ -80,6 +84,16 @@ module Fastlane
80
84
  release = update_release(client, release)
81
85
  end
82
86
 
87
+ test_devices =
88
+ get_value_from_value_or_file(params[:test_devices], params[:test_devices_file])
89
+ if present?(test_devices)
90
+ UI.message("🤖 Starting automated tests. Note: This feature is in beta.")
91
+ release_test = test_release(alpha_client, release, test_devices, params[:test_username], params[:test_password], params[:test_username_resource], params[:test_password_resource])
92
+ unless params[:test_async]
93
+ poll_test_finished(alpha_client, release_test.name)
94
+ end
95
+ end
96
+
83
97
  testers = get_value_from_value_or_file(params[:testers], params[:testers_file])
84
98
  groups = get_value_from_value_or_file(params[:groups], params[:groups_file])
85
99
  emails = string_to_array(testers)
@@ -260,7 +274,7 @@ module Fastlane
260
274
  # it should return a long running operation object, so we make a
261
275
  # standard http call instead and convert it to a long running object
262
276
  # https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-firebaseappdistribution_v1/lib/google/apis/firebaseappdistribution_v1/service.rb#L79
263
- # TODO(kbolay) Prefer client.upload_medium
277
+ # TODO(kbolay): Prefer client.upload_medium
264
278
  response = client.http(
265
279
  :post,
266
280
  "https://firebaseappdistribution.googleapis.com/upload/v1/#{app_name}/releases:upload",
@@ -318,6 +332,99 @@ module Fastlane
318
332
  end
319
333
  end
320
334
 
335
+ def self.test_release(alpha_client, release, test_devices, username = nil, password = nil, username_resource = nil, password_resource = nil)
336
+ if username_resource.nil? ^ password_resource.nil?
337
+ UI.user_error!("Username and password resource names for automated tests need to be specified together.")
338
+ end
339
+ field_hints = nil
340
+ if !username_resource.nil? && !password_resource.nil?
341
+ field_hints =
342
+ Google::Apis::FirebaseappdistributionV1alpha::GoogleFirebaseAppdistroV1alphaLoginCredentialFieldHints.new(
343
+ username_resource_name: username_resource,
344
+ password_resource_name: password_resource
345
+ )
346
+ end
347
+
348
+ if username.nil? ^ password.nil?
349
+ UI.user_error!("Username and password for automated tests need to be specified together.")
350
+ end
351
+ login_credential = nil
352
+ if !username.nil? && !password.nil?
353
+ login_credential =
354
+ Google::Apis::FirebaseappdistributionV1alpha::GoogleFirebaseAppdistroV1alphaLoginCredential.new(
355
+ username: username,
356
+ password: password,
357
+ field_hints: field_hints
358
+ )
359
+ else
360
+ unless field_hints.nil?
361
+ UI.user_error!("Must specify username and password for automated tests if resource names are set.")
362
+ end
363
+ end
364
+
365
+ device_executions = string_to_array(test_devices, ';').map do |td_string|
366
+ td_hash = parse_test_device_string(td_string)
367
+ Google::Apis::FirebaseappdistributionV1alpha::GoogleFirebaseAppdistroV1alphaDeviceExecution.new(
368
+ device: Google::Apis::FirebaseappdistributionV1alpha::GoogleFirebaseAppdistroV1alphaTestDevice.new(
369
+ model: td_hash['model'],
370
+ version: td_hash['version'],
371
+ orientation: td_hash['orientation'],
372
+ locale: td_hash['locale']
373
+ )
374
+ )
375
+ end
376
+
377
+ release_test =
378
+ Google::Apis::FirebaseappdistributionV1alpha::GoogleFirebaseAppdistroV1alphaReleaseTest.new(
379
+ login_credential: login_credential,
380
+ device_executions: device_executions
381
+ )
382
+ alpha_client.create_project_app_release_test(release.name, release_test)
383
+ rescue Google::Apis::Error => err
384
+ UI.crash!(err)
385
+ end
386
+
387
+ def self.poll_test_finished(alpha_client, release_test_name)
388
+ TEST_MAX_POLLING_RETRIES.times do
389
+ UI.message("⏳ The automated test results are pending.")
390
+ sleep(TEST_POLLING_INTERVAL_SECONDS)
391
+ release_test = alpha_client.get_project_app_release_test(release_test_name)
392
+ if release_test.device_executions.all? { |e| e.state == 'PASSED' }
393
+ UI.success("✅ Passed automated test(s).")
394
+ return
395
+ end
396
+ release_test.device_executions.each do |de|
397
+ case de.state
398
+ when 'PASSED', 'IN_PROGRESS'
399
+ next
400
+ when 'FAILED'
401
+ UI.test_failure!("Automated test failed for #{device_to_s(de.device)}: #{de.failed_reason}.")
402
+ when 'INCONCLUSIVE'
403
+ UI.test_failure!("Automated test inconclusive for #{device_to_s(de.device)}: #{de.inconclusive_reason}.")
404
+ else
405
+ UI.test_failure!("Unsupported automated test state for #{device_to_s(de.device)}: #{de.state}.")
406
+ end
407
+ end
408
+ end
409
+ UI.test_failure!("It took longer than expected to process your test, please try again.")
410
+ end
411
+
412
+ def self.parse_test_device_string(td_string)
413
+ allowed_keys = %w[model version locale orientation]
414
+ key_value_pairs = td_string.split(',').map do |key_value_string|
415
+ key, value = key_value_string.split('=')
416
+ unless allowed_keys.include?(key)
417
+ UI.user_error!("Unrecognized key in test_devices. Can only contain keys #{allowed_keys.join(', ')}.")
418
+ end
419
+ [key, value]
420
+ end
421
+ Hash[key_value_pairs]
422
+ end
423
+
424
+ def self.device_to_s(device)
425
+ "#{device.model} (#{device.version}/#{device.orientation}/#{device.locale})"
426
+ end
427
+
321
428
  def self.available_options
322
429
  [
323
430
  # iOS Specific
@@ -358,7 +465,7 @@ module Fastlane
358
465
  FastlaneCore::ConfigItem.new(key: :firebase_cli_path,
359
466
  deprecated: "This plugin no longer uses the Firebase CLI",
360
467
  env_name: "FIREBASEAPPDISTRO_FIREBASE_CLI_PATH",
361
- description: "The absolute path of the firebase cli command",
468
+ description: "Absolute path of the Firebase CLI command",
362
469
  type: String),
363
470
  FastlaneCore::ConfigItem.new(key: :debug,
364
471
  description: "Print verbose debug output",
@@ -374,7 +481,7 @@ module Fastlane
374
481
  type: Integer),
375
482
  FastlaneCore::ConfigItem.new(key: :groups,
376
483
  env_name: "FIREBASEAPPDISTRO_GROUPS",
377
- description: "The group aliases used for distribution, separated by commas",
484
+ description: "Group aliases used for distribution, separated by commas",
378
485
  optional: true,
379
486
  type: String),
380
487
  FastlaneCore::ConfigItem.new(key: :groups_file,
@@ -403,6 +510,39 @@ module Fastlane
403
510
  optional: true,
404
511
  type: String),
405
512
 
513
+ # Release Testing
514
+ FastlaneCore::ConfigItem.new(key: :test_devices,
515
+ env_name: "FIREBASEAPPDISTRO_TEST_DEVICES",
516
+ description: "List of devices to run automated tests on, in the format 'model=<model-id>,version=<os-version-id>,locale=<locale>,orientation=<orientation>;model=<model-id>,...'. Run 'gcloud firebase test android|ios models list' to see available devices. Note: This feature is in beta.",
517
+ optional: true,
518
+ type: String),
519
+ FastlaneCore::ConfigItem.new(key: :test_devices_file,
520
+ env_name: "FIREBASEAPPDISTRO_TEST_DEVICES_FILE",
521
+ description: "Path to file containing a list of devices to run automated tests on, in the format 'model=<model-id>,version=<os-version-id>,locale=<locale>,orientation=<orientation>;model=<model-id>,...'. Run 'gcloud firebase test android|ios models list' to see available devices. Note: This feature is in beta.",
522
+ optional: true,
523
+ type: String),
524
+ FastlaneCore::ConfigItem.new(key: :test_username,
525
+ description: "Username for automatic login",
526
+ optional: true,
527
+ type: String),
528
+ FastlaneCore::ConfigItem.new(key: :test_password,
529
+ description: "Password for automatic login",
530
+ optional: true,
531
+ type: String),
532
+ FastlaneCore::ConfigItem.new(key: :test_username_resource,
533
+ description: "Resource name for the username field for automatic login",
534
+ optional: true,
535
+ type: String),
536
+ FastlaneCore::ConfigItem.new(key: :test_password_resource,
537
+ description: "Resource name for the password field for automatic login",
538
+ optional: true,
539
+ type: String),
540
+ FastlaneCore::ConfigItem.new(key: :test_async,
541
+ description: "Run tests asynchronously. Visit the Firebase console for the automatic test results.",
542
+ optional: false,
543
+ default_value: false,
544
+ type: Boolean),
545
+
406
546
  # Auth
407
547
  FastlaneCore::ConfigItem.new(key: :firebase_cli_token,
408
548
  description: "Auth token generated using the Firebase CLI's login:ci command",
@@ -432,7 +572,8 @@ module Fastlane
432
572
  <<-CODE
433
573
  firebase_app_distribution(
434
574
  app: "<your Firebase app ID>",
435
- testers: "snatchev@google.com, rebeccahe@google.com"
575
+ testers: "snatchev@google.com, rebeccahe@google.com",
576
+ test_devices: "model=shiba,version=34,locale=en,orientation=portrait;model=b0q,version=33,locale=en,orientation=portrait",
436
577
  )
437
578
  CODE
438
579
  ]
@@ -27,10 +27,10 @@ module Fastlane
27
27
 
28
28
  # Returns the array representation of a string with trimmed comma
29
29
  # seperated values.
30
- def string_to_array(string)
30
+ def string_to_array(string, delimiter = ",")
31
31
  return [] if string.nil?
32
32
  # Strip string and then strip individual values
33
- string.strip.split(",").map(&:strip)
33
+ string.strip.split(delimiter).map(&:strip)
34
34
  end
35
35
 
36
36
  def parse_plist(path)
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module FirebaseAppDistribution
3
- VERSION = "0.8.1"
3
+ VERSION = "0.9.0.pre.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-firebase_app_distribution
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0.pre.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Natchev
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-01-15 00:00:00.000000000 Z
13
+ date: 2024-01-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: google-apis-firebaseappdistribution_v1