Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
bd7d602
Add Android Firebase Action + Helper
jkmassel Apr 5, 2022
f866e66
Move Firebase Device out of the Helper
jkmassel Apr 6, 2022
848c0ae
Move log file parsing out of the FirebaseHelper
jkmassel May 2, 2022
928613f
Add CHANGELOG note
jkmassel May 2, 2022
c52bcff
Cleanup
jkmassel May 2, 2022
e49b930
Apply suggestions from code review
jkmassel May 17, 2022
66f3e65
Fix tests
jkmassel May 17, 2022
372ad20
Don’t authenticate in constructor
jkmassel May 17, 2022
0deed47
Verify gcloud binary on FirebaseTestRunner.new
jkmassel May 17, 2022
77e180f
Make CI happy
jkmassel May 17, 2022
5ac5225
Remove the explicit verify_has_gloud_binary call
jkmassel May 17, 2022
c659f02
Simplify more_details_url
jkmassel May 17, 2022
23870c0
Simplify raw_results_paths
jkmassel May 17, 2022
7ac5002
Adjust `require`
jkmassel May 17, 2022
9dc580e
Add docs
jkmassel May 17, 2022
ff89bd0
Fix broken success? method
jkmassel May 17, 2022
d7b73c5
Fix `passed?`
jkmassel May 24, 2022
c6a8f2c
Fix Google Cloud Storage gem pinning
jkmassel May 24, 2022
8e16c7b
Apply suggestions from code review
jkmassel May 24, 2022
14eed21
Fix tests
jkmassel May 24, 2022
bd7395e
Simplify parameters
jkmassel May 24, 2022
3267537
Indentation Fix
jkmassel May 24, 2022
b99126a
Fix an oops
jkmassel May 24, 2022
1c1a8bc
Re-add default_value_dynamic
jkmassel May 24, 2022
8ab2031
Fix unclear errors when gcloud binary missing
jkmassel May 24, 2022
9ba5d34
Escape all the things
jkmassel May 24, 2022
5d15b3a
Improve Firebase Test Runner Errors
jkmassel May 24, 2022
85b0df0
Remove constants
jkmassel May 24, 2022
5b46778
Fix lint issues
jkmassel May 25, 2022
fdb177c
Merge remote-tracking branch 'origin/trunk' into add/firebase-tests
jkmassel Jun 1, 2022
839be18
Merge remote-tracking branch 'origin/trunk' into add/firebase-tests
jkmassel Jul 1, 2022
f1e3128
Fix rubocop error
jkmassel Jul 1, 2022
d9536de
Document the `env_name`
jkmassel Jul 1, 2022
08bc2c0
Remove key file environment variable setting
jkmassel Jul 1, 2022
7826e23
Improve argument documentation
jkmassel Jul 1, 2022
1b789ce
Avoid double escaping
jkmassel Jul 1, 2022
46e3825
Apply suggestions from code review
jkmassel Jul 1, 2022
913578a
Fix crashes
AliSoftware Jul 4, 2022
20ae178
Check params early to avoid late prompts
AliSoftware Jul 11, 2022
febebef
Add Action Validation Tests
jkmassel Jul 15, 2022
75a8d41
Fix params
jkmassel Jul 15, 2022
8e7c274
Add Firebase Login Action
jkmassel Jul 16, 2022
fb136d0
Remove login logic from Firebase_Test Action
jkmassel Jul 16, 2022
6db3296
Put back key file parameter
jkmassel Jul 16, 2022
a660c60
Make FirebaseTestRunner static
jkmassel Jul 16, 2022
495b038
Manually specify the project_id field
jkmassel Jul 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Metrics/ClassLength:
Max: 300

Metrics/MethodLength:
Max: 100
Max: 150

Metrics/ModuleLength:
Max: 300
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
### New Features

* Introduce new `ios_send_app_size_metrics` and `android_send_app_size_metrics` actions. [#364] [#365]
* Add the ability to run Firebase Test Lab tests. [#355]

### Bug Fixes

Expand Down
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ PATH
chroma (= 0.2.0)
diffy (~> 3.3)
git (~> 1.3)
google-cloud-storage (~> 1.31)
jsonlint (~> 0.3)
nokogiri (~> 1.11)
octokit (~> 4.18)
Expand Down
4 changes: 4 additions & 0 deletions fastlane-plugin-wpmreleasetoolkit.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Gem::Specification.new do |spec|
spec.add_dependency 'progress_bar', '~> 1.3'
spec.add_dependency 'rake', '>= 12.3', '< 14.0'
spec.add_dependency 'rake-compiler', '~> 1.0'

# `google-cloud-storage` is required by fastlane, but we pin it in case it's not in the future
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

spec.add_dependency 'google-cloud-storage', '~> 1.31'

# Some of the upstream code uses `BigDecimal.new` which version 2.0 of the
# `bigdecimal` gem removed. Until we'll find the time to identify the
# dependencies and see if we can move them to something compatible with
Expand Down
4 changes: 2 additions & 2 deletions lib/fastlane/plugin/wpmreleasetoolkit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

module Fastlane
module Wpmreleasetoolkit
# Return all .rb files inside the "actions" and "helper" directory
# Return all .rb files inside the "actions", "helper" and "models" directories
def self.all_classes
Dir[File.expand_path('**/{actions,helper}/**/*.rb', File.dirname(__FILE__))]
Dir[File.expand_path('**/{actions,helper,models}/**/*.rb', File.dirname(__FILE__))]
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
require 'securerandom'

module Fastlane
module Actions
module SharedValues
FIREBASE_TEST_RESULT = :FIREBASE_TEST_LOG_FILE
FIREBASE_TEST_LOG_FILE_PATH = :FIREBASE_TEST_LOG_FILE_PATH
end

class AndroidFirebaseTestAction < Action
def self.run(params)
validate_options(params)

UI.user_error!('You must be logged in to Firebase prior to calling this action. Use the `FirebaseLogin` Action to log in if needed') unless Fastlane::FirebaseAccount.authenticated?

# Log in to Firebase (and validate credentials)
run_uuid = params[:test_run_id] || SecureRandom.uuid
test_dir = params[:results_output_dir] || File.join(Dir.tmpdir(), run_uuid)

# Set up the log file and output directory
FileUtils.mkdir_p(test_dir)
Fastlane::Actions.lane_context[:FIREBASE_TEST_LOG_FILE_PATH] = File.join(test_dir, 'output.log')

device = Fastlane::FirebaseDevice.new(
model: params[:model],
version: params[:version],
locale: params[:locale],
orientation: params[:orientation]
)

result = FirebaseTestRunner.run_tests(
project_id: params[:project_id],
apk_path: params[:apk_path],
test_apk_path: params[:test_apk_path],
device: device,
type: params[:type]
)

# Download all of the outputs from the job to the local machine
FirebaseTestRunner.download_result_files(
result: result,
destination: test_dir,
project_id: params[:project_id],
key_file_path: params[:key_file]
)

FastlaneCore::UI.test_failure! "Firebase Tests failed – more information can be found at #{result.more_details_url}" unless result.success?

UI.success 'Firebase Tests Complete'
end

# Fastlane doesn't eagerly validate options for us, so we'll do it first to have control over
# when they're evalutated.
def self.validate_options(params)
available_options
.reject { |opt| opt.optional || !opt.default_value.nil? }
.map(&:key)
.each { |k| params[k] }
end

#####################################################
# @!group Documentation
#####################################################

def self.description
'Runs the specified tests in Firebase Test Lab'
end

def self.details
description
end

def self.available_options
[
FastlaneCore::ConfigItem.new(
key: :project_id,
# `env_name` comes from the Google Cloud default: https://cloud.google.com/functions/docs/configuring/env-var
env_name: 'GCP_PROJECT',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming there is a rationale behind choosing that specific env_name rather than following the more common naming pattern for config items like ANDROID_FIREBASE_TEST_PROJECT_ID… like, this is a typical environment variable that is usually set in client projects for other reasons / tools to pick up?

If that's the rationale (this env var name being some standard used by other stuff as well), then you should probably add a # comment to mention it, so that if there's a reason then we'd not tempted to normalize that env_name later and break things.

If it's not (i.e. it's just that the client app you want to test this action with first happens to have that env var set, but for legacy reasons with some old tooling which won't be relevant anymore, and thus no hard reason to keep that name), you might as well change this to try to follow our usual naming conventions of the env var (even if that means that you'll explicitly pass project_id: ENV['GCP_PROJECT'] at call site for this client app, or rename the env var in the client repo)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in d9536de

description: 'The Project ID to test in',
type: String
),
FastlaneCore::ConfigItem.new(
key: :key_file,
description: 'The key file used to authorize with Google Cloud',
type: String,
verify_block: proc do |value|
UI.user_error!('The `:key_file` parameter is required') if value.empty?
UI.user_error!("No Google Cloud Key file found at: #{value}") unless File.exist?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :apk_path,
description: 'Path to the application APK on the local machine',
type: String,
verify_block: proc do |value|
UI.user_error!('The `:apk_path` parameter is required') if value.empty?
UI.user_error!("Invalid application APK: #{value}") unless File.exist?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :test_apk_path,
description: 'Path to the test bundle APK on the local machine',
type: String,
verify_block: proc do |value|
UI.user_error!('The `:test_apk_path` parameter is required') if value.empty?
UI.user_error!("Invalid test APK: #{value}") unless File.exist?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :model,
description: 'The device model to use to run the test',
type: String,
verify_block: proc do |value|
UI.user_error!('The `:model` parameter is required') if value.empty?
FirebaseTestRunner.verify_has_gcloud_binary!
model_names = Fastlane::FirebaseDevice.valid_model_names
UI.user_error!("Invalid Model Name: #{value}. Valid Model Names: #{model_names}") unless model_names.include?(value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user_error doesn't seem to show (and thus list the available models) when run on CI and we pass an invalid model — see example here. It just says the parameter has been passed invalid value but the message above doesn't show on the logs, so that is not super helpful 😒

  | [2022-07-04T16:30:17Z] [16:30:17]: ▸ BUILD SUCCESSFUL in 12m 56s
  | [2022-07-04T16:30:17Z] [16:30:17]: ▸ 94 actionable tasks: 86 executed, 8 from cache
  | [2022-07-04T16:30:17Z] [16:30:17]: ▸ Publishing build scan...
  | [2022-07-04T16:30:17Z] [16:30:17]: ▸ https://gradle.a8c.com/s/wz445ksdkrrek
  | [2022-07-04T16:30:19Z] [16:30:19]: Error setting value 'Nexus5' for option 'model'
  | [2022-07-04T16:30:19Z] [16:30:19]: You passed invalid parameters to 'android_firebase_test'.
  | [2022-07-04T16:30:19Z] [16:30:19]: Check out the error below and available options by running `fastlane action android_firebase_test`
  | [2022-07-04T16:30:19Z] +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | [2022-07-04T16:30:19Z] \|                                                                                                                                                                                                       Lane Context                                                                                                                                                                                                       \|
  | [2022-07-04T16:30:19Z] +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | [2022-07-04T16:30:19Z] \| DEFAULT_PLATFORM                    \| android                                                                                                                                                                                                                                                                                                                                                                            \|
  | [2022-07-04T16:30:19Z] \| PLATFORM_NAME                       \| android                                                                                                                                                                                                                                                                                                                                                                            \|
  | [2022-07-04T16:30:19Z] \| LANE_NAME                           \| android build_and_instrumented_test                                                                                                                                                                                                                                                                                                                                                \|
  | [2022-07-04T16:30:19Z] \| GRADLE_ALL_APK_OUTPUT_PATHS         \| ["/var/lib/buildkite-agent/builds/ci-android-i-04a64e2244229b61c-1/automattic/woocommerce-android/WooCommerce/build/outputs/apk/vanilla/debug/WooCommerce-vanilla-debug.apk", "/var/lib/buildkite-agent/builds/ci-android-i-04a64e2244229b61c-1/automattic/woocommerce-android/WooCommerce/build/outputs/apk/androidTest/vanilla/debug/WooCommerce-vanilla-debug-androidTest.apk"] \|
  | [2022-07-04T16:30:19Z] \| GRADLE_ALL_AAB_OUTPUT_PATHS         \| []                                                                                                                                                                                                                                                                                                                                                                                 \|
  | [2022-07-04T16:30:19Z] \| GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS \| ["/var/lib/buildkite-agent/builds/ci-android-i-04a64e2244229b61c-1/automattic/woocommerce-android/WooCommerce/build/outputs/apk/vanilla/debug/output-metadata.json", "/var/lib/buildkite-agent/builds/ci-android-i-04a64e2244229b61c-1/automattic/woocommerce-android/WooCommerce/build/outputs/apk/androidTest/vanilla/debug/output-metadata.json"]                               \|
  | [2022-07-04T16:30:19Z] \| GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS \| []                                                                                                                                                                                                                                                                                                                                                                                 \|
  | [2022-07-04T16:30:19Z] \| GRADLE_APK_OUTPUT_PATH              \| /var/lib/buildkite-agent/builds/ci-android-i-04a64e2244229b61c-1/automattic/woocommerce-android/WooCommerce/build/outputs/apk/androidTest/vanilla/debug/WooCommerce-vanilla-debug-androidTest.apk                                                                                                                                                                                  \|
  | [2022-07-04T16:30:19Z] \| GRADLE_OUTPUT_JSON_OUTPUT_PATH      \| /var/lib/buildkite-agent/builds/ci-android-i-04a64e2244229b61c-1/automattic/woocommerce-android/WooCommerce/build/outputs/apk/androidTest/vanilla/debug/output-metadata.json                                                                                                                                                                                                       \|
  | [2022-07-04T16:30:19Z] +-------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | [2022-07-04T16:30:19Z] [16:30:19]: Shell command exited with exit status 1 instead of 0.
  | [2022-07-04T16:30:20Z]
  | [2022-07-04T16:30:20Z] +------+------------------------------------------------------+-------------+
  | [2022-07-04T16:30:20Z] \|                             fastlane summary                              \|
  | [2022-07-04T16:30:20Z] +------+------------------------------------------------------+-------------+
  | [2022-07-04T16:30:20Z] \| Step \| Action                                               \| Time (in s) \|
  | [2022-07-04T16:30:20Z] +------+------------------------------------------------------+-------------+
  | [2022-07-04T16:30:20Z] \| 1    \| default_platform                                     \| 0           \|
  | [2022-07-04T16:30:20Z] \| 2    \| is_ci                                                \| 0           \|
  | [2022-07-04T16:30:20Z] \| 3    \| assembleVanillaDebug assembleVanillaDebugAndroidTest \| 777         \|
  | [2022-07-04T16:30:20Z] +------+------------------------------------------------------+-------------+
  | [2022-07-04T16:30:20Z]
  | [2022-07-04T16:30:20Z] [16:30:20]: fastlane finished with errors
  | [2022-07-04T16:30:20Z]
  | [2022-07-04T16:30:20Z] [!] Shell command exited with exit status 1 instead of 0.
  | [2022-07-04T16:30:20Z] 🚨 Error: The command exited with status 1
  | [2022-07-04T16:30:20Z] user command error: exit status 1

end
),
FastlaneCore::ConfigItem.new(
key: :version,
description: 'The Android version (API Level) to use to run the test',
type: Integer,
verify_block: proc do |value|
FirebaseTestRunner.verify_has_gcloud_binary!
version_numbers = Fastlane::FirebaseDevice.valid_version_numbers
UI.user_error!("Invalid Version Number: #{value}. Valid Version Numbers: #{version_numbers}") unless version_numbers.include?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :locale,
description: 'The locale code to use when running the test',
type: String,
default_value: 'en',
verify_block: proc do |value|
FirebaseTestRunner.verify_has_gcloud_binary!
locale_codes = Fastlane::FirebaseDevice.valid_locales
UI.user_error!("Invalid Locale: #{value}. Valid Locales: #{locale_codes}") unless locale_codes.include?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :orientation,
description: 'Which orientation to run the device in',
type: String,
default_value: 'portrait',
verify_block: proc do |value|
orientations = Fastlane::FirebaseDevice.valid_orientations
UI.user_error!("Invalid Orientation: #{value}. Valid Orientations: #{orientations}") unless orientations.include?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :type,
description: 'The type of test to run (e.g. `instrumentation` or `robo`)',
type: String,
default_value: 'instrumentation',
verify_block: proc do |value|
types = Fastlane::FirebaseTestRunner::VALID_TEST_TYPES
UI.user_error!("Invalid Test Type: #{value}. Valid Types: #{types}") unless types.include?(value)
end
),
FastlaneCore::ConfigItem.new(
key: :test_run_id,
description: 'A unique ID used to identify this test run',
default_value_dynamic: true,
optional: true,
type: String
),
FastlaneCore::ConfigItem.new(
key: :results_output_dir,
description: 'The path to the folder where we will store the results of this test run',
default_value_dynamic: true,
optional: true,
type: String
),
]
end

def self.authors
['Automattic']
end

def self.is_supported?(platform)
platform == :android
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ def self.details
DETAILS
end

# rubocop:disable Metrics/MethodLength
def self.available_options
[
FastlaneCore::ConfigItem.new(
Expand Down Expand Up @@ -259,7 +258,6 @@ def self.available_options
),
]
end
# rubocop:enable Metrics/MethodLength

def self.return_type
:integer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'securerandom'

module Fastlane
module Actions
class FirebaseLoginAction < Action
def self.run(params)
Fastlane::FirebaseAccount.activate_service_account_with_key_file(params[:key_file])
end

#####################################################
# @!group Documentation
#####################################################
def self.description
'Logs the local machine into Google Cloud using the provided key file'
end

def self.details
description
end

def self.available_options
[
FastlaneCore::ConfigItem.new(
key: :key_file,
description: 'The key file used to authorize with Google Cloud',
type: String,
verify_block: proc do |value|
UI.user_error!('The `:key_file` parameter is required') if value.empty?
UI.user_error!("No Google Cloud Key file found at: #{value}") unless File.exist?(value)
end
),
]
end

def self.authors
['Automattic']
end

def self.is_supported?(platform)
true
end
end
end
end
19 changes: 19 additions & 0 deletions lib/fastlane/plugin/wpmreleasetoolkit/models/firebase_account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Fastlane
class FirebaseAccount
def self.activate_service_account_with_key_file(key_file_path)
Fastlane::Actions.sh('gcloud', 'auth', 'activate-service-account', '--key-file', key_file_path)
end

def self.authenticated?
auth_status = JSON.parse(auth_status_data)
auth_status.any? do |account|
account['status'] == 'ACTIVE'
end
end

# Lookup the current account authentication status
def self.auth_status_data
Fastlane::Actions.sh('gcloud', 'auth', 'list', '--format', 'json', log: false)
end
end
end
62 changes: 62 additions & 0 deletions lib/fastlane/plugin/wpmreleasetoolkit/models/firebase_device.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
module Fastlane
class FirebaseDevice
attr_reader :model, :version, :locale, :orientation
Comment on lines +1 to +3
Copy link
Contributor

@AliSoftware AliSoftware May 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I really like that this was represented as a model class. We don't have many model classes in our release-toolkit right now so it's rare to see a good reason for having them, but this one was a good fit for it indeed 👌

I'm not a fan of this being defined directly at the root of the Fastlane namespace (i.e. what if in the future fastlane itself adds such a FirebaseDevice class?) Even though I know all our other existing classes in models/ already follow this pattern, that doesn't mean it was a good choice back then 😅 But maybe that's a refactor for another time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I worried about this for a moment as well – IMHO if that happens at some point we can address it then? I didn't want to bury it too deeply since it's a pain to reference a deeply-nested model object?

Copy link
Contributor

@AliSoftware AliSoftware May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I think we could also keep the idea in the back of our head for later to introduce a module WPMRT namespace for models at some point.

I worried about it for this old WIP as well, which might be even more at risk of clashing with something provided by fastlane given its more generic name… so maybe at that point create that WPMRT namespace then. Given yours is not introduced as public API (iinm), changing the internal namespace and thus fully-qualified name of that class later would not be a breaking change (unlike the LocaleHelper PR which is planned to be exposed publicly) so that's ok to keep it as is for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing the internal namespace and thus fully-qualified name of that class later would not be a breaking change

Yeah exactly – this was what had me thinking it'd make sense to leave it for the moment 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing we could consider at least doing though: put all the Firebase-related models under a models/firebase subdirectory, and use Fastlane::Firebase::Device instead of Fastlane::FirebaseDevice (and similar for the 2 others). (I think Rubymine can do such a refactor automatically accross the codebase…?)

Since those are models that all go together hand in hand that would make it clear and neat, and would make us ready for if we add more, unrelated model files for other unrelated things in the future, avoinding to put everything in the same bowl.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that:


def initialize(model:, version:, orientation:, locale: 'en')
raise 'Invalid Model' unless FirebaseDevice.valid_model_names.include? model
raise 'Invalid Version' unless FirebaseDevice.valid_version_numbers.include? version
raise 'Invalid Locale' unless FirebaseDevice.valid_locales.include? locale
raise 'Invalid Orientation' unless FirebaseDevice.valid_orientations.include? orientation

@model = model
@version = version
@locale = locale
@orientation = orientation
end

def to_s
"model=#{@model},version=#{@version},locale=#{@locale},orientation=#{@orientation}"
end

class << self
@locale_data = nil
@model_data = nil
@version_data = nil

def valid_model_names
JSON.parse(model_data).map { |device| device['codename'] }
end

def valid_version_numbers
JSON.parse(version_data).map { |version| version['apiLevel'].to_i }
end

def valid_locales
JSON.parse(locale_data).map { |locale| locale['id'] }
end

def valid_orientations
%w[portrait landscape]
end

def locale_data
FirebaseDevice.verify_logged_in!
@locale_data ||= Fastlane::Actions.sh('gcloud', 'firebase', 'test', 'android', 'locales', 'list', '--format="json"', log: false)
end

def model_data
FirebaseDevice.verify_logged_in!
@model_data ||= Fastlane::Actions.sh('gcloud', 'firebase', 'test', 'android', 'models', 'list', '--format="json"', log: false)
end

def version_data
FirebaseDevice.verify_logged_in!
@version_data ||= Fastlane::Actions.sh('gcloud', 'firebase', 'test', 'android', 'versions', 'list', '--format="json"', log: false)
end

def verify_logged_in!
UI.user_error!('You must call `firebase_login` before creating a FirebaseDevice object') unless FirebaseAccount.authenticated?
end
end
end
end
Loading