fastlane-plugin-wpmreleasetoolkit 5.5.0 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_create_avd_action.rb +90 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_launch_emulator_action.rb +61 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_send_app_size_metrics.rb +6 -11
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_shutdown_emulator_action.rb +48 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_emulator_helper.rb +198 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_tools_path_helper.rb +87 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd2b56e6aa5cf05e5e464b66e8b136e05048c7cdadee95b43bb152ab6d451e9f
|
4
|
+
data.tar.gz: da440f83d0f87a6d2dd6c74684a149d381f157d0f0ce40157c12cd237ebed373
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e684c1a705d0fab1f9d3ce82f7feed96be8a4aa09a954a19db1a564c4b958654668a6d2b9c23ee41bdcfd39ec68104f3e44e877a8df6d2bb5773efbe706c1730
|
7
|
+
data.tar.gz: 9fb910e098bbcc54a8753aebb1c2776e0c6e889d20e042f2848a38a5e3ebbeb95ae7b8def13d4efa0fa0e06c050e24e3d80633642a4281e3ba194e55c148427b
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class AndroidCreateAvdAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
device_model = params[:device_model]
|
6
|
+
api_level = params[:api_level]
|
7
|
+
avd_name = params[:avd_name]
|
8
|
+
sdcard = params[:sdcard]
|
9
|
+
|
10
|
+
helper = Fastlane::Helper::Android::EmulatorHelper.new
|
11
|
+
|
12
|
+
# Ensure we have the system image needed for creating the AVD with this API level
|
13
|
+
system_image = params[:system_image] || helper.install_system_image(api: api_level)
|
14
|
+
|
15
|
+
# Create the AVD for device, API and system image we need
|
16
|
+
helper.create_avd(
|
17
|
+
api: api_level,
|
18
|
+
device: device_model,
|
19
|
+
system_image: system_image,
|
20
|
+
name: avd_name,
|
21
|
+
sdcard: sdcard
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
#####################################################
|
26
|
+
# @!group Documentation
|
27
|
+
#####################################################
|
28
|
+
|
29
|
+
def self.description
|
30
|
+
'Creates a new Android Virtual Device (AVD) for a specific device model and API level'
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.details
|
34
|
+
<<~DESC
|
35
|
+
Creates a new Android Virtual Device (AVD) for a specific device model and API level.
|
36
|
+
By default, it also installs the necessary system image (using `sdkmanager`) if needed before creating the AVD
|
37
|
+
DESC
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.available_options
|
41
|
+
[
|
42
|
+
FastlaneCore::ConfigItem.new(key: :device_model,
|
43
|
+
env_name: 'FL_ANDROID_CREATE_AVD_DEVICE_MODEL',
|
44
|
+
description: 'The device model code to use to create the AVD. Valid values can be found using `avdmanager list devices`',
|
45
|
+
type: String,
|
46
|
+
optional: false),
|
47
|
+
FastlaneCore::ConfigItem.new(key: :api_level,
|
48
|
+
env_name: 'FL_ANDROID_CREATE_AVD_API_LEVEL',
|
49
|
+
description: 'The API level to use to install the necessary system-image and create the AVD',
|
50
|
+
type: Integer,
|
51
|
+
optional: false),
|
52
|
+
FastlaneCore::ConfigItem.new(key: :avd_name,
|
53
|
+
env_name: 'FL_ANDROID_CREATE_AVD_AVD_NAME',
|
54
|
+
description: 'The name to give to the created AVD. If not provided, will be derived from device model and API level',
|
55
|
+
type: String,
|
56
|
+
optional: true,
|
57
|
+
default_value: nil),
|
58
|
+
FastlaneCore::ConfigItem.new(key: :sdcard,
|
59
|
+
env_name: 'FL_ANDROID_CREATE_AVD_SDCARD',
|
60
|
+
description: 'The size of the SD card to use for the AVD',
|
61
|
+
type: String,
|
62
|
+
optional: true,
|
63
|
+
default_value: '512M'),
|
64
|
+
FastlaneCore::ConfigItem.new(key: :system_image,
|
65
|
+
env_name: 'FL_ANDROID_CREATE_AVD_SYSTEM_IMAGE',
|
66
|
+
description: 'The system image to use (as used/listed by `sdkmanager`). Defaults to the appropriate system image given the API level requested and the current machine\'s architecture',
|
67
|
+
type: String,
|
68
|
+
optional: true,
|
69
|
+
default_value_dynamic: true,
|
70
|
+
default_value: nil),
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.output
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.return_value
|
78
|
+
'Returns the name of the created AVD'
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.authors
|
82
|
+
['Automattic']
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.is_supported?(platform)
|
86
|
+
platform == :android
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class AndroidLaunchEmulatorAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
helper = Fastlane::Helper::Android::EmulatorHelper.new
|
6
|
+
helper.launch_avd(
|
7
|
+
name: params[:avd_name],
|
8
|
+
cold_boot: params[:cold_boot],
|
9
|
+
wipe_data: params[:wipe_data]
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
#####################################################
|
14
|
+
# @!group Documentation
|
15
|
+
#####################################################
|
16
|
+
|
17
|
+
def self.description
|
18
|
+
'Boots an Android emulator using the given AVD name'
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.details
|
22
|
+
description
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.available_options
|
26
|
+
[
|
27
|
+
FastlaneCore::ConfigItem.new(key: :avd_name,
|
28
|
+
env_name: 'FL_ANDROID_LAUNCH_EMULATOR_AVD_NAME',
|
29
|
+
description: 'The name of the AVD to boot',
|
30
|
+
type: String,
|
31
|
+
optional: false),
|
32
|
+
FastlaneCore::ConfigItem.new(key: :cold_boot,
|
33
|
+
env_name: 'FL_ANDROID_LAUNCH_EMULATOR_COLD_BOOT',
|
34
|
+
description: 'Indicate if we want a cold boot (true) of if we prefer booting from a snapshot (false)',
|
35
|
+
type: Fastlane::Boolean,
|
36
|
+
default_value: true),
|
37
|
+
FastlaneCore::ConfigItem.new(key: :wipe_data,
|
38
|
+
env_name: 'FL_ANDROID_LAUNCH_EMULATOR_WIPE_DATA',
|
39
|
+
description: 'Indicate if we want to wipe the device data before booting the AVD, so it is like it were a brand new device',
|
40
|
+
type: Fastlane::Boolean,
|
41
|
+
default_value: true),
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.output
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.return_value
|
49
|
+
'The serial of the emulator that was created after booting the AVD (e.g. `emulator-5554`)'
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.authors
|
53
|
+
['Automattic']
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.is_supported?(platform)
|
57
|
+
platform == :android
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -71,31 +71,26 @@ module Fastlane
|
|
71
71
|
end
|
72
72
|
|
73
73
|
# The path where the `apkanalyzer` binary was found, after searching it:
|
74
|
-
# - in priority in `$
|
74
|
+
# - in priority in `$ANDROID_HOME` (or `$ANDROID_SDK_ROOT` for legacy setups), under `cmdline-tools/latest/bin/` or `cmdline-tools/tools/bin`
|
75
75
|
# - and falling back by trying to find it in `$PATH`
|
76
76
|
#
|
77
77
|
# @return [String,Nil] The path to `apkanalyzer`, or `nil` if it wasn't found in any of the above tested paths.
|
78
78
|
#
|
79
79
|
def find_apkanalyzer_binary
|
80
|
-
|
81
|
-
|
82
|
-
pattern = File.join(sdk_root, 'cmdline-tools', '{latest,tools}', 'bin', 'apkanalyzer')
|
83
|
-
apkanalyzer_bin = Dir.glob(pattern).find { |path| File.executable?(path) }
|
84
|
-
end
|
85
|
-
apkanalyzer_bin || Action.sh('command', '-v', 'apkanalyzer', print_command_output: false) { |_| nil }
|
80
|
+
@tools ||= Fastlane::Helper::Android::ToolsPathHelper.new
|
81
|
+
@tools.find_tool_path(binary: 'apkanalyzer', search_paths: @tools.cmdline_tools_search_paths)
|
86
82
|
end
|
87
83
|
|
88
84
|
# The path where the `apkanalyzer` binary was found, after searching it:
|
89
|
-
# - in priority in `$
|
85
|
+
# - in priority in `$ANDROID_HOME` (or `$ANDROID_SDK_ROOT` for legacy setups), under `cmdline-tools/latest/bin/` or `cmdline-tools/tools/bin`
|
90
86
|
# - and falling back by trying to find it in `$PATH`
|
91
87
|
#
|
92
88
|
# @return [String] The path to `apkanalyzer`
|
93
89
|
# @raise [FastlaneCore::Interface::FastlaneError] if it wasn't found in any of the above tested paths.
|
94
90
|
#
|
95
91
|
def find_apkanalyzer_binary!
|
96
|
-
|
97
|
-
|
98
|
-
apkanalyzer_bin
|
92
|
+
@tools ||= Fastlane::Helper::Android::ToolsPathHelper.new
|
93
|
+
@tools.find_tool_path!(binary: 'apkanalyzer', search_paths: @tools.cmdline_tools_search_paths)
|
99
94
|
end
|
100
95
|
|
101
96
|
# Add the `file-size` and `download-size` values of an APK to the helper, as reported by the corresponding `apkanalyzer apk …` commands
|
data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_shutdown_emulator_action.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class AndroidShutdownEmulatorAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
helper = Fastlane::Helper::Android::EmulatorHelper.new
|
6
|
+
helper.shut_down_emulators!(serials: params[:serials])
|
7
|
+
end
|
8
|
+
|
9
|
+
#####################################################
|
10
|
+
# @!group Documentation
|
11
|
+
#####################################################
|
12
|
+
|
13
|
+
def self.description
|
14
|
+
'Shuts down Android emulators'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.details
|
18
|
+
description
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.available_options
|
22
|
+
[
|
23
|
+
FastlaneCore::ConfigItem.new(key: :serials,
|
24
|
+
env_name: 'FL_ANDROID_SHUTDOWN_EMULATOR_SERIALS',
|
25
|
+
description: 'The serial(s) of the emulators to shut down. If not provided (nil), will shut them all down',
|
26
|
+
type: Array,
|
27
|
+
optional: true,
|
28
|
+
default_value: nil),
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.output
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.return_value
|
36
|
+
# If you method provides a return value, you can describe here what it does
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.authors
|
40
|
+
['Automattic']
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.is_supported?(platform)
|
44
|
+
platform == :android
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Helper
|
3
|
+
module Android
|
4
|
+
# Helper methods to manipulate System Images, AVDs and Android Emulators
|
5
|
+
#
|
6
|
+
class EmulatorHelper
|
7
|
+
BOOT_WAIT = 2
|
8
|
+
BOOT_TIMEOUT = 60
|
9
|
+
|
10
|
+
SHUTDOWN_WAIT = 2
|
11
|
+
SHUTDOWN_TIMEOUT = 60
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@tools = Fastlane::Helper::Android::ToolsPathHelper.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# Installs the system-image suitable for a given Android `api`, with Google APIs, and for the current machine's architecture
|
18
|
+
#
|
19
|
+
# @param [Integer] api The Android API level to use
|
20
|
+
#
|
21
|
+
# @return [String] The `sdkmanager` package specifier that has been installed
|
22
|
+
#
|
23
|
+
def install_system_image(api:)
|
24
|
+
package = system_image_package(api: api)
|
25
|
+
|
26
|
+
UI.message("Installing System Image for Android #{api} (#{package})")
|
27
|
+
Actions.sh(@tools.sdkmanager, '--install', package)
|
28
|
+
UI.success("System Image #{package} successfully installed.")
|
29
|
+
package
|
30
|
+
end
|
31
|
+
|
32
|
+
# Create an emulator (AVD) for a given `api` number and `device` model
|
33
|
+
#
|
34
|
+
# @param [Integer] api The Android API level to use for this AVD
|
35
|
+
# @param [String] device The Device Model to use for this AVD. Valid values can be found using `avdmanager list devices`
|
36
|
+
# @param [String] name The name to give for the created AVD. Defaults to `<device>_API_<api>`.
|
37
|
+
# @param [String] sdcard The size of the SD card for this device. Defaults to `512M`.
|
38
|
+
#
|
39
|
+
# @return [String] The device name (i.e. either `name` if provided, or the derived `<device>_API_<api>` if provided `name` was `nil``)
|
40
|
+
#
|
41
|
+
def create_avd(api:, device:, system_image: nil, name: nil, sdcard: '512M')
|
42
|
+
package = system_image || system_image_package(api: api)
|
43
|
+
device_name = name || "#{device.gsub(' ', '_').capitalize}_API_#{api}"
|
44
|
+
|
45
|
+
UI.message("Creating AVD `#{device_name}` (#{device}, API #{api})")
|
46
|
+
|
47
|
+
Actions.sh(
|
48
|
+
@tools.avdmanager, 'create', 'avd',
|
49
|
+
'--force',
|
50
|
+
'--package', package,
|
51
|
+
'--device', device,
|
52
|
+
'--sdcard', sdcard,
|
53
|
+
'--name', device_name
|
54
|
+
)
|
55
|
+
|
56
|
+
UI.success("AVD `#{device_name}` successfully created.")
|
57
|
+
|
58
|
+
device_name
|
59
|
+
end
|
60
|
+
|
61
|
+
# Launch the emulator for the given AVD, then return the emulator serial
|
62
|
+
#
|
63
|
+
# @param [String] name name of the AVD to launch
|
64
|
+
# @param [Int] port the TCP port to use to connect to the emulator via adb. If nil (default), will let `emulator` pick the first free one.
|
65
|
+
# @param [Boolean] cold_boot if true, will do a cold boot, if false will try to use a previous snapshot of the device
|
66
|
+
# @param [Boolean] wipe_data if true, will wipe the emulator (i.e. reset the user data image)
|
67
|
+
#
|
68
|
+
# @return [String] emulator serial number corresponding to the launched AVD
|
69
|
+
#
|
70
|
+
def launch_avd(name:, port: nil, cold_boot: true, wipe_data: true)
|
71
|
+
UI.message("Launching emulator for #{name}")
|
72
|
+
|
73
|
+
params = ['-avd', name]
|
74
|
+
params << ['-port', port.to_s] unless port.nil?
|
75
|
+
params << '-no-snapshot' if cold_boot
|
76
|
+
params << '-wipe-data' if wipe_data
|
77
|
+
|
78
|
+
UI.command([@tools.emulator, *params].shelljoin)
|
79
|
+
# We want to launch emulator in the background to not block the rest of the code, so we can't use `Actions.sh` here
|
80
|
+
# We also want to filter the `stdout`+`stderr` emitted by the `emulator` process in the background,
|
81
|
+
# to limit verbosity and only print error lines, and also prefix those clearly (because they might happen
|
82
|
+
# at any moment in the background, so in parallel/the middle of other fastlane logs).
|
83
|
+
t = Thread.new do
|
84
|
+
Open3.popen2e(@tools.emulator, *params) do |i, oe, wait_thr|
|
85
|
+
i.close
|
86
|
+
until oe.eof?
|
87
|
+
line = oe.readline
|
88
|
+
UI.error("📱 [emulator]: #{line}") if line.start_with?(/ERROR|PANIC/)
|
89
|
+
next unless line.include?('PANIC: Broken AVD system path')
|
90
|
+
|
91
|
+
UI.user_error! <<~HINT
|
92
|
+
#{line}
|
93
|
+
Verify that your `sdkmanager/avdmanager` tools are not installed in a different SDK root than your `emulator` tool
|
94
|
+
(which can happen if you installed Android's command-line tools via `brew`, but the `emulator` via Android Studio, or vice-versa)
|
95
|
+
HINT
|
96
|
+
end
|
97
|
+
UI.error("📱 [emulator]: exited with non-zero status code: #{wait_thr.value.exitstatus}") unless wait_thr.value.success?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
t.abort_on_exception = true # To bubble up any exception like `UI.user_error!` back to the main thread here
|
101
|
+
|
102
|
+
UI.message('Waiting for emulator to start...')
|
103
|
+
# Loop until the emulator has started and shows up in `adb devices -l` so we can find its serial
|
104
|
+
serial = nil
|
105
|
+
retry_loop(time_between_retries: BOOT_WAIT, timeout: BOOT_TIMEOUT, description: 'waiting for emulator to start') do
|
106
|
+
serial = find_serial(avd_name: name)
|
107
|
+
!serial.nil?
|
108
|
+
end
|
109
|
+
UI.message("Found device `#{name}` with serial `#{serial}`")
|
110
|
+
|
111
|
+
# Once the emulator has started, wait for the device in the emulator to finish booting
|
112
|
+
UI.message('Waiting for device to finish booting...')
|
113
|
+
retry_loop(time_between_retries: BOOT_WAIT, timeout: BOOT_TIMEOUT, description: 'waiting for device to finish booting') do
|
114
|
+
Actions.sh(@tools.adb, '-s', serial, 'shell', 'getprop', 'sys.boot_completed').chomp == '1'
|
115
|
+
end
|
116
|
+
|
117
|
+
UI.success("Emulator #{name} successfully booted as `#{serial}`.")
|
118
|
+
|
119
|
+
serial
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return [Array<Fastlane::Helper::AdbDevice>] List of currently booted emulators
|
123
|
+
#
|
124
|
+
def running_emulators
|
125
|
+
helper = Fastlane::Helper::AdbHelper.new(adb_path: @tools.adb)
|
126
|
+
helper.load_all_devices.select { |device| device.serial.include?('emulator') }
|
127
|
+
end
|
128
|
+
|
129
|
+
def find_serial(avd_name:)
|
130
|
+
running_emulators.find do |candidate|
|
131
|
+
command = [@tools.adb, '-s', candidate.serial, 'emu', 'avd', 'name']
|
132
|
+
UI.command(command.shelljoin)
|
133
|
+
candidate_name = Actions.sh(*command, log: false).split("\n").first.chomp
|
134
|
+
candidate_name == avd_name
|
135
|
+
end&.serial
|
136
|
+
end
|
137
|
+
|
138
|
+
# Trigger a shutdown for all running emulators, and wait until there is no more emulators running.
|
139
|
+
#
|
140
|
+
# @param [Array<String>] serials List of emulator serials to shut down. Will shut down all of them if `nil`.
|
141
|
+
#
|
142
|
+
def shut_down_emulators!(serials: nil)
|
143
|
+
UI.message("Shutting down #{serials || 'all'} emulator(s)...")
|
144
|
+
|
145
|
+
emulators_list = running_emulators.map(&:serial)
|
146
|
+
# Get the intersection of the set of running emulators with the ones we want to shut down
|
147
|
+
emulators_list &= serials unless serials.nil?
|
148
|
+
emulators_list.each do |e|
|
149
|
+
Actions.sh(@tools.adb, '-s', e, 'emu', 'kill') { |_| } # ignore error if no emulator with specified serial is running
|
150
|
+
|
151
|
+
# NOTE: Alternative way of shutting down emulator would be to call the following command instead, which shuts down the emulator more gracefully:
|
152
|
+
# `adb -s #{e} shell reboot -p` # In case you're wondering, `-p` is for "power-off"
|
153
|
+
# But this alternate command:
|
154
|
+
# - Requires that `-no-snapshot` was used on boot (to avoid being prompted to save current state on shutdown)
|
155
|
+
# - Disconnects the emulator from `adb` (and thus disappear from `adb devices -l`) for a short amount of time,
|
156
|
+
# before reconnecting to it but in an `offline` state, until `emulator` finally completely quits and it disappears
|
157
|
+
# again (for good) from `adb devices --list`.
|
158
|
+
# This means that so if we used alternative, we couldn't really retry_loop until emulator disappears from `running_emulators` to detect
|
159
|
+
# that the shutdown was really complete, as we might as well accidentally detect the intermediate disconnect instead.
|
160
|
+
end
|
161
|
+
|
162
|
+
# Wait until all emulators are killed
|
163
|
+
retry_loop(time_between_retries: SHUTDOWN_WAIT, timeout: SHUTDOWN_TIMEOUT, description: 'waiting for devices to shutdown') do
|
164
|
+
(emulators_list & running_emulators.map(&:serial)).empty?
|
165
|
+
end
|
166
|
+
|
167
|
+
UI.success('All emulators are now shut down.')
|
168
|
+
end
|
169
|
+
|
170
|
+
# Find the system-images package for the provided `api`, with Google APIs, and matching the current platform/architecture this lane is called from.
|
171
|
+
#
|
172
|
+
# @param [Integer] api The Android API level to use for this AVD
|
173
|
+
# @return [String] The `system-images;android-<N>;google_apis;<platform>` package specifier for `sdkmanager` to use in its install command
|
174
|
+
#
|
175
|
+
# @note Results from this method are memoized, to avoid repeating calls to `sdkmanager` when querying for the same api level multiple times.
|
176
|
+
#
|
177
|
+
def system_image_package(api:)
|
178
|
+
@system_image_packages ||= {}
|
179
|
+
@system_image_packages[api] ||= begin
|
180
|
+
platform = `uname -m`.chomp
|
181
|
+
all_packages = `#{@tools.sdkmanager} --list`
|
182
|
+
package = all_packages.match(/^ *(system-images;android-#{api};google_apis;#{platform}(-[^ ]*)?)/)&.captures&.first
|
183
|
+
UI.user_error!("Could not find system-image for API `#{api}` and your platform `#{platform}` in `sdkmanager --list`. Maybe Google removed it for download and it's time to update to a newer API?") if package.nil?
|
184
|
+
package
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def retry_loop(time_between_retries:, timeout:, description:)
|
189
|
+
Timeout.timeout(timeout) do
|
190
|
+
sleep(time_between_retries) until yield
|
191
|
+
end
|
192
|
+
rescue Timeout::Error
|
193
|
+
UI.user_error!("Timed out #{description}")
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Helper
|
5
|
+
module Android
|
6
|
+
# Helper to find the paths of common Android build and SDK tools on the current machine
|
7
|
+
# Based on `$ANDROID_HOME` and the common relative paths those tools are installed in.
|
8
|
+
#
|
9
|
+
class ToolsPathHelper
|
10
|
+
attr_reader :android_home
|
11
|
+
|
12
|
+
def initialize(sdk_root: nil)
|
13
|
+
@android_home = sdk_root || ENV['ANDROID_HOME'] || ENV['ANDROID_SDK_ROOT'] || ENV['ANDROID_SDK']
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [String] binary The name of the binary to search for
|
17
|
+
# @param [Array<String>] search_paths The search paths, relative to `@android_home`, in which to search for the tools.
|
18
|
+
# If `android_home` is `nil` or the binary wasn't found in any of the `search_paths`, will fallback to searching in `$PATH`.
|
19
|
+
# @return [String] The absolute path of the tool if found, `nil` if not found.
|
20
|
+
def find_tool_path(binary:, search_paths:)
|
21
|
+
bin_path = unless android_home.nil?
|
22
|
+
search_paths
|
23
|
+
.map { |path| File.join(android_home, path, binary) }
|
24
|
+
.find { |path| File.executable?(path) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# If not found in any of the `search_paths`, try to look for it in $PATH
|
28
|
+
bin_path ||= Actions.sh('command', '-v', binary) { |err, res, _| res if err&.success? }&.chomp
|
29
|
+
|
30
|
+
# Normalize return value to `nil` if it was not found, empty, or is not an executable
|
31
|
+
bin_path = nil if !bin_path.nil? && (bin_path.empty? || !File.executable?(bin_path))
|
32
|
+
|
33
|
+
bin_path
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param [String] binary The name of the binary to search for
|
37
|
+
# @param [Array<String>] search_paths The search paths, relative to `@android_home`, in which to search for the tools.
|
38
|
+
# If `android_home` is `nil` or the binary wasn't found in any of the `search_paths`, will fallback to searching in `$PATH`.
|
39
|
+
# @return [String] The absolute path of the tool if found.
|
40
|
+
# @raise [FastlaneCore::Interface::FastlaneError] If the tool couldn't be found.
|
41
|
+
def find_tool_path!(binary:, search_paths:)
|
42
|
+
bin_path = find_tool_path(binary: binary, search_paths: search_paths)
|
43
|
+
UI.user_error!("Unable to find path for #{binary} in #{search_paths.inspect}. Verify you installed the proper Android tools.") if bin_path.nil?
|
44
|
+
bin_path
|
45
|
+
end
|
46
|
+
|
47
|
+
def cmdline_tools_search_paths
|
48
|
+
# It appears that depending on the machines and versions of Android SDK, some versions
|
49
|
+
# installed the command line tools in `tools` and not `latest` subdirectory, hence why
|
50
|
+
# we search both (`latest` first, `tools` as fallback) to cover all our bases.
|
51
|
+
[
|
52
|
+
File.join('cmdline-tools', 'latest', 'bin'),
|
53
|
+
File.join('cmdline-tools', 'tools', 'bin'),
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
def sdkmanager
|
58
|
+
@sdkmanager ||= find_tool_path!(
|
59
|
+
binary: 'sdkmanager',
|
60
|
+
search_paths: cmdline_tools_search_paths
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def avdmanager
|
65
|
+
@avdmanager ||= find_tool_path!(
|
66
|
+
binary: 'avdmanager',
|
67
|
+
search_paths: cmdline_tools_search_paths
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def emulator
|
72
|
+
@emulator ||= find_tool_path!(
|
73
|
+
binary: 'emulator',
|
74
|
+
search_paths: [File.join('emulator')]
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def adb
|
79
|
+
@adb ||= find_tool_path!(
|
80
|
+
binary: 'adb',
|
81
|
+
search_paths: [File.join('platform-tools')]
|
82
|
+
)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-wpmreleasetoolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Automattic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -260,14 +260,14 @@ dependencies:
|
|
260
260
|
requirements:
|
261
261
|
- - "~>"
|
262
262
|
- !ruby/object:Gem::Version
|
263
|
-
version: '2'
|
263
|
+
version: '2.210'
|
264
264
|
type: :development
|
265
265
|
prerelease: false
|
266
266
|
version_requirements: !ruby/object:Gem::Requirement
|
267
267
|
requirements:
|
268
268
|
- - "~>"
|
269
269
|
- !ruby/object:Gem::Version
|
270
|
-
version: '2'
|
270
|
+
version: '2.210'
|
271
271
|
- !ruby/object:Gem::Dependency
|
272
272
|
name: pry
|
273
273
|
requirement: !ruby/object:Gem::Requirement
|
@@ -402,6 +402,7 @@ files:
|
|
402
402
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_release.rb
|
403
403
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_codefreeze_prechecks.rb
|
404
404
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_completecodefreeze_prechecks.rb
|
405
|
+
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_create_avd_action.rb
|
405
406
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_create_xml_release_notes.rb
|
406
407
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_current_branch_is_hotfix.rb
|
407
408
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_download_file_by_version.rb
|
@@ -412,7 +413,9 @@ files:
|
|
412
413
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_app_version.rb
|
413
414
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_release_version.rb
|
414
415
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_hotfix_prechecks.rb
|
416
|
+
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_launch_emulator_action.rb
|
415
417
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_send_app_size_metrics.rb
|
418
|
+
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_shutdown_emulator_action.rb
|
416
419
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_tag_build.rb
|
417
420
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_release_notes.rb
|
418
421
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/common/buildkite_trigger_build_action.rb
|
@@ -471,8 +474,10 @@ files:
|
|
471
474
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_update_release_notes.rb
|
472
475
|
- lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_validate_ci_build.rb
|
473
476
|
- lib/fastlane/plugin/wpmreleasetoolkit/helper/an_metadata_update_helper.rb
|
477
|
+
- lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_emulator_helper.rb
|
474
478
|
- lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_git_helper.rb
|
475
479
|
- lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_localize_helper.rb
|
480
|
+
- lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_tools_path_helper.rb
|
476
481
|
- lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb
|
477
482
|
- lib/fastlane/plugin/wpmreleasetoolkit/helper/app_size_metrics_helper.rb
|
478
483
|
- lib/fastlane/plugin/wpmreleasetoolkit/helper/ci_helper.rb
|