fastlane 2.174.0 → 2.179.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +93 -80
- data/cert/lib/cert/options.rb +3 -2
- data/cert/lib/cert/runner.rb +5 -1
- data/deliver/lib/deliver/app_screenshot.rb +6 -2
- data/deliver/lib/deliver/download_screenshots.rb +1 -2
- data/deliver/lib/deliver/options.rb +3 -2
- data/deliver/lib/deliver/runner.rb +12 -4
- data/deliver/lib/deliver/setup.rb +0 -1
- data/deliver/lib/deliver/upload_metadata.rb +5 -4
- data/deliver/lib/deliver/upload_screenshots.rb +12 -11
- data/fastlane/lib/fastlane/actions/adb.rb +1 -1
- data/fastlane/lib/fastlane/actions/app_store_build_number.rb +8 -3
- data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +7 -4
- data/fastlane/lib/fastlane/actions/appaloosa.rb +7 -2
- data/fastlane/lib/fastlane/actions/backup_file.rb +1 -1
- data/fastlane/lib/fastlane/actions/build_app.rb +4 -0
- data/fastlane/lib/fastlane/actions/check_app_store_metadata.rb +4 -0
- data/fastlane/lib/fastlane/actions/commit_github_file.rb +11 -1
- data/fastlane/lib/fastlane/actions/create_xcframework.rb +5 -0
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +8 -2
- data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -1
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +5 -15
- data/fastlane/lib/fastlane/actions/get_github_release.rb +11 -1
- data/fastlane/lib/fastlane/actions/get_provisioning_profile.rb +4 -0
- data/fastlane/lib/fastlane/actions/get_version_number.rb +17 -10
- data/fastlane/lib/fastlane/actions/git_branch.rb +4 -10
- data/fastlane/lib/fastlane/actions/git_commit.rb +1 -1
- data/fastlane/lib/fastlane/actions/git_tag_exists.rb +4 -0
- data/fastlane/lib/fastlane/actions/github_api.rb +2 -1
- data/fastlane/lib/fastlane/actions/increment_build_number.rb +8 -1
- data/fastlane/lib/fastlane/actions/install_provisioning_profile.rb +4 -0
- data/fastlane/lib/fastlane/actions/jazzy.rb +10 -1
- data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +3 -2
- data/fastlane/lib/fastlane/actions/match_nuke.rb +59 -0
- data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +0 -1
- data/fastlane/lib/fastlane/actions/register_device.rb +3 -3
- data/fastlane/lib/fastlane/actions/register_devices.rb +3 -3
- data/fastlane/lib/fastlane/actions/restore_file.rb +1 -1
- data/fastlane/lib/fastlane/actions/set_changelog.rb +3 -3
- data/fastlane/lib/fastlane/actions/spaceship_logs.rb +1 -1
- data/fastlane/lib/fastlane/actions/swiftlint.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +1 -2
- data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +4 -5
- data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +5 -1
- data/fastlane/lib/fastlane/documentation/actions_list.rb +2 -2
- data/fastlane/lib/fastlane/erb_template_helper.rb +7 -1
- data/fastlane/lib/fastlane/fast_file.rb +9 -5
- data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
- data/fastlane/lib/fastlane/helper/gem_helper.rb +2 -2
- data/fastlane/lib/fastlane/helper/git_helper.rb +11 -7
- data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +1 -2
- data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +1 -2
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +1 -2
- data/fastlane/lib/fastlane/swift_fastlane_function.rb +4 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +3 -3
- data/fastlane/swift/Fastlane.swift +491 -315
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +3 -3
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +9 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
- data/fastlane/swift/formatting/Brewfile.lock.json +13 -11
- data/fastlane_core/lib/fastlane_core.rb +1 -0
- data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -9
- data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +1 -1
- data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +23 -0
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +6 -6
- data/fastlane_core/lib/fastlane_core/helper.rb +50 -6
- data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +3 -2
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +14 -8
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -1
- data/fastlane_core/lib/fastlane_core/pkg_upload_package_builder.rb +3 -2
- data/fastlane_core/lib/fastlane_core/project.rb +3 -14
- data/{deliver/lib/deliver → fastlane_core/lib/fastlane_core}/queue_worker.rb +2 -2
- data/fastlane_core/lib/fastlane_core/ui/interface.rb +1 -1
- data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +2 -2
- data/gym/lib/gym/.runner.rb.swp +0 -0
- data/gym/lib/gym/generators/.package_command_generator_xcode7.rb.swp +0 -0
- data/gym/lib/gym/generators/package_command_generator.rb +4 -0
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +13 -8
- data/gym/lib/gym/runner.rb +11 -4
- data/match/lib/match/change_password.rb +3 -3
- data/match/lib/match/encryption/interface.rb +1 -1
- data/match/lib/match/encryption/openssl.rb +2 -2
- data/match/lib/match/importer.rb +1 -1
- data/match/lib/match/migrate.rb +1 -1
- data/match/lib/match/module.rb +1 -0
- data/match/lib/match/nuke.rb +6 -1
- data/match/lib/match/options.rb +2 -2
- data/match/lib/match/runner.rb +1 -1
- data/match/lib/match/storage/google_cloud_storage.rb +1 -1
- data/match/lib/match/storage/s3_storage.rb +1 -1
- data/pilot/lib/pilot/build_manager.rb +25 -8
- data/pilot/lib/pilot/manager.rb +5 -1
- data/pilot/lib/pilot/options.rb +6 -5
- data/precheck/lib/precheck/options.rb +3 -2
- data/precheck/lib/precheck/runner.rb +6 -2
- data/scan/lib/scan/detect_values.rb +4 -1
- data/scan/lib/scan/options.rb +10 -0
- data/scan/lib/scan/runner.rb +27 -0
- data/screengrab/lib/screengrab/android_environment.rb +8 -6
- data/screengrab/lib/screengrab/runner.rb +2 -3
- data/sigh/lib/sigh/download_all.rb +1 -1
- data/sigh/lib/sigh/options.rb +3 -2
- data/sigh/lib/sigh/runner.rb +5 -1
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +2 -1
- data/spaceship/README.md +2 -2
- data/spaceship/lib/spaceship/client.rb +18 -17
- data/spaceship/lib/spaceship/connect_api/api_client.rb +24 -6
- data/spaceship/lib/spaceship/connect_api/models/app.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/app_preview_set.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +6 -0
- data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/build.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +4 -0
- data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +13 -0
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +13 -0
- data/spaceship/lib/spaceship/connect_api/token.rb +2 -2
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +15 -0
- data/spaceship/lib/spaceship/playground.rb +2 -2
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +41 -28
- metadata +41 -22
data/pilot/lib/pilot/options.rb
CHANGED
@@ -11,7 +11,7 @@ module Pilot
|
|
11
11
|
|
12
12
|
[
|
13
13
|
FastlaneCore::ConfigItem.new(key: :api_key_path,
|
14
|
-
|
14
|
+
env_names: ["PILOT_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
|
15
15
|
description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
|
16
16
|
optional: true,
|
17
17
|
conflicting_options: [:username],
|
@@ -19,7 +19,7 @@ module Pilot
|
|
19
19
|
UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
|
20
20
|
end),
|
21
21
|
FastlaneCore::ConfigItem.new(key: :api_key,
|
22
|
-
|
22
|
+
env_names: ["PILOT_API_KEY", "APP_STORE_CONNECT_API_KEY"],
|
23
23
|
description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
|
24
24
|
type: Hash,
|
25
25
|
optional: true,
|
@@ -31,6 +31,7 @@ module Pilot
|
|
31
31
|
short_option: "-u",
|
32
32
|
env_name: "PILOT_USERNAME",
|
33
33
|
description: "Your Apple ID Username",
|
34
|
+
optional: true,
|
34
35
|
default_value: user,
|
35
36
|
default_value_dynamic: true),
|
36
37
|
FastlaneCore::ConfigItem.new(key: :app_identifier,
|
@@ -88,7 +89,7 @@ module Pilot
|
|
88
89
|
type: Boolean,
|
89
90
|
env_name: "DEMO_ACCOUNT_REQUIRED",
|
90
91
|
description: "Do you need a demo account when Apple does review?",
|
91
|
-
|
92
|
+
optional: true),
|
92
93
|
FastlaneCore::ConfigItem.new(key: :beta_app_review_info,
|
93
94
|
type: Hash,
|
94
95
|
env_name: "PILOT_BETA_APP_REVIEW_INFO",
|
@@ -182,8 +183,8 @@ module Pilot
|
|
182
183
|
FastlaneCore::ConfigItem.new(key: :notify_external_testers,
|
183
184
|
is_string: false,
|
184
185
|
env_name: "PILOT_NOTIFY_EXTERNAL_TESTERS",
|
185
|
-
description: "Should notify external testers?",
|
186
|
-
|
186
|
+
description: "Should notify external testers? (Not setting a value will use App Store Connect's default which is to notify)",
|
187
|
+
optional: true),
|
187
188
|
FastlaneCore::ConfigItem.new(key: :app_version,
|
188
189
|
env_name: "PILOT_APP_VERSION",
|
189
190
|
description: "The version number of the application build to distribute. If the version number is not specified, then the most recent build uploaded to TestFlight will be distributed. If specified, the most recent build for the version number will be distributed",
|
@@ -26,7 +26,7 @@ module Precheck
|
|
26
26
|
|
27
27
|
[
|
28
28
|
FastlaneCore::ConfigItem.new(key: :api_key_path,
|
29
|
-
|
29
|
+
env_names: ["PRECHECK_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
|
30
30
|
description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
|
31
31
|
optional: true,
|
32
32
|
conflicting_options: [:username],
|
@@ -34,7 +34,7 @@ module Precheck
|
|
34
34
|
UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
|
35
35
|
end),
|
36
36
|
FastlaneCore::ConfigItem.new(key: :api_key,
|
37
|
-
|
37
|
+
env_names: ["PRECHECK_API_KEY", "APP_STORE_CONNECT_API_KEY"],
|
38
38
|
description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
|
39
39
|
type: Hash,
|
40
40
|
optional: true,
|
@@ -52,6 +52,7 @@ module Precheck
|
|
52
52
|
short_option: "-u",
|
53
53
|
env_name: "PRECHECK_USERNAME",
|
54
54
|
description: "Your Apple ID Username",
|
55
|
+
optional: true,
|
55
56
|
default_value: user,
|
56
57
|
default_value_dynamic: true),
|
57
58
|
FastlaneCore::ConfigItem.new(key: :team_id,
|
@@ -26,12 +26,16 @@ module Precheck
|
|
26
26
|
# There is also a check in Deliver::Runner for this.
|
27
27
|
# Please remove check in Deliver when the API support IAPs.
|
28
28
|
if Precheck.config[:include_in_app_purchases]
|
29
|
-
UI.user_error!("Precheck cannot check In-app purchases with the App Store Connect API Key (yet). Exclude In-app purchases from precheck or use Apple ID login")
|
29
|
+
UI.user_error!("Precheck cannot check In-app purchases with the App Store Connect API Key (yet). Exclude In-app purchases from precheck, disable the precheck step in your build step, or use Apple ID login")
|
30
30
|
end
|
31
31
|
|
32
32
|
UI.message("Creating authorization token for App Store Connect API")
|
33
33
|
Spaceship::ConnectAPI.token = api_token
|
34
34
|
elsif Spaceship::Tunes.client.nil?
|
35
|
+
# Username is now optional since addition of App Store Connect API Key
|
36
|
+
# Force asking for username to prompt user if not already set
|
37
|
+
Precheck.config.fetch(:username, force_ask: true)
|
38
|
+
|
35
39
|
# Team selection passed though FASTLANE_ITC_TEAM_ID and FASTLANE_ITC_TEAM_NAME environment variables
|
36
40
|
# Prompts select team if multiple teams and none specified
|
37
41
|
UI.message("Starting login with user '#{Precheck.config[:username]}'")
|
@@ -72,7 +76,7 @@ module Precheck
|
|
72
76
|
end
|
73
77
|
|
74
78
|
def api_token
|
75
|
-
@api_token ||= Spaceship::ConnectAPI::Token.create(Precheck.config[:api_key]) if Precheck.config[:api_key]
|
79
|
+
@api_token ||= Spaceship::ConnectAPI::Token.create(**Precheck.config[:api_key]) if Precheck.config[:api_key]
|
76
80
|
@api_token ||= Spaceship::ConnectAPI::Token.from_json_file(Precheck.config[:api_key_path]) if Precheck.config[:api_key_path]
|
77
81
|
return @api_token
|
78
82
|
end
|
@@ -162,7 +162,10 @@ module Scan
|
|
162
162
|
filter_simulators(simulators, :equal, version).tap(&potential_emptiness_error).select(&selector)
|
163
163
|
end
|
164
164
|
).tap do |array|
|
165
|
-
|
165
|
+
if array.empty?
|
166
|
+
UI.test_failure!("No device found with name '#{device_string}'") if Scan.config[:ensure_devices_found]
|
167
|
+
UI.error("Ignoring '#{device_string}', couldn’t find matching simulator")
|
168
|
+
end
|
166
169
|
end
|
167
170
|
end
|
168
171
|
|
data/scan/lib/scan/options.rb
CHANGED
@@ -69,6 +69,11 @@ module Scan
|
|
69
69
|
default_value: false,
|
70
70
|
type: Boolean,
|
71
71
|
optional: true),
|
72
|
+
FastlaneCore::ConfigItem.new(key: :ensure_devices_found,
|
73
|
+
description: "Should fail if devices not found",
|
74
|
+
default_value: false,
|
75
|
+
type: Boolean,
|
76
|
+
optional: true),
|
72
77
|
|
73
78
|
# simulator management
|
74
79
|
FastlaneCore::ConfigItem.new(key: :force_quit_simulator,
|
@@ -269,6 +274,11 @@ module Scan
|
|
269
274
|
optional: true,
|
270
275
|
is_string: false,
|
271
276
|
default_value: false),
|
277
|
+
FastlaneCore::ConfigItem.new(key: :output_xctestrun,
|
278
|
+
type: Boolean,
|
279
|
+
env_name: "SCAN_OUTPUT_XCTESTRUN",
|
280
|
+
description: "Should provide additional copy of .xctestrun file (settings.xctestrun) and place in output path?",
|
281
|
+
default_value: false),
|
272
282
|
FastlaneCore::ConfigItem.new(key: :result_bundle,
|
273
283
|
short_option: "-z",
|
274
284
|
env_name: "SCAN_RESULT_BUNDLE",
|
data/scan/lib/scan/runner.rb
CHANGED
@@ -110,6 +110,7 @@ module Scan
|
|
110
110
|
|
111
111
|
copy_simulator_logs
|
112
112
|
zip_build_products
|
113
|
+
copy_xctestrun
|
113
114
|
|
114
115
|
if result[:failures] > 0
|
115
116
|
open_report
|
@@ -150,6 +151,32 @@ module Scan
|
|
150
151
|
UI.message("Successfully zipped build products: #{output_path}")
|
151
152
|
end
|
152
153
|
|
154
|
+
def copy_xctestrun
|
155
|
+
return unless Scan.config[:output_xctestrun]
|
156
|
+
|
157
|
+
# Gets :derived_data_path/Build/Products directory for coping .xctestrun file
|
158
|
+
derived_data_path = Scan.config[:derived_data_path]
|
159
|
+
path = File.join(derived_data_path, "Build", "Products")
|
160
|
+
|
161
|
+
# Gets absolute path of output directory
|
162
|
+
output_directory = File.absolute_path(Scan.config[:output_directory])
|
163
|
+
output_path = File.join(output_directory, "settings.xctestrun")
|
164
|
+
|
165
|
+
# Caching path for action to put into lane_context
|
166
|
+
Scan.cache[:output_xctestrun] = output_path
|
167
|
+
|
168
|
+
# Copy .xctestrun file and moves it to output directory
|
169
|
+
UI.message("Copying .xctestrun file")
|
170
|
+
xctestrun_file = Dir.glob("#{path}/*.xctestrun").first
|
171
|
+
|
172
|
+
if xctestrun_file
|
173
|
+
FileUtils.cp(xctestrun_file, output_path)
|
174
|
+
UI.message("Successfully copied xctestrun file: #{output_path}")
|
175
|
+
else
|
176
|
+
UI.user_error!("Could not find .xctextrun file to copy")
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
153
180
|
def test_results
|
154
181
|
temp_junit_report = Scan.cache[:temp_junit_report]
|
155
182
|
return File.read(temp_junit_report) if temp_junit_report && File.file?(temp_junit_report)
|
@@ -34,22 +34,22 @@ module Screengrab
|
|
34
34
|
def find_platform_tools(android_home)
|
35
35
|
return nil unless android_home
|
36
36
|
|
37
|
-
platform_tools_path = File.join(android_home, 'platform-tools')
|
37
|
+
platform_tools_path = Helper.localize_file_path(File.join(android_home, 'platform-tools'))
|
38
38
|
File.directory?(platform_tools_path) ? platform_tools_path : nil
|
39
39
|
end
|
40
40
|
|
41
41
|
def find_build_tools(android_home, build_tools_version)
|
42
42
|
return nil unless android_home
|
43
43
|
|
44
|
-
build_tools_dir = File.join(android_home, 'build-tools')
|
44
|
+
build_tools_dir = Helper.localize_file_path(File.join(android_home, 'build-tools'))
|
45
45
|
|
46
46
|
return nil unless build_tools_dir && File.directory?(build_tools_dir)
|
47
47
|
|
48
|
-
return File.join(build_tools_dir, build_tools_version) if build_tools_version
|
48
|
+
return Helper.localize_file_path(File.join(build_tools_dir, build_tools_version)) if build_tools_version
|
49
49
|
|
50
50
|
version = select_build_tools_version(build_tools_dir)
|
51
51
|
|
52
|
-
return version ? File.join(build_tools_dir, version) : nil
|
52
|
+
return version ? Helper.localize_file_path(File.join(build_tools_dir, version)) : nil
|
53
53
|
end
|
54
54
|
|
55
55
|
def select_build_tools_version(build_tools_dir)
|
@@ -73,14 +73,16 @@ module Screengrab
|
|
73
73
|
def find_adb(platform_tools_path)
|
74
74
|
return FastlaneCore::CommandExecutor.which('adb') unless platform_tools_path
|
75
75
|
|
76
|
-
adb_path = File.join(platform_tools_path, 'adb')
|
76
|
+
adb_path = Helper.get_executable_path(File.join(platform_tools_path, 'adb'))
|
77
|
+
adb_path = Helper.localize_file_path(adb_path)
|
77
78
|
return executable_command?(adb_path) ? adb_path : nil
|
78
79
|
end
|
79
80
|
|
80
81
|
def find_aapt(build_tools_path)
|
81
82
|
return FastlaneCore::CommandExecutor.which('aapt') unless build_tools_path
|
82
83
|
|
83
|
-
aapt_path = File.join(build_tools_path, 'aapt')
|
84
|
+
aapt_path = Helper.get_executable_path(File.join(build_tools_path, 'aapt'))
|
85
|
+
aapt_path = Helper.localize_file_path(aapt_path)
|
84
86
|
return executable_command?(aapt_path) ? aapt_path : nil
|
85
87
|
end
|
86
88
|
|
@@ -308,7 +308,7 @@ module Screengrab
|
|
308
308
|
if out =~ /Permission denied/
|
309
309
|
dir = File.dirname(path)
|
310
310
|
base = File.basename(path)
|
311
|
-
run_adb_command("-s #{device_serial} shell run-as #{@config[:app_package_name]}
|
311
|
+
run_adb_command("-s #{device_serial} shell run-as #{@config[:app_package_name]} \"tar -cC #{dir} #{base}\" | tar -xv -f- -C #{tempdir}",
|
312
312
|
print_all: false,
|
313
313
|
print_command: true)
|
314
314
|
end
|
@@ -392,13 +392,12 @@ module Screengrab
|
|
392
392
|
end
|
393
393
|
|
394
394
|
def run_adb_command(command, print_all: false, print_command: false, raise_errors: true)
|
395
|
-
adb_path = @android_env.adb_path.chomp("adb")
|
396
395
|
adb_host = @config[:adb_host]
|
397
396
|
host = adb_host.nil? ? '' : "-H #{adb_host} "
|
398
397
|
output = ''
|
399
398
|
begin
|
400
399
|
errout = nil
|
401
|
-
cmdout = @executor.execute(command: adb_path + "
|
400
|
+
cmdout = @executor.execute(command: @android_env.adb_path + " " + host + command,
|
402
401
|
print_all: print_all,
|
403
402
|
print_command: print_command,
|
404
403
|
error: raise_errors ? nil : proc { |out, status| errout = out }) || ''
|
@@ -60,7 +60,7 @@ module Sigh
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def api_token
|
63
|
-
api_token ||= Spaceship::ConnectAPI::Token.create(Sigh.config[:api_key]) if Sigh.config[:api_key]
|
63
|
+
api_token ||= Spaceship::ConnectAPI::Token.create(**Sigh.config[:api_key]) if Sigh.config[:api_key]
|
64
64
|
api_token ||= Spaceship::ConnectAPI::Token.from_json_file(Sigh.config[:api_key_path]) if Sigh.config[:api_key_path]
|
65
65
|
return api_token
|
66
66
|
end
|
data/sigh/lib/sigh/options.rb
CHANGED
@@ -57,7 +57,7 @@ module Sigh
|
|
57
57
|
|
58
58
|
# App Store Connect API
|
59
59
|
FastlaneCore::ConfigItem.new(key: :api_key_path,
|
60
|
-
|
60
|
+
env_names: ["SIGH_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
|
61
61
|
description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
|
62
62
|
optional: true,
|
63
63
|
conflicting_options: [:api_key],
|
@@ -65,7 +65,7 @@ module Sigh
|
|
65
65
|
UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
|
66
66
|
end),
|
67
67
|
FastlaneCore::ConfigItem.new(key: :api_key,
|
68
|
-
|
68
|
+
env_names: ["SIGH_API_KEY", "APP_STORE_CONNECT_API_KEY"],
|
69
69
|
description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
|
70
70
|
type: Hash,
|
71
71
|
optional: true,
|
@@ -77,6 +77,7 @@ module Sigh
|
|
77
77
|
short_option: "-u",
|
78
78
|
env_name: "SIGH_USERNAME",
|
79
79
|
description: "Your Apple ID Username",
|
80
|
+
optional: true,
|
80
81
|
default_value: user,
|
81
82
|
default_value_dynamic: true),
|
82
83
|
FastlaneCore::ConfigItem.new(key: :team_id,
|
data/sigh/lib/sigh/runner.rb
CHANGED
@@ -21,6 +21,10 @@ module Sigh
|
|
21
21
|
UI.message("Creating authorization token for App Store Connect API")
|
22
22
|
Spaceship::ConnectAPI.token = api_token
|
23
23
|
else
|
24
|
+
# Username is now optional since addition of App Store Connect API Key
|
25
|
+
# Force asking for username to prompt user if not already set
|
26
|
+
Sigh.config.fetch(:username, force_ask: true)
|
27
|
+
|
24
28
|
# Team selection passed though FASTLANE_ITC_TEAM_ID and FASTLANE_ITC_TEAM_NAME environment variables
|
25
29
|
# Prompts select team if multiple teams and none specified
|
26
30
|
UI.message("Starting login with user '#{Sigh.config[:username]}'")
|
@@ -60,7 +64,7 @@ module Sigh
|
|
60
64
|
end
|
61
65
|
|
62
66
|
def api_token
|
63
|
-
@api_token ||= Spaceship::ConnectAPI::Token.create(Sigh.config[:api_key]) if Sigh.config[:api_key]
|
67
|
+
@api_token ||= Spaceship::ConnectAPI::Token.create(**Sigh.config[:api_key]) if Sigh.config[:api_key]
|
64
68
|
@api_token ||= Spaceship::ConnectAPI::Token.from_json_file(Sigh.config[:api_key_path]) if Sigh.config[:api_key_path]
|
65
69
|
return @api_token
|
66
70
|
end
|
@@ -69,7 +69,8 @@ module Snapshot
|
|
69
69
|
unless launcher_config.dark_mode.nil?
|
70
70
|
interface_style(type, launcher_config.dark_mode)
|
71
71
|
end
|
72
|
-
|
72
|
+
end
|
73
|
+
if launcher_config.reinstall_app && !launcher_config.erase_simulator
|
73
74
|
# no need to reinstall if device has been erased
|
74
75
|
uninstall_app(type)
|
75
76
|
end
|
data/spaceship/README.md
CHANGED
@@ -83,7 +83,7 @@ Using spaceship, the execution time of [_sigh_](https://docs.fastlane.tools/acti
|
|
83
83
|
|
84
84
|
_spaceship_ is part of _fastlane_:
|
85
85
|
|
86
|
-
|
86
|
+
gem install fastlane
|
87
87
|
|
88
88
|
# Usage
|
89
89
|
|
@@ -93,7 +93,7 @@ To try _spaceship_, just run `fastlane spaceship`. It will automatically start t
|
|
93
93
|
|
94
94
|
![assets/docs/Playground.png](assets/docs/Playground.png)
|
95
95
|
|
96
|
-
This requires you to install `pry` using `
|
96
|
+
This requires you to install `pry` using `gem install pry`. `pry` is not installed by default, as most [_fastlane_](https://fastlane.tools) users won't need the `spaceship playground`. You can add the `pry` dependency to your `Gemfile`.
|
97
97
|
|
98
98
|
## Apple Developer Portal API
|
99
99
|
|
@@ -134,7 +134,7 @@ module Spaceship
|
|
134
134
|
if teams.count > 1
|
135
135
|
puts("The current user is in #{teams.count} teams. Pass a team ID or call `select_team` to choose a team. Using the first one for now.")
|
136
136
|
end
|
137
|
-
@current_team_id ||=
|
137
|
+
@current_team_id ||= user_details_data['sessionToken']['contentProviderId']
|
138
138
|
end
|
139
139
|
|
140
140
|
# Set a new team ID which will be used from now on
|
@@ -171,6 +171,9 @@ module Spaceship
|
|
171
171
|
|
172
172
|
handle_itc_response(response.body)
|
173
173
|
|
174
|
+
# clear user_details_data cache, as session switch will have changed sessionToken attribute
|
175
|
+
@_cached_user_details = nil
|
176
|
+
|
174
177
|
@current_team_id = team_id
|
175
178
|
end
|
176
179
|
|
@@ -880,10 +883,7 @@ module Spaceship
|
|
880
883
|
response = @client.send(method, url_or_path, params, headers, &block)
|
881
884
|
log_response(method, url_or_path, response, headers, &block)
|
882
885
|
|
883
|
-
|
884
|
-
if resp_hash[:status] == 401
|
885
|
-
handle_401(response)
|
886
|
-
end
|
886
|
+
handle_error(response)
|
887
887
|
|
888
888
|
if response.body.to_s.include?("<title>302 Found</title>")
|
889
889
|
raise AppleTimeoutError.new, "Apple 302 detected - this might be temporary server error, check https://developer.apple.com/system-status/ to see if there is a known downtime"
|
@@ -893,22 +893,23 @@ module Spaceship
|
|
893
893
|
raise BadGatewayError.new, "Apple 502 detected - this might be temporary server error, try again later"
|
894
894
|
end
|
895
895
|
|
896
|
-
if resp_hash[:status] == 403
|
897
|
-
msg = "Access forbidden"
|
898
|
-
logger.warn(msg)
|
899
|
-
raise AccessForbiddenError.new, msg
|
900
|
-
elsif resp_hash[:status] == 429
|
901
|
-
raise TooManyRequestsError, resp_hash
|
902
|
-
end
|
903
|
-
|
904
896
|
return response
|
905
897
|
end
|
906
898
|
end
|
907
899
|
|
908
|
-
def
|
909
|
-
|
910
|
-
|
911
|
-
|
900
|
+
def handle_error(response)
|
901
|
+
case response.status
|
902
|
+
when 401
|
903
|
+
msg = "Auth lost"
|
904
|
+
logger.warn(msg)
|
905
|
+
raise UnauthorizedAccessError.new, "Unauthorized Access"
|
906
|
+
when 403
|
907
|
+
msg = "Access forbidden"
|
908
|
+
logger.warn(msg)
|
909
|
+
raise AccessForbiddenError.new, msg
|
910
|
+
when 429
|
911
|
+
raise TooManyRequestsError, response.to_hash
|
912
|
+
end
|
912
913
|
end
|
913
914
|
|
914
915
|
def send_request_auto_paginate(method, url_or_path, params, headers, &block)
|
@@ -150,6 +150,12 @@ module Spaceship
|
|
150
150
|
|
151
151
|
protected
|
152
152
|
|
153
|
+
class TimeoutRetryError < StandardError
|
154
|
+
def initialize(msg)
|
155
|
+
super
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
153
159
|
def with_asc_retry(tries = 5, &_block)
|
154
160
|
tries = 1 if Object.const_defined?("SpecHelper")
|
155
161
|
|
@@ -159,7 +165,7 @@ module Spaceship
|
|
159
165
|
|
160
166
|
if [500, 504].include?(status)
|
161
167
|
msg = "Timeout received! Retrying after 3 seconds (remaining: #{tries})..."
|
162
|
-
raise msg
|
168
|
+
raise TimeoutRetryError, msg
|
163
169
|
end
|
164
170
|
|
165
171
|
return response
|
@@ -167,7 +173,7 @@ module Spaceship
|
|
167
173
|
# Catch unathorized access and re-raising
|
168
174
|
# There is no need to try again
|
169
175
|
raise error
|
170
|
-
rescue => error
|
176
|
+
rescue TimeoutRetryError => error
|
171
177
|
tries -= 1
|
172
178
|
puts(error) if Spaceship::Globals.verbose?
|
173
179
|
if tries.zero?
|
@@ -190,7 +196,7 @@ module Spaceship
|
|
190
196
|
|
191
197
|
raise UnexpectedResponse, response.body['error'] if response.body['error']
|
192
198
|
|
193
|
-
raise UnexpectedResponse,
|
199
|
+
raise UnexpectedResponse, format_errors(response) if response.body['errors']
|
194
200
|
|
195
201
|
raise UnexpectedResponse, "Temporary App Store Connect error: #{response.body}" if response.body['statusCode'] == 'ERROR'
|
196
202
|
|
@@ -199,11 +205,23 @@ module Spaceship
|
|
199
205
|
return Spaceship::ConnectAPI::Response.new(body: response.body, status: response.status, headers: response.headers, client: self)
|
200
206
|
end
|
201
207
|
|
202
|
-
|
203
|
-
|
208
|
+
# Overridden from Spaceship::Client
|
209
|
+
def handle_error(response)
|
210
|
+
case response.status.to_i
|
211
|
+
when 401
|
212
|
+
raise UnauthorizedAccessError, format_errors(response) if response && (response.body || {})['errors']
|
213
|
+
when 403
|
214
|
+
error = (response.body['errors'] || []).first || {}
|
215
|
+
error_code = error['code']
|
216
|
+
if error_code == "FORBIDDEN.REQUIRED_AGREEMENTS_MISSING_OR_EXPIRED"
|
217
|
+
raise ProgramLicenseAgreementUpdated, format_errors(response) if response && (response.body || {})['errors']
|
218
|
+
else
|
219
|
+
raise AccessForbiddenError, format_errors(response) if response && (response.body || {})['errors']
|
220
|
+
end
|
221
|
+
end
|
204
222
|
end
|
205
223
|
|
206
|
-
def
|
224
|
+
def format_errors(response)
|
207
225
|
# Example error format
|
208
226
|
# {
|
209
227
|
# "errors":[
|