fastlane 2.211.0 → 2.212.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +96 -96
- data/deliver/lib/deliver/app_screenshot.rb +1 -0
- data/deliver/lib/deliver/runner.rb +2 -6
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +19 -2
- data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +1 -1
- data/fastlane/lib/fastlane/actions/xcodes.rb +17 -2
- data/fastlane/lib/fastlane/fast_file.rb +18 -5
- data/fastlane/lib/fastlane/features.rb +3 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Actions.swift +1 -1
- data/fastlane/swift/Appfile.swift +1 -1
- data/fastlane/swift/ArgumentProcessor.swift +1 -1
- data/fastlane/swift/Atomic.swift +1 -1
- data/fastlane/swift/ControlCommand.swift +1 -1
- data/fastlane/swift/Deliverfile.swift +2 -2
- data/fastlane/swift/DeliverfileProtocol.swift +2 -2
- data/fastlane/swift/Fastlane.swift +30 -6
- data/fastlane/swift/Gymfile.swift +2 -2
- data/fastlane/swift/GymfileProtocol.swift +6 -2
- data/fastlane/swift/LaneFileProtocol.swift +1 -1
- data/fastlane/swift/MainProcess.swift +1 -1
- data/fastlane/swift/Matchfile.swift +2 -2
- data/fastlane/swift/MatchfileProtocol.swift +3 -3
- data/fastlane/swift/OptionalConfigValue.swift +1 -1
- data/fastlane/swift/Plugins.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +2 -2
- data/fastlane/swift/PrecheckfileProtocol.swift +2 -2
- data/fastlane/swift/RubyCommand.swift +1 -1
- data/fastlane/swift/RubyCommandable.swift +1 -1
- data/fastlane/swift/Runner.swift +1 -1
- data/fastlane/swift/RunnerArgument.swift +1 -1
- data/fastlane/swift/Scanfile.swift +2 -2
- data/fastlane/swift/ScanfileProtocol.swift +6 -2
- data/fastlane/swift/Screengrabfile.swift +2 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
- data/fastlane/swift/Snapshotfile.swift +2 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +2 -2
- data/fastlane/swift/SocketClient.swift +1 -1
- data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
- data/fastlane/swift/SocketResponse.swift +1 -1
- data/fastlane/swift/formatting/Brewfile.lock.json +26 -18
- data/fastlane/swift/main.swift +1 -1
- data/fastlane_core/lib/fastlane_core/cert_checker.rb +9 -2
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +4 -2
- data/gym/lib/gym/generators/build_command_generator.rb +1 -0
- data/gym/lib/gym/options.rb +7 -0
- data/match/lib/match/importer.rb +4 -0
- data/match/lib/match/module.rb +1 -1
- data/scan/lib/scan/options.rb +5 -0
- data/scan/lib/scan/test_command_generator.rb +6 -1
- data/spaceship/lib/spaceship/client.rb +23 -0
- data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +17 -0
- data/spaceship/lib/spaceship/connect_api/models/build_bundle.rb +9 -0
- data/spaceship/lib/spaceship/connect_api/models/build_bundle_file_sizes.rb +34 -0
- data/spaceship/lib/spaceship/connect_api/models/device.rb +44 -4
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +19 -0
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +9 -0
- data/spaceship/lib/spaceship/connect_api.rb +1 -0
- data/spaceship/lib/spaceship/errors.rb +34 -0
- data/spaceship/lib/spaceship/hashcash.rb +52 -0
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +10 -2
- data/spaceship/lib/spaceship.rb +1 -0
- metadata +24 -22
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'tempfile'
|
2
2
|
require 'openssl'
|
3
3
|
|
4
|
+
require_relative 'features'
|
4
5
|
require_relative 'helper'
|
5
6
|
|
6
7
|
# WWDR Intermediate Certificates in https://www.apple.com/certificateauthority/
|
@@ -155,11 +156,17 @@ module FastlaneCore
|
|
155
156
|
keychain = wwdr_keychain
|
156
157
|
keychain = "-k #{keychain.shellescape}" unless keychain.empty?
|
157
158
|
|
158
|
-
|
159
|
+
# Attempts to fix an issue installing WWDR cert tends to fail on CIs
|
160
|
+
# https://github.com/fastlane/fastlane/issues/20960
|
161
|
+
curl_extras = ""
|
162
|
+
if FastlaneCore::Feature.enabled?('FASTLANE_WWDR_USE_HTTP1_AND_RETRIES')
|
163
|
+
curl_extras = "--http1.1 --retry 3 --retry-all-errors "
|
164
|
+
end
|
159
165
|
|
160
|
-
import_command = "curl -f -o #{filename} #{url} && security import #{filename} #{keychain}"
|
166
|
+
import_command = "curl #{curl_extras}-f -o #{filename} #{url} && security import #{filename} #{keychain}"
|
161
167
|
UI.verbose("Installing WWDR Cert: #{import_command}")
|
162
168
|
|
169
|
+
require 'open3'
|
163
170
|
stdout, stderr, status = Open3.capture3(import_command)
|
164
171
|
if FastlaneCore::Globals.verbose?
|
165
172
|
UI.command_output(stdout)
|
@@ -86,11 +86,13 @@ module FastlaneCore
|
|
86
86
|
|
87
87
|
def header(message)
|
88
88
|
format = format_string
|
89
|
-
|
89
|
+
# clamp to zero to prevent negative argument error below
|
90
|
+
available_width = [0, TTY::Screen.width - format.length].max
|
91
|
+
if message.length + 8 < available_width
|
90
92
|
message = "--- #{message} ---"
|
91
93
|
i = message.length
|
92
94
|
else
|
93
|
-
i =
|
95
|
+
i = available_width
|
94
96
|
end
|
95
97
|
success("-" * i)
|
96
98
|
success(message)
|
@@ -39,6 +39,7 @@ module Gym
|
|
39
39
|
options << "-destination '#{config[:destination]}'" if config[:destination]
|
40
40
|
options << "-archivePath #{archive_path.shellescape}" unless config[:skip_archive]
|
41
41
|
options << "-resultBundlePath '#{result_bundle_path}'" if config[:result_bundle]
|
42
|
+
options << "-showBuildTimingSummary" if config[:build_timing_summary]
|
42
43
|
if config[:use_system_scm] && !options.include?("-scmProvider system")
|
43
44
|
options << "-scmProvider system"
|
44
45
|
end
|
data/gym/lib/gym/options.rb
CHANGED
@@ -239,6 +239,13 @@ module Gym
|
|
239
239
|
default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
|
240
240
|
default_value_dynamic: true),
|
241
241
|
|
242
|
+
FastlaneCore::ConfigItem.new(key: :build_timing_summary,
|
243
|
+
env_name: "GYM_BUILD_TIMING_SUMMARY",
|
244
|
+
description: "Create a build timing summary",
|
245
|
+
type: Boolean,
|
246
|
+
default_value: false,
|
247
|
+
optional: true),
|
248
|
+
|
242
249
|
# xcpretty
|
243
250
|
FastlaneCore::ConfigItem.new(key: :disable_xcpretty,
|
244
251
|
env_name: "DISABLE_XCPRETTY",
|
data/match/lib/match/importer.rb
CHANGED
@@ -80,6 +80,10 @@ module Match
|
|
80
80
|
certificate_type = [
|
81
81
|
Spaceship::ConnectAPI::Certificate::CertificateType::MAC_INSTALLER_DISTRIBUTION
|
82
82
|
].join(',')
|
83
|
+
when :developer_id_installer
|
84
|
+
certificate_type = [
|
85
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_INSTALLER
|
86
|
+
].join(',')
|
83
87
|
else
|
84
88
|
UI.user_error!("Cert type '#{cert_type}' is not supported")
|
85
89
|
end
|
data/match/lib/match/module.rb
CHANGED
@@ -11,7 +11,7 @@ module Match
|
|
11
11
|
DESCRIPTION = "Easily sync your certificates and profiles across your team"
|
12
12
|
|
13
13
|
def self.environments
|
14
|
-
return %w(appstore adhoc development enterprise developer_id mac_installer_distribution)
|
14
|
+
return %w(appstore adhoc development enterprise developer_id mac_installer_distribution developer_id_installer)
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.storage_modes
|
data/scan/lib/scan/options.rb
CHANGED
@@ -315,6 +315,11 @@ module Scan
|
|
315
315
|
env_name: "SCAN_OUTPUT_XCTESTRUN",
|
316
316
|
description: "Should provide additional copy of .xctestrun file (settings.xctestrun) and place in output path?",
|
317
317
|
default_value: false),
|
318
|
+
FastlaneCore::ConfigItem.new(key: :result_bundle_path,
|
319
|
+
env_name: "SCAN_RESULT_BUNDLE_PATH",
|
320
|
+
description: "Custom path for the result bundle, overrides result_bundle",
|
321
|
+
type: String,
|
322
|
+
optional: true),
|
318
323
|
FastlaneCore::ConfigItem.new(key: :result_bundle,
|
319
324
|
short_option: "-z",
|
320
325
|
env_name: "SCAN_RESULT_BUNDLE",
|
@@ -53,7 +53,12 @@ module Scan
|
|
53
53
|
if config[:use_system_scm] && !options.include?("-scmProvider system")
|
54
54
|
options << "-scmProvider system"
|
55
55
|
end
|
56
|
-
|
56
|
+
if config[:result_bundle_path]
|
57
|
+
options << "-resultBundlePath '#{config[:result_bundle_path].shellescape}'"
|
58
|
+
Scan.cache[:result_bundle_path] = config[:result_bundle_path]
|
59
|
+
elsif config[:result_bundle]
|
60
|
+
options << "-resultBundlePath '#{result_bundle_path(true)}'"
|
61
|
+
end
|
57
62
|
if FastlaneCore::Helper.xcode_at_least?(10)
|
58
63
|
options << "-parallel-testing-enabled #{config[:parallel_testing] ? 'YES' : 'NO'}" unless config[:parallel_testing].nil?
|
59
64
|
options << "-parallel-testing-worker-count #{config[:concurrent_workers]}" if config[:concurrent_workers]
|
@@ -18,6 +18,7 @@ require_relative 'tunes/errors'
|
|
18
18
|
require_relative 'globals'
|
19
19
|
require_relative 'provider'
|
20
20
|
require_relative 'stats_middleware'
|
21
|
+
require_relative 'hashcash'
|
21
22
|
|
22
23
|
Faraday::Utils.default_params_encoder = Faraday::FlatParamsEncoder
|
23
24
|
|
@@ -490,6 +491,12 @@ module Spaceship
|
|
490
491
|
modified_cookie.gsub!(unescaped_important_cookie, escaped_important_cookie)
|
491
492
|
end
|
492
493
|
|
494
|
+
# Fixes issue https://github.com/fastlane/fastlane/issues/21071
|
495
|
+
# On 2023-02-23, Apple added a custom implementation
|
496
|
+
# of hashcash to their auth flow
|
497
|
+
# hashcash = nil
|
498
|
+
hashcash = self.fetch_hashcash
|
499
|
+
|
493
500
|
response = request(:post) do |req|
|
494
501
|
req.url("https://idmsa.apple.com/appleauth/auth/signin")
|
495
502
|
req.body = data.to_json
|
@@ -498,6 +505,7 @@ module Spaceship
|
|
498
505
|
req.headers['X-Apple-Widget-Key'] = self.itc_service_key
|
499
506
|
req.headers['Accept'] = 'application/json, text/javascript'
|
500
507
|
req.headers["Cookie"] = modified_cookie if modified_cookie
|
508
|
+
req.headers["X-Apple-HC"] = hashcash if hashcash
|
501
509
|
end
|
502
510
|
rescue UnauthorizedAccessError
|
503
511
|
raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
|
@@ -545,6 +553,21 @@ module Spaceship
|
|
545
553
|
end
|
546
554
|
# rubocop:enable Metrics/PerceivedComplexity
|
547
555
|
|
556
|
+
def fetch_hashcash
|
557
|
+
response = request(:get, "https://idmsa.apple.com/appleauth/auth/signin?widgetKey=#{self.itc_service_key}")
|
558
|
+
headers = response.headers
|
559
|
+
|
560
|
+
bits = headers["X-Apple-HC-Bits"]
|
561
|
+
challenge = headers["X-Apple-HC-Challenge"]
|
562
|
+
|
563
|
+
if bits.nil? || challenge.nil?
|
564
|
+
puts("Unable to find 'X-Apple-HC-Bits' and 'X-Apple-HC-Challenge' to make hashcash")
|
565
|
+
return nil
|
566
|
+
end
|
567
|
+
|
568
|
+
return Spaceship::Hashcash.make(bits: bits, challenge: challenge)
|
569
|
+
end
|
570
|
+
|
548
571
|
# Get the `itctx` from the new (22nd May 2017) API endpoint "olympus"
|
549
572
|
# Update (29th March 2019) olympus migrates to new appstoreconnect API
|
550
573
|
def fetch_olympus_session
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../model'
|
2
|
+
require_relative '../../errors'
|
2
3
|
module Spaceship
|
3
4
|
class ConnectAPI
|
4
5
|
class AppInfoLocalization
|
@@ -32,11 +33,15 @@ module Spaceship
|
|
32
33
|
client ||= Spaceship::ConnectAPI
|
33
34
|
attributes = reverse_attr_mapping(attributes)
|
34
35
|
client.patch_app_info_localization(app_info_localization_id: id, attributes: attributes)
|
36
|
+
rescue
|
37
|
+
raise Spaceship::AppStoreLocalizationError, @locale
|
35
38
|
end
|
36
39
|
|
37
40
|
def delete!(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
|
38
41
|
client ||= Spaceship::ConnectAPI
|
39
42
|
client.delete_app_info_localization(app_info_localization_id: id)
|
43
|
+
rescue
|
44
|
+
raise Spaceship::AppStoreLocalizationError, @locale
|
40
45
|
end
|
41
46
|
end
|
42
47
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative '../model'
|
2
2
|
require_relative './app_preview_set'
|
3
3
|
require_relative './app_screenshot_set'
|
4
|
+
require_relative '../../errors'
|
4
5
|
|
5
6
|
module Spaceship
|
6
7
|
class ConnectAPI
|
@@ -43,23 +44,31 @@ module Spaceship
|
|
43
44
|
client ||= Spaceship::ConnectAPI
|
44
45
|
resp = client.get_app_store_version_localization(app_store_version_localization_id: app_store_version_localization_id, filter: filter, includes: includes, limit: limit, sort: sort)
|
45
46
|
return resp.to_models
|
47
|
+
rescue
|
48
|
+
raise Spaceship::AppStoreLocalizationError, @locale
|
46
49
|
end
|
47
50
|
|
48
51
|
def self.all(client: nil, app_store_version_id: nil, filter: {}, includes: nil, limit: nil, sort: nil)
|
49
52
|
client ||= Spaceship::ConnectAPI
|
50
53
|
resp = client.get_app_store_version_localizations(app_store_version_id: app_store_version_id, filter: filter, includes: includes, limit: limit, sort: sort)
|
51
54
|
return resp.to_models
|
55
|
+
rescue
|
56
|
+
raise Spaceship::AppStoreLocalizationError, @locale
|
52
57
|
end
|
53
58
|
|
54
59
|
def update(client: nil, attributes: nil)
|
55
60
|
client ||= Spaceship::ConnectAPI
|
56
61
|
attributes = reverse_attr_mapping(attributes)
|
57
62
|
client.patch_app_store_version_localization(app_store_version_localization_id: id, attributes: attributes)
|
63
|
+
rescue
|
64
|
+
raise Spaceship::AppStoreLocalizationError, @locale
|
58
65
|
end
|
59
66
|
|
60
67
|
def delete!(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
|
61
68
|
client ||= Spaceship::ConnectAPI
|
62
69
|
client.delete_app_store_version_localization(app_store_version_localization_id: id)
|
70
|
+
rescue
|
71
|
+
raise Spaceship::AppStoreLocalizationError, @locale
|
63
72
|
end
|
64
73
|
|
65
74
|
#
|
@@ -71,12 +80,16 @@ module Spaceship
|
|
71
80
|
filter ||= {}
|
72
81
|
filter["appStoreVersionLocalization"] = id
|
73
82
|
return Spaceship::ConnectAPI::AppPreviewSet.all(client: client, filter: filter, includes: includes, limit: limit, sort: sort)
|
83
|
+
rescue
|
84
|
+
raise Spaceship::AppStoreAppPreviewError, @locale
|
74
85
|
end
|
75
86
|
|
76
87
|
def create_app_preview_set(client: nil, attributes: nil)
|
77
88
|
client ||= Spaceship::ConnectAPI
|
78
89
|
resp = client.post_app_preview_set(app_store_version_localization_id: id, attributes: attributes)
|
79
90
|
return resp.to_models.first
|
91
|
+
rescue
|
92
|
+
raise Spaceship::AppStoreAppPreviewError, @locale
|
80
93
|
end
|
81
94
|
|
82
95
|
#
|
@@ -86,12 +99,16 @@ module Spaceship
|
|
86
99
|
def get_app_screenshot_sets(client: nil, filter: {}, includes: "appScreenshots", limit: nil, sort: nil)
|
87
100
|
client ||= Spaceship::ConnectAPI
|
88
101
|
return Spaceship::ConnectAPI::AppScreenshotSet.all(client: client, app_store_version_localization_id: id, filter: filter, includes: includes, limit: limit, sort: sort)
|
102
|
+
rescue
|
103
|
+
raise Spaceship::AppStoreScreenshotError, @locale
|
89
104
|
end
|
90
105
|
|
91
106
|
def create_app_screenshot_set(client: nil, attributes: nil)
|
92
107
|
client ||= Spaceship::ConnectAPI
|
93
108
|
resp = client.post_app_screenshot_set(app_store_version_localization_id: id, attributes: attributes)
|
94
109
|
return resp.to_models.first
|
110
|
+
rescue
|
111
|
+
raise Spaceship::AppStoreScreenshotError, @locale
|
95
112
|
end
|
96
113
|
end
|
97
114
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../model'
|
2
|
+
require_relative './build_bundle_file_sizes'
|
2
3
|
module Spaceship
|
3
4
|
class ConnectAPI
|
4
5
|
class BuildBundle
|
@@ -54,6 +55,14 @@ module Spaceship
|
|
54
55
|
def self.type
|
55
56
|
return "buildBundles"
|
56
57
|
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# API
|
61
|
+
#
|
62
|
+
|
63
|
+
def build_bundle_file_sizes(client: nil)
|
64
|
+
@build_bundle_file_sizes ||= BuildBundleFileSizes.all(client: client, build_bundle_id: id)
|
65
|
+
end
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative '../model'
|
2
|
+
module Spaceship
|
3
|
+
class ConnectAPI
|
4
|
+
class BuildBundleFileSizes
|
5
|
+
include Spaceship::ConnectAPI::Model
|
6
|
+
|
7
|
+
attr_accessor :device_model
|
8
|
+
attr_accessor :os_version
|
9
|
+
attr_accessor :download_bytes
|
10
|
+
attr_accessor :install_bytes
|
11
|
+
|
12
|
+
attr_mapping({
|
13
|
+
"deviceModel" => "device_model",
|
14
|
+
"osVersion" => "os_version",
|
15
|
+
"downloadBytes" => "download_bytes",
|
16
|
+
"installBytes" => "install_bytes"
|
17
|
+
})
|
18
|
+
|
19
|
+
def self.type
|
20
|
+
return "buildBundleFileSizes"
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# API
|
25
|
+
#
|
26
|
+
|
27
|
+
def self.all(client: nil, build_bundle_id: nil, limit: 30)
|
28
|
+
client ||= Spaceship::ConnectAPI
|
29
|
+
resps = client.get_build_bundles_build_bundle_file_sizes(build_bundle_id: build_bundle_id).all_pages
|
30
|
+
resps.flat_map(&:to_models)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -61,7 +61,7 @@ module Spaceship
|
|
61
61
|
# @param platform [String] The platform of the device.
|
62
62
|
# @param include_disabled [Bool] Whether to include disable devices. false by default.
|
63
63
|
# @return (Device) Find a device based on the UDID of the device. nil if no device was found.
|
64
|
-
def self.find_by_udid(device_udid, client: nil,
|
64
|
+
def self.find_by_udid(device_udid, client: nil, include_disabled: false)
|
65
65
|
self.all(client: client).find do |device|
|
66
66
|
device.udid.casecmp(device_udid) == 0 && (include_disabled ? true : device.enabled?)
|
67
67
|
end
|
@@ -70,10 +70,9 @@ module Spaceship
|
|
70
70
|
# @param client [ConnectAPI] ConnectAPI client.
|
71
71
|
# @param name [String] The name to be assigned to the device, if it needs to be created.
|
72
72
|
# @param platform [String] The platform of the device.
|
73
|
-
# @param include_disabled [Bool] Whether to include disable devices. false by default.
|
74
73
|
# @return (Device) Find a device based on the UDID of the device. If no device was found, nil if no device was found.
|
75
|
-
def self.find_or_create(device_udid, client: nil, name: nil, platform: nil
|
76
|
-
existing = self.find_by_udid(device_udid, client: client
|
74
|
+
def self.find_or_create(device_udid, client: nil, name: nil, platform: nil)
|
75
|
+
existing = self.find_by_udid(device_udid, client: client)
|
77
76
|
return existing if existing
|
78
77
|
return self.create(client: client, name: name, platform: platform, udid: device_udid)
|
79
78
|
end
|
@@ -88,6 +87,47 @@ module Spaceship
|
|
88
87
|
resp = client.post_device(name: name, platform: platform, udid: udid)
|
89
88
|
return resp.to_models.first
|
90
89
|
end
|
90
|
+
|
91
|
+
# @param device_udid [String] Device Provisioning UDID that needs to be modified.
|
92
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
93
|
+
# @param enabled [Boolean] New enabled value. true - if device must be enabled, `false` - to disable device. nil if no status change needed.
|
94
|
+
# @param new_name [String] A new name for the device. nil if no name change needed.
|
95
|
+
# @return (Device) Modified device based on the UDID of the device. nil if no device was found.
|
96
|
+
def self.modify(device_udid, client: nil, enabled: nil, new_name: nil)
|
97
|
+
client ||= Spaceship::ConnectAPI
|
98
|
+
existing = self.find_by_udid(device_udid, client: client, include_disabled: true)
|
99
|
+
return nil if existing.nil?
|
100
|
+
|
101
|
+
enabled = existing.enabled? if enabled.nil?
|
102
|
+
new_name ||= existing.name
|
103
|
+
return existing if existing.name == new_name && existing.enabled? == enabled
|
104
|
+
new_status = enabled ? Status::ENABLED : Status::DISABLED
|
105
|
+
|
106
|
+
resp = client.patch_device(id: existing.id, new_name: new_name, status: new_status)
|
107
|
+
return resp.to_models.first
|
108
|
+
end
|
109
|
+
|
110
|
+
# @param device_udid [String] Device Provisioning UDID that needs to be enabled.
|
111
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
112
|
+
# @return (Device) Modified device based on the UDID of the device. nil if no device was found.
|
113
|
+
def self.enable(device_udid, client: nil)
|
114
|
+
self.modify(device_udid, client: client, enabled: true)
|
115
|
+
end
|
116
|
+
|
117
|
+
# @param device_udid [String] Device Provisioning UDID that needs to be disabled.
|
118
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
119
|
+
# @return (Device) Modified device based on the UDID of the device. nil if no device was found.
|
120
|
+
def self.disable(device_udid, client: nil)
|
121
|
+
self.modify(device_udid, client: client, enabled: false)
|
122
|
+
end
|
123
|
+
|
124
|
+
# @param device_udid [String] Device Provisioning UDID that needs to be renamed.
|
125
|
+
# @param new_name [String] A new name for the device.
|
126
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
127
|
+
# @return (Device) Modified device based on the UDID of the device. nil if no device was found.
|
128
|
+
def self.rename(device_udid, new_name, client: nil)
|
129
|
+
self.modify(device_udid, client: client, new_name: new_name)
|
130
|
+
end
|
91
131
|
end
|
92
132
|
end
|
93
133
|
end
|
@@ -190,6 +190,25 @@ module Spaceship
|
|
190
190
|
provisioning_request_client.post("devices", body)
|
191
191
|
end
|
192
192
|
|
193
|
+
def patch_device(id: nil, status: nil, new_name: nil)
|
194
|
+
raise "Device id is nil" if id.nil?
|
195
|
+
|
196
|
+
attributes = {
|
197
|
+
name: new_name,
|
198
|
+
status: status
|
199
|
+
}
|
200
|
+
|
201
|
+
body = {
|
202
|
+
data: {
|
203
|
+
attributes: attributes,
|
204
|
+
id: id,
|
205
|
+
type: "devices"
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
provisioning_request_client.patch("devices/#{id}", body)
|
210
|
+
end
|
211
|
+
|
193
212
|
#
|
194
213
|
# profiles
|
195
214
|
#
|
@@ -412,6 +412,15 @@ module Spaceship
|
|
412
412
|
test_flight_request_client.get("betaTesterMetrics", params)
|
413
413
|
end
|
414
414
|
|
415
|
+
#
|
416
|
+
# buildBundles
|
417
|
+
#
|
418
|
+
|
419
|
+
def get_build_bundles_build_bundle_file_sizes(build_bundle_id:, limit: nil)
|
420
|
+
params = test_flight_request_client.build_params(filter: nil, includes: nil, limit: limit, sort: nil, cursor: nil)
|
421
|
+
test_flight_request_client.get("buildBundles/#{build_bundle_id}/buildBundleFileSizes", params)
|
422
|
+
end
|
423
|
+
|
415
424
|
#
|
416
425
|
# builds
|
417
426
|
#
|
@@ -33,6 +33,7 @@ require 'spaceship/connect_api/models/build'
|
|
33
33
|
require 'spaceship/connect_api/models/build_delivery'
|
34
34
|
require 'spaceship/connect_api/models/build_beta_detail'
|
35
35
|
require 'spaceship/connect_api/models/build_bundle'
|
36
|
+
require 'spaceship/connect_api/models/build_bundle_file_sizes'
|
36
37
|
require 'spaceship/connect_api/models/custom_app_organization'
|
37
38
|
require 'spaceship/connect_api/models/custom_app_user'
|
38
39
|
require 'spaceship/connect_api/models/pre_release_version'
|
@@ -98,4 +98,38 @@ module Spaceship
|
|
98
98
|
|
99
99
|
# Raised when 403 is received from portal request
|
100
100
|
class AccessForbiddenError < BasicPreferredInfoError; end
|
101
|
+
|
102
|
+
# Base class for errors coming from App Store Connect locale changes
|
103
|
+
class AppStoreLocaleError < BasicPreferredInfoError
|
104
|
+
def initialize(msg)
|
105
|
+
@message = (msg ? "An exception occurred for locale: #{msg}." : nil)
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
# no need to search github issues since the error is specific
|
110
|
+
def show_github_issues
|
111
|
+
false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Raised for localized text errors from App Store Connect
|
116
|
+
class AppStoreLocalizationError < AppStoreLocaleError
|
117
|
+
def preferred_error_info
|
118
|
+
"#{@message} Check the localization requirements here: https://help.apple.com/app-store-connect/en.lproj/static.html#dev354659071"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Raised for localized screenshots errors from App Store Connect
|
123
|
+
class AppStoreScreenshotError < AppStoreLocaleError
|
124
|
+
def preferred_error_info
|
125
|
+
"#{@message} Check the screenshot requirements here: https://help.apple.com/app-store-connect/en.lproj/static.html#devd274dd925"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Raised for localized app preview errors from App Store Connect
|
130
|
+
class AppStoreAppPreviewError < AppStoreLocaleError
|
131
|
+
def preferred_error_info
|
132
|
+
"#{@message} Check the app preview requirements here: https://help.apple.com/app-store-connect/en.lproj/static.html#dev4e413fcb8"
|
133
|
+
end
|
134
|
+
end
|
101
135
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Spaceship
|
4
|
+
module Hashcash
|
5
|
+
# This App Store Connect hashcash spec was generously donated by...
|
6
|
+
#
|
7
|
+
# __ _
|
8
|
+
# __ _ _ __ _ __ / _|(_) __ _ _ _ _ __ ___ ___
|
9
|
+
# / _` || '_ \ | '_ \ | |_ | | / _` || | | || '__|/ _ \/ __|
|
10
|
+
# | (_| || |_) || |_) || _|| || (_| || |_| || | | __/\__ \
|
11
|
+
# \__,_|| .__/ | .__/ |_| |_| \__, | \__,_||_| \___||___/
|
12
|
+
# |_| |_| |___/
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# <summary>
|
16
|
+
# 1:11:20230223170600:4d74fb15eb23f465f1f6fcbf534e5877::6373
|
17
|
+
# X-APPLE-HC: 1:11:20230223170600:4d74fb15eb23f465f1f6fcbf534e5877::6373
|
18
|
+
# ^ ^ ^ ^ ^
|
19
|
+
# | | | | +-- Counter
|
20
|
+
# | | | +-- Resource
|
21
|
+
# | | +-- Date YYMMDD[hhmm[ss]]
|
22
|
+
# | +-- Bits (number of leading zeros)
|
23
|
+
# +-- Version
|
24
|
+
#
|
25
|
+
# We can't use an off-the-shelf Hashcash because Apple's implementation is not quite the same as the spec/convention.
|
26
|
+
# 1. The spec calls for a nonce called "Rand" to be inserted between the Ext and Counter. They don't do that at all.
|
27
|
+
# 2. The Counter conventionally encoded as base-64 but Apple just uses the decimal number's string representation.
|
28
|
+
#
|
29
|
+
# Iterate from Counter=0 to Counter=N finding an N that makes the SHA1(X-APPLE-HC) lead with Bits leading zero bits
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# We get the "Resource" from the X-Apple-HC-Challenge header and Bits from X-Apple-HC-Bits
|
33
|
+
#
|
34
|
+
# </summary>
|
35
|
+
def self.make(bits:, challenge:)
|
36
|
+
version = 1
|
37
|
+
date = Time.now.strftime("%Y%m%d%H%M%S")
|
38
|
+
|
39
|
+
counter = 0
|
40
|
+
loop do
|
41
|
+
hc = [
|
42
|
+
version, bits, date, challenge, ":#{counter}"
|
43
|
+
].join(":")
|
44
|
+
|
45
|
+
if Digest::SHA1.digest(hc).unpack1('B*')[0, bits.to_i].to_i == 0
|
46
|
+
return hc
|
47
|
+
end
|
48
|
+
counter += 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -61,9 +61,17 @@ module Spaceship
|
|
61
61
|
|
62
62
|
# Send token to server to get a valid session
|
63
63
|
r = request(:post) do |req|
|
64
|
-
req.url("https://idmsa.apple.com/appleauth/auth/verify/
|
64
|
+
req.url("https://idmsa.apple.com/appleauth/auth/verify/phone/securitycode")
|
65
65
|
req.headers['Content-Type'] = 'application/json'
|
66
|
-
req.body = {
|
66
|
+
req.body = {
|
67
|
+
"phoneNumber": {
|
68
|
+
"id": device_id
|
69
|
+
},
|
70
|
+
"securityCode": {
|
71
|
+
"code" => code.to_s
|
72
|
+
},
|
73
|
+
"mode": "sms"
|
74
|
+
}.to_json
|
67
75
|
update_request_headers(req)
|
68
76
|
end
|
69
77
|
|
data/spaceship/lib/spaceship.rb
CHANGED
metadata
CHANGED
@@ -1,39 +1,39 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.212.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
-
|
7
|
+
- Roger Oba
|
8
|
+
- Manish Rathi
|
9
|
+
- Helmut Januschka
|
9
10
|
- Stefan Natchev
|
10
|
-
-
|
11
|
-
- Jérôme Lacoste
|
12
|
-
- Daniel Jankowski
|
13
|
-
- Aaron Brager
|
14
|
-
- Matthew Ellis
|
11
|
+
- Joshua Liebowitz
|
15
12
|
- Kohki Miki
|
16
|
-
-
|
17
|
-
-
|
13
|
+
- Jimmy Dee
|
14
|
+
- Jorge Revuelta H
|
18
15
|
- Andrew McBurney
|
19
|
-
-
|
20
|
-
-
|
16
|
+
- Satoshi Namai
|
17
|
+
- Josh Holtz
|
18
|
+
- Fumiya Nakamura
|
21
19
|
- Danielle Tomlinson
|
22
|
-
-
|
23
|
-
-
|
24
|
-
-
|
20
|
+
- Łukasz Grabowski
|
21
|
+
- Luka Mirosevic
|
22
|
+
- Felix Krause
|
23
|
+
- Jérôme Lacoste
|
25
24
|
- Max Ott
|
26
|
-
-
|
27
|
-
-
|
28
|
-
-
|
25
|
+
- Manu Wallner
|
26
|
+
- Aaron Brager
|
27
|
+
- Maksym Grebenets
|
28
|
+
- Daniel Jankowski
|
29
29
|
- Olivier Halligon
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
30
|
+
- Iulian Onofrei
|
31
|
+
- Matthew Ellis
|
32
|
+
- Jan Piotrowski
|
33
33
|
autorequire:
|
34
34
|
bindir: bin
|
35
35
|
cert_chain: []
|
36
|
-
date:
|
36
|
+
date: 2023-02-24 00:00:00.000000000 Z
|
37
37
|
dependencies:
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: xcodeproj
|
@@ -1702,6 +1702,7 @@ files:
|
|
1702
1702
|
- spaceship/lib/spaceship/connect_api/models/build.rb
|
1703
1703
|
- spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb
|
1704
1704
|
- spaceship/lib/spaceship/connect_api/models/build_bundle.rb
|
1705
|
+
- spaceship/lib/spaceship/connect_api/models/build_bundle_file_sizes.rb
|
1705
1706
|
- spaceship/lib/spaceship/connect_api/models/build_delivery.rb
|
1706
1707
|
- spaceship/lib/spaceship/connect_api/models/bundle_id.rb
|
1707
1708
|
- spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb
|
@@ -1740,6 +1741,7 @@ files:
|
|
1740
1741
|
- spaceship/lib/spaceship/du/utilities.rb
|
1741
1742
|
- spaceship/lib/spaceship/errors.rb
|
1742
1743
|
- spaceship/lib/spaceship/globals.rb
|
1744
|
+
- spaceship/lib/spaceship/hashcash.rb
|
1743
1745
|
- spaceship/lib/spaceship/helper/net_http_generic_request.rb
|
1744
1746
|
- spaceship/lib/spaceship/helper/plist_middleware.rb
|
1745
1747
|
- spaceship/lib/spaceship/helper/rels_middleware.rb
|