fastlane 2.143.0 → 2.147.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +82 -82
- data/credentials_manager/lib/credentials_manager/appfile_config.rb +4 -0
- data/deliver/lib/deliver/app_screenshot.rb +1 -0
- data/deliver/lib/deliver/options.rb +30 -1
- data/deliver/lib/deliver/setup.rb +4 -4
- data/fastlane/lib/assets/custom_action_template.rb +6 -6
- data/fastlane/lib/fastlane/actions/automatic_code_signing.rb +7 -1
- data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +3 -0
- data/fastlane/lib/fastlane/actions/cocoapods.rb +1 -1
- data/fastlane/lib/fastlane/actions/crashlytics.rb +14 -2
- data/fastlane/lib/fastlane/actions/create_pull_request.rb +7 -1
- data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +13 -5
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +3 -3
- data/fastlane/lib/fastlane/actions/get_version_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/git_branch.rb +1 -1
- data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +7 -1
- data/fastlane/lib/fastlane/actions/set_pod_key.rb +3 -3
- data/fastlane/lib/fastlane/actions/setup_ci.rb +1 -1
- data/fastlane/lib/fastlane/actions/setup_jenkins.rb +11 -2
- data/fastlane/lib/fastlane/actions/slather.rb +1 -1
- data/fastlane/lib/fastlane/actions/swiftlint.rb +28 -7
- data/fastlane/lib/fastlane/actions/testfairy.rb +18 -3
- data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +203 -0
- data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -1
- data/fastlane/lib/fastlane/actions/verify_build.rb +1 -1
- data/fastlane/lib/fastlane/actions/verify_xcode.rb +7 -0
- data/fastlane/lib/fastlane/commands_generator.rb +4 -1
- data/fastlane/lib/fastlane/helper/lane_helper.rb +13 -0
- data/fastlane/lib/fastlane/helper/s3_client_helper.rb +14 -9
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/Fastlane.swift +138 -23
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +6 -2
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +10 -2
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
- data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +9 -0
- data/fastlane_core/lib/fastlane_core/device_manager.rb +3 -3
- data/fastlane_core/lib/fastlane_core/helper.rb +17 -0
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +46 -2
- data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +15 -2
- data/frameit/lib/frameit/device_types.rb +10 -0
- data/frameit/lib/frameit/editor.rb +1 -1
- data/frameit/lib/frameit/options.rb +5 -2
- data/frameit/lib/frameit/runner.rb +5 -0
- data/frameit/lib/frameit/screenshot.rb +5 -0
- data/gym/lib/gym/generators/package_command_generator.rb +4 -0
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +5 -0
- data/gym/lib/gym/runner.rb +14 -0
- data/match/lib/match/change_password.rb +1 -18
- data/match/lib/match/encryption/openssl.rb +1 -1
- data/match/lib/match/generator.rb +5 -1
- data/match/lib/match/importer.rb +35 -18
- data/match/lib/match/options.rb +6 -1
- data/match/lib/match/storage/s3_storage.rb +10 -5
- data/match/lib/match/utils.rb +1 -1
- data/pilot/lib/pilot/build_manager.rb +15 -4
- data/pilot/lib/pilot/options.rb +8 -0
- data/produce/lib/produce/developer_center.rb +11 -2
- data/produce/lib/produce/itunes_connect.rb +11 -3
- data/produce/lib/produce/options.rb +12 -0
- data/scan/lib/scan/options.rb +11 -1
- data/scan/lib/scan/runner.rb +2 -0
- data/scan/lib/scan/test_command_generator.rb +4 -1
- data/screengrab/lib/screengrab/runner.rb +1 -1
- data/snapshot/lib/assets/SnapfileTemplate +3 -0
- data/snapshot/lib/snapshot/options.rb +10 -0
- data/snapshot/lib/snapshot/reports_generator.rb +4 -0
- data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +4 -0
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +21 -0
- data/snapshot/lib/snapshot/test_command_generator_base.rb +3 -0
- data/spaceship/lib/spaceship/base.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/model.rb +6 -0
- data/spaceship/lib/spaceship/connect_api/models/app.rb +11 -0
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +23 -0
- data/spaceship/lib/spaceship/portal/app_service.rb +2 -2
- data/spaceship/lib/spaceship/portal/portal_client.rb +13 -0
- data/spaceship/lib/spaceship/tunes/app_version.rb +6 -1
- data/spaceship/lib/spaceship/tunes/application.rb +2 -1
- data/spaceship/lib/spaceship/tunes/iap.rb +15 -0
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +16 -2
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +52 -16
- data/supply/lib/supply/.client.rb.swp +0 -0
- data/supply/lib/supply/client.rb +4 -4
- data/supply/lib/supply/setup.rb +5 -3
- metadata +40 -32
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/pilot/lib/pilot/.manager.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
data/scan/lib/scan/runner.rb
CHANGED
@@ -45,6 +45,9 @@ module Scan
|
|
45
45
|
options << "-enableCodeCoverage #{config[:code_coverage] ? 'YES' : 'NO'}" unless config[:code_coverage].nil?
|
46
46
|
options << "-enableAddressSanitizer #{config[:address_sanitizer] ? 'YES' : 'NO'}" unless config[:address_sanitizer].nil?
|
47
47
|
options << "-enableThreadSanitizer #{config[:thread_sanitizer] ? 'YES' : 'NO'}" unless config[:thread_sanitizer].nil?
|
48
|
+
if FastlaneCore::Helper.xcode_at_least?(11)
|
49
|
+
options << "-testPlan '#{config[:testplan]}'" if config[:testplan]
|
50
|
+
end
|
48
51
|
options << "-xctestrun '#{config[:xctestrun]}'" if config[:xctestrun]
|
49
52
|
options << config[:xcargs] if config[:xcargs]
|
50
53
|
|
@@ -82,7 +85,7 @@ module Scan
|
|
82
85
|
def pipe
|
83
86
|
pipe = ["| tee '#{xcodebuild_log_path}'"]
|
84
87
|
|
85
|
-
if Scan.config[:output_style] == 'raw'
|
88
|
+
if Scan.config[:disable_xcpretty] || Scan.config[:output_style] == 'raw'
|
86
89
|
return pipe
|
87
90
|
end
|
88
91
|
|
@@ -63,7 +63,7 @@ module Screengrab
|
|
63
63
|
|
64
64
|
# Root is needed to access device paths at /data
|
65
65
|
if @config[:use_adb_root]
|
66
|
-
run_adb_command("root", print_all: false, print_command: true)
|
66
|
+
run_adb_command("-s #{device_serial} root", print_all: false, print_command: true)
|
67
67
|
end
|
68
68
|
|
69
69
|
clear_device_previous_screenshots(device_serial, device_screenshots_paths)
|
@@ -27,6 +27,9 @@
|
|
27
27
|
# remove the '#' to clear all previously generated screenshots before creating new ones
|
28
28
|
# clear_previous_screenshots(true)
|
29
29
|
|
30
|
+
# Remove the '#' to set the status bar to 9:41 AM, and show full battery and reception.
|
31
|
+
# override_status_bar(true)
|
32
|
+
|
30
33
|
# Arguments to pass to the app on launch. See https://docs.fastlane.tools/actions/snapshot/#launch-arguments
|
31
34
|
# launch_arguments(["-favColor red"])
|
32
35
|
|
@@ -111,6 +111,11 @@ module Snapshot
|
|
111
111
|
description: "Enabling this option will automatically erase the simulator before running the application",
|
112
112
|
default_value: false,
|
113
113
|
is_string: false),
|
114
|
+
FastlaneCore::ConfigItem.new(key: :override_status_bar,
|
115
|
+
env_name: 'SNAPSHOT_OVERRIDE_STATUS_BAR',
|
116
|
+
description: "Enabling this option wil automatically override the status bar to show 9:41 AM, full battery, and full reception",
|
117
|
+
default_value: false,
|
118
|
+
is_string: false),
|
114
119
|
FastlaneCore::ConfigItem.new(key: :localize_simulator,
|
115
120
|
env_name: 'SNAPSHOT_LOCALIZE_SIMULATOR',
|
116
121
|
description: "Enabling this option will configure the Simulator's system language",
|
@@ -232,6 +237,11 @@ module Snapshot
|
|
232
237
|
env_name: "SNAPSHOT_CLONED_SOURCE_PACKAGES_PATH",
|
233
238
|
description: "Sets a custom path for Swift Package Manager dependencies",
|
234
239
|
type: String,
|
240
|
+
optional: true),
|
241
|
+
FastlaneCore::ConfigItem.new(key: :testplan,
|
242
|
+
env_name: "SNAPSHOT_TESTPLAN",
|
243
|
+
description: "The testplan associated with the scheme that should be used for testing",
|
244
|
+
is_string: true,
|
235
245
|
optional: true)
|
236
246
|
]
|
237
247
|
end
|
@@ -97,13 +97,17 @@ module Snapshot
|
|
97
97
|
'iPhone SE' => "iPhone SE",
|
98
98
|
'iPhone 4s' => "iPhone 4s (3.5-Inch)",
|
99
99
|
'iPad 2' => 'iPad 2',
|
100
|
+
'iPad Air (3rd generation)' => 'iPad Air (3rd generation)',
|
100
101
|
'iPad Air 2' => 'iPad Air 2',
|
101
102
|
'iPad Air' => 'iPad Air',
|
102
103
|
'iPad (5th generation)' => 'iPad (5th generation)',
|
104
|
+
'iPad (7th generation)' => 'iPad (7th generation)',
|
103
105
|
'iPad Pro (9.7-inch)' => 'iPad Pro (9.7-inch)',
|
104
106
|
'iPad Pro (9.7 inch)' => 'iPad Pro (9.7-inch)', # iOS 10.3.1 simulator
|
105
107
|
'iPad Pro (10.5-inch)' => 'iPad Pro (10.5-inch)',
|
108
|
+
'iPad Pro (11-inch) (2nd generation)' => 'iPad Pro (11-inch) (2nd generation)',
|
106
109
|
'iPad Pro (11-inch)' => 'iPad Pro (11-inch)',
|
110
|
+
'iPad Pro (12.9-inch) (4th generation)' => 'iPad Pro (12.9-inch) (4th generation)',
|
107
111
|
'iPad Pro (12.9-inch) (3rd generation)' => 'iPad Pro (12.9-inch) (3rd generation)',
|
108
112
|
'iPad Pro (12.9-inch) (2nd generation)' => 'iPad Pro (12.9-inch) (2nd generation)',
|
109
113
|
'iPad Pro (12.9-inch)' => 'iPad Pro (12.9-inch)',
|
@@ -12,6 +12,7 @@ module Snapshot
|
|
12
12
|
attr_accessor :reinstall_app
|
13
13
|
attr_accessor :app_identifier
|
14
14
|
attr_accessor :disable_slide_to_type
|
15
|
+
attr_accessor :override_status_bar
|
15
16
|
|
16
17
|
# xcode 8
|
17
18
|
attr_accessor :number_of_retries
|
@@ -43,6 +44,7 @@ module Snapshot
|
|
43
44
|
@output_directory = snapshot_config[:output_directory]
|
44
45
|
@concurrent_simulators = snapshot_config[:concurrent_simulators]
|
45
46
|
@disable_slide_to_type = snapshot_config[:disable_slide_to_type]
|
47
|
+
@override_status_bar = snapshot_config[:override_status_bar]
|
46
48
|
|
47
49
|
launch_arguments = Array(snapshot_config[:launch_arguments])
|
48
50
|
# if more than 1 set of arguments, use a tuple with an index
|
@@ -89,10 +89,14 @@ module Snapshot
|
|
89
89
|
log_path: xcodebuild_log_path(language: language, locale: locale)
|
90
90
|
)
|
91
91
|
|
92
|
+
devices.each { |device_type| override_status_bar(device_type) } if launcher_config.override_status_bar
|
93
|
+
|
92
94
|
UI.important("Running snapshot on: #{devices.join(', ')}")
|
93
95
|
|
94
96
|
execute(command: command, language: language, locale: locale, launch_args: launch_arguments, devices: devices)
|
95
97
|
|
98
|
+
devices.each { |device_type| clear_status_bar(device_type) } if launcher_config.override_status_bar
|
99
|
+
|
96
100
|
return copy_screenshots(language: language, locale: locale, launch_args: launch_arguments)
|
97
101
|
end
|
98
102
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'plist'
|
2
|
+
require 'time'
|
2
3
|
|
3
4
|
require_relative '../module'
|
4
5
|
require_relative '../test_command_generator'
|
@@ -102,6 +103,26 @@ module Snapshot
|
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
106
|
+
def override_status_bar(device_type)
|
107
|
+
device_udid = TestCommandGenerator.device_udid(device_type)
|
108
|
+
|
109
|
+
UI.message("Launch Simulator #{device_type}")
|
110
|
+
Helper.backticks("xcrun instruments -w #{device_udid} &> /dev/null")
|
111
|
+
|
112
|
+
UI.message("Overriding Status Bar")
|
113
|
+
|
114
|
+
# The time needs to be passed as ISO8601 so the simulator formats it correctly
|
115
|
+
time = Time.new(2007, 1, 9, 9, 41, 0)
|
116
|
+
Helper.backticks("xcrun simctl status_bar #{device_udid} override --time #{time.iso8601} --dataNetwork wifi --wifiMode active --wifiBars 3 --cellularMode active --cellularBars 4 --batteryState charged --batteryLevel 100 &> /dev/null")
|
117
|
+
end
|
118
|
+
|
119
|
+
def clear_status_bar(device_type)
|
120
|
+
device_udid = TestCommandGenerator.device_udid(device_type)
|
121
|
+
|
122
|
+
UI.message("Clearing Status Bar Override")
|
123
|
+
Helper.backticks("xcrun simctl status_bar #{device_udid} clear &> /dev/null")
|
124
|
+
end
|
125
|
+
|
105
126
|
def uninstall_app(device_type)
|
106
127
|
launcher_config.app_identifier ||= UI.input("App Identifier: ")
|
107
128
|
device_udid = TestCommandGenerator.device_udid(device_type)
|
@@ -26,6 +26,9 @@ module Snapshot
|
|
26
26
|
options << "-sdk '#{config[:sdk]}'" if config[:sdk]
|
27
27
|
options << "-derivedDataPath '#{derived_data_path}'"
|
28
28
|
options << "-resultBundlePath '#{result_bundle_path}'" if result_bundle_path
|
29
|
+
if FastlaneCore::Helper.xcode_at_least?(11)
|
30
|
+
options << "-testPlan '#{config[:testplan]}'" if config[:testplan]
|
31
|
+
end
|
29
32
|
options << config[:xcargs] if config[:xcargs]
|
30
33
|
return options
|
31
34
|
end
|
@@ -103,6 +103,17 @@ module Spaceship
|
|
103
103
|
resps = Spaceship::ConnectAPI.get_beta_groups(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
|
104
104
|
return resps.flat_map(&:to_models)
|
105
105
|
end
|
106
|
+
|
107
|
+
def create_beta_group(group_name: nil, public_link_enabled: false, public_link_limit: 10_000, public_link_limit_enabled: false)
|
108
|
+
resps = Spaceship::ConnectAPI.create_beta_group(
|
109
|
+
app_id: id,
|
110
|
+
group_name: group_name,
|
111
|
+
public_link_enabled: public_link_enabled,
|
112
|
+
public_link_limit: public_link_limit,
|
113
|
+
public_link_limit_enabled: public_link_limit_enabled
|
114
|
+
).all_pages
|
115
|
+
return resps.flat_map(&:to_models).first
|
116
|
+
end
|
106
117
|
end
|
107
118
|
end
|
108
119
|
end
|
@@ -181,6 +181,29 @@ module Spaceship
|
|
181
181
|
Client.instance.post("builds/#{build_id}/relationships/betaGroups", body)
|
182
182
|
end
|
183
183
|
|
184
|
+
def create_beta_group(app_id: nil, group_name: nil, public_link_enabled: false, public_link_limit: 10_000, public_link_limit_enabled: false)
|
185
|
+
body = {
|
186
|
+
data: {
|
187
|
+
attributes: {
|
188
|
+
name: group_name,
|
189
|
+
publicLinkEnabled: public_link_enabled,
|
190
|
+
publicLinkLimit: public_link_limit,
|
191
|
+
publicLinkLimitEnabled: public_link_limit_enabled
|
192
|
+
},
|
193
|
+
relationships: {
|
194
|
+
app: {
|
195
|
+
data: {
|
196
|
+
id: app_id,
|
197
|
+
type: "apps"
|
198
|
+
}
|
199
|
+
}
|
200
|
+
},
|
201
|
+
type: "betaGroups"
|
202
|
+
}
|
203
|
+
}
|
204
|
+
Client.instance.post("betaGroups", body)
|
205
|
+
end
|
206
|
+
|
184
207
|
#
|
185
208
|
# betaTesters
|
186
209
|
#
|
@@ -59,11 +59,11 @@ module Spaceship
|
|
59
59
|
NetworkExtension = AppService.new_service("NWEXT04537")
|
60
60
|
NFCTagReading = AppService.new_service("NFCTRMAY17")
|
61
61
|
PersonalVPN = AppService.new_service("V66P55NK2I")
|
62
|
-
Passbook = AppService.new_service("
|
62
|
+
Passbook = AppService.new_service("passbook")
|
63
63
|
PushNotification = AppService.new_service("push")
|
64
64
|
SiriKit = AppService.new_service("SI015DKUHP")
|
65
65
|
VPNConfiguration = AppService.new_service("V66P55NK2I")
|
66
|
-
Wallet = AppService.new_service("
|
66
|
+
Wallet = AppService.new_service("passbook")
|
67
67
|
WirelessAccessory = AppService.new_service("WC421J6T7P")
|
68
68
|
|
69
69
|
constants.each do |c|
|
@@ -100,6 +100,19 @@ module Spaceship
|
|
100
100
|
end
|
101
101
|
private :platform_slug
|
102
102
|
|
103
|
+
def list_pending_agreements(language: "en")
|
104
|
+
r = request(:post) do |req|
|
105
|
+
req.url("account/listPendingAgreements")
|
106
|
+
req.body = {
|
107
|
+
teamId: team_id,
|
108
|
+
languageIsoCode: language
|
109
|
+
}.to_json
|
110
|
+
req.headers['Content-Type'] = 'application/json'
|
111
|
+
end
|
112
|
+
|
113
|
+
return parse_response(r)
|
114
|
+
end
|
115
|
+
|
103
116
|
#####################################################
|
104
117
|
# @!group Apps
|
105
118
|
#####################################################
|
@@ -767,14 +767,19 @@ module Spaceship
|
|
767
767
|
end
|
768
768
|
|
769
769
|
def setup_screenshots
|
770
|
-
# Enable Scaling for all screen sizes that don't have at least one screenshot
|
770
|
+
# Enable Scaling for all screen sizes that don't have at least one screenshot or at least one trailer (app_preview)
|
771
771
|
# We automatically disable scaling once we upload at least one screenshot
|
772
772
|
language_details = raw_data_details.each do |current_language|
|
773
773
|
language_details = (current_language["displayFamilies"] || {})["value"]
|
774
774
|
(language_details || []).each do |device_language_details|
|
775
|
+
# Do not enable scaling if a screenshot already exists
|
775
776
|
next if device_language_details["screenshots"].nil?
|
776
777
|
next if device_language_details["screenshots"]["value"].count > 0
|
777
778
|
|
779
|
+
# Do not enable scaling if a trailer already exists
|
780
|
+
next if device_language_details["trailers"].nil?
|
781
|
+
next if device_language_details["trailers"]["value"].count > 0
|
782
|
+
|
778
783
|
# The current row includes screenshots for all device types
|
779
784
|
# so we need to enable scaling for both iOS and watchOS apps
|
780
785
|
device_language_details["scaled"]["value"] = true if device_language_details["scaled"]
|
@@ -91,7 +91,7 @@ module Spaceship
|
|
91
91
|
# @param platform (String): Platform one of (ios,osx)
|
92
92
|
# should it be an ios or an osx app
|
93
93
|
|
94
|
-
def create!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil, company_name: nil, platform: nil, itunes_connect_users: nil)
|
94
|
+
def create!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil, company_name: nil, platform: nil, platforms: nil, itunes_connect_users: nil)
|
95
95
|
puts("The `version` parameter is deprecated. Use `ensure_version!` method instead") if version
|
96
96
|
client.create_application!(name: name,
|
97
97
|
primary_language: primary_language,
|
@@ -100,6 +100,7 @@ module Spaceship
|
|
100
100
|
bundle_id_suffix: bundle_id_suffix,
|
101
101
|
company_name: company_name,
|
102
102
|
platform: platform,
|
103
|
+
platforms: platforms,
|
103
104
|
itunes_connect_users: itunes_connect_users)
|
104
105
|
end
|
105
106
|
|
@@ -132,6 +132,21 @@ module Spaceship
|
|
132
132
|
return nil
|
133
133
|
end
|
134
134
|
|
135
|
+
# generate app-specific shared secret (or regenerate if exists)
|
136
|
+
def generate_shared_secret
|
137
|
+
client.generate_shared_secret(app_id: self.application.apple_id)
|
138
|
+
end
|
139
|
+
|
140
|
+
# retrieve app-specific shared secret
|
141
|
+
# @param create (Boolean) Create new shared secret if does not exist
|
142
|
+
def get_shared_secret(create: false)
|
143
|
+
secret = client.get_shared_secret(app_id: self.application.apple_id)
|
144
|
+
if create && secret.nil?
|
145
|
+
secret = generate_shared_secret
|
146
|
+
end
|
147
|
+
secret
|
148
|
+
end
|
149
|
+
|
135
150
|
private
|
136
151
|
|
137
152
|
def find_product_with_retries(product_id, max_tries)
|
@@ -286,7 +286,7 @@ module Spaceship
|
|
286
286
|
# @param sku (String): A unique ID for your app that is not visible on the App Store.
|
287
287
|
# @param bundle_id (String): The bundle ID must match the one you used in Xcode. It
|
288
288
|
# can't be changed after you submit your first build.
|
289
|
-
def create_application!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil, company_name: nil, platform: nil, itunes_connect_users: nil)
|
289
|
+
def create_application!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil, company_name: nil, platform: nil, platforms: nil, itunes_connect_users: nil)
|
290
290
|
puts("The `version` parameter is deprecated. Use `Spaceship::Tunes::Application.ensure_version!` method instead") if version
|
291
291
|
|
292
292
|
# First, we need to fetch the data from Apple, which we then modify with the user's values
|
@@ -307,7 +307,7 @@ module Spaceship
|
|
307
307
|
data['enabledPlatformsForCreation'] = { value: [platform] }
|
308
308
|
|
309
309
|
data['initialPlatform'] = platform
|
310
|
-
data['enabledPlatformsForCreation'] = { value: [platform] }
|
310
|
+
data['enabledPlatformsForCreation'] = { value: platforms || [platform] }
|
311
311
|
|
312
312
|
unless itunes_connect_users.nil?
|
313
313
|
data['iTunesConnectUsers']['grantedAllUsers'] = false
|
@@ -1422,6 +1422,20 @@ module Spaceship
|
|
1422
1422
|
handle_itc_response(r.body)
|
1423
1423
|
end
|
1424
1424
|
|
1425
|
+
# Retrieves app-specific shared secret key
|
1426
|
+
def get_shared_secret(app_id: nil)
|
1427
|
+
r = request(:get, "ra/apps/#{app_id}/iaps/appSharedSecret")
|
1428
|
+
data = parse_response(r, 'data')
|
1429
|
+
data['sharedSecret']
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
# Generates app-specific shared secret key
|
1433
|
+
def generate_shared_secret(app_id: nil)
|
1434
|
+
r = request(:post, "ra/apps/#{app_id}/iaps/appSharedSecret")
|
1435
|
+
data = parse_response(r, 'data')
|
1436
|
+
data['sharedSecret']
|
1437
|
+
end
|
1438
|
+
|
1425
1439
|
#####################################################
|
1426
1440
|
# @!group Sandbox Testers
|
1427
1441
|
#####################################################
|
@@ -131,18 +131,33 @@ module Spaceship
|
|
131
131
|
puts("Environment variable `SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER` is set, automatically requesting 2FA token via SMS to that number")
|
132
132
|
puts("SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER = #{env_2fa_sms_default_phone_number}")
|
133
133
|
puts("")
|
134
|
+
|
134
135
|
phone_number = env_2fa_sms_default_phone_number
|
135
136
|
phone_id = phone_id_from_number(response.body["trustedPhoneNumbers"], phone_number)
|
137
|
+
# don't request sms if no trusted devices and env default is the only trusted number,
|
138
|
+
# code was automatically sent
|
139
|
+
should_request_code = !sms_automatically_sent(response)
|
140
|
+
code_type = 'phone'
|
141
|
+
body = request_two_factor_code_from_phone(phone_id, phone_number, code_length, should_request_code)
|
142
|
+
elsif sms_automatically_sent(response) # sms fallback, code was automatically sent
|
143
|
+
fallback_number = response.body["trustedPhoneNumbers"].first
|
144
|
+
phone_number = fallback_number["numberWithDialCode"]
|
145
|
+
phone_id = fallback_number["id"]
|
146
|
+
|
147
|
+
code_type = 'phone'
|
148
|
+
body = request_two_factor_code_from_phone(phone_id, phone_number, code_length, false)
|
149
|
+
elsif sms_fallback(response) # sms fallback but code wasn't sent bec > 1 phone number
|
136
150
|
code_type = 'phone'
|
137
|
-
body =
|
151
|
+
body = request_two_factor_code_from_phone_choose(response.body["trustedPhoneNumbers"], code_length)
|
138
152
|
else
|
139
153
|
puts("(Input `sms` to escape this prompt and select a trusted phone number to send the code as a text message)")
|
140
154
|
puts("")
|
141
155
|
puts("(You can also set the environment variable `SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER` to automate this)")
|
142
|
-
puts("(Read more at: https://github.com/fastlane/fastlane/blob/master/spaceship/docs/Authentication.md#auto-select-sms-via-
|
156
|
+
puts("(Read more at: https://github.com/fastlane/fastlane/blob/master/spaceship/docs/Authentication.md#auto-select-sms-via-spaceship_2fa_sms_default_phone_number)")
|
143
157
|
puts("")
|
144
|
-
|
158
|
+
|
145
159
|
code = ask_for_2fa_code("Please enter the #{code_length} digit code:")
|
160
|
+
code_type = 'trusteddevice'
|
146
161
|
body = { "securityCode" => { "code" => code.to_s } }.to_json
|
147
162
|
|
148
163
|
# User exited by entering `sms` and wants to choose phone number for SMS
|
@@ -191,11 +206,30 @@ module Spaceship
|
|
191
206
|
return true
|
192
207
|
end
|
193
208
|
|
209
|
+
# For reference in case auth behavior changes:
|
210
|
+
# The "noTrustedDevices" field is only present
|
211
|
+
# in the response for `GET /appleauth/auth`
|
212
|
+
|
213
|
+
# Account is not signed into any devices that can display a verification code
|
214
|
+
def sms_fallback(response)
|
215
|
+
response.body["noTrustedDevices"]
|
216
|
+
end
|
217
|
+
|
218
|
+
# see `sms_fallback` + account has only one trusted number for receiving an sms
|
219
|
+
def sms_automatically_sent(response)
|
220
|
+
(response.body["trustedPhoneNumbers"] || []).count == 1 && sms_fallback(response)
|
221
|
+
end
|
222
|
+
|
194
223
|
# extracted into its own method for testing
|
195
224
|
def ask_for_2fa_code(text)
|
196
225
|
ask(text)
|
197
226
|
end
|
198
227
|
|
228
|
+
# extracted into its own method for testing
|
229
|
+
def choose_phone_number(opts)
|
230
|
+
choose(*opts)
|
231
|
+
end
|
232
|
+
|
199
233
|
def phone_id_from_number(phone_numbers, phone_number)
|
200
234
|
characters_to_remove_from_phone_numbers = ' \-()"'
|
201
235
|
|
@@ -247,27 +281,29 @@ If it is, please open an issue at https://github.com/fastlane/fastlane/issues/ne
|
|
247
281
|
available = phone_numbers.collect do |current|
|
248
282
|
current['numberWithDialCode']
|
249
283
|
end
|
250
|
-
chosen =
|
284
|
+
chosen = choose_phone_number(available)
|
251
285
|
phone_id = phone_id_from_masked_number(phone_numbers, chosen)
|
252
286
|
|
253
287
|
request_two_factor_code_from_phone(phone_id, chosen, code_length)
|
254
288
|
end
|
255
289
|
|
256
290
|
# this is used in two places: after choosing a phone number and when a phone number is set via ENV var
|
257
|
-
def request_two_factor_code_from_phone(phone_id, phone_number, code_length)
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
291
|
+
def request_two_factor_code_from_phone(phone_id, phone_number, code_length, should_request_code = true)
|
292
|
+
if should_request_code
|
293
|
+
# Request code
|
294
|
+
r = request(:put) do |req|
|
295
|
+
req.url("https://idmsa.apple.com/appleauth/auth/verify/phone")
|
296
|
+
req.headers['Content-Type'] = 'application/json'
|
297
|
+
req.body = { "phoneNumber" => { "id" => phone_id }, "mode" => "sms" }.to_json
|
298
|
+
update_request_headers(req)
|
299
|
+
end
|
265
300
|
|
266
|
-
|
267
|
-
|
268
|
-
|
301
|
+
# we use `Spaceship::TunesClient.new.handle_itc_response`
|
302
|
+
# since this might be from the Dev Portal, but for 2 step
|
303
|
+
Spaceship::TunesClient.new.handle_itc_response(r.body)
|
269
304
|
|
270
|
-
|
305
|
+
puts("Successfully requested text message to #{phone_number}")
|
306
|
+
end
|
271
307
|
|
272
308
|
code = ask_for_2fa_code("Please enter the #{code_length} digit code you received at #{phone_number}:")
|
273
309
|
|