fastlane 2.215.1 → 2.217.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +90 -90
  3. data/deliver/lib/deliver/app_screenshot.rb +7 -0
  4. data/deliver/lib/deliver/runner.rb +2 -1
  5. data/deliver/lib/deliver/upload_metadata.rb +58 -13
  6. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +1 -1
  7. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +6 -2
  8. data/fastlane/lib/fastlane/actions/git_branch.rb +1 -1
  9. data/fastlane/lib/fastlane/actions/install_on_device.rb +1 -1
  10. data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
  11. data/fastlane/lib/fastlane/actions/notarize.rb +17 -2
  12. data/fastlane/lib/fastlane/actions/slather.rb +17 -4
  13. data/fastlane/lib/fastlane/helper/git_helper.rb +3 -0
  14. data/fastlane/lib/fastlane/lane.rb +9 -1
  15. data/fastlane/lib/fastlane/runner.rb +1 -1
  16. data/fastlane/lib/fastlane/version.rb +1 -1
  17. data/fastlane/swift/Deliverfile.swift +1 -1
  18. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  19. data/fastlane/swift/Fastlane.swift +46 -6
  20. data/fastlane/swift/Gymfile.swift +1 -1
  21. data/fastlane/swift/GymfileProtocol.swift +1 -1
  22. data/fastlane/swift/Matchfile.swift +1 -1
  23. data/fastlane/swift/MatchfileProtocol.swift +13 -1
  24. data/fastlane/swift/Precheckfile.swift +1 -1
  25. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  26. data/fastlane/swift/Scanfile.swift +1 -1
  27. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  28. data/fastlane/swift/Screengrabfile.swift +1 -1
  29. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  30. data/fastlane/swift/Snapshotfile.swift +1 -1
  31. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  32. data/fastlane/swift/formatting/Brewfile.lock.json +18 -28
  33. data/fastlane_core/lib/fastlane_core/cert_checker.rb +1 -1
  34. data/fastlane_core/lib/fastlane_core/project.rb +4 -0
  35. data/fastlane_core/lib/fastlane_core/queue_worker.rb +1 -1
  36. data/gym/lib/gym/module.rb +13 -2
  37. data/gym/lib/gym/options.rb +1 -1
  38. data/match/lib/match/options.rb +13 -0
  39. data/match/lib/match/runner.rb +11 -5
  40. data/match/lib/match/storage/git_storage.rb +9 -1
  41. data/precheck/lib/precheck/rules/unreachable_urls_rule.rb +1 -1
  42. data/snapshot/lib/assets/SnapshotHelper.swift +13 -9
  43. data/snapshot/lib/snapshot/reports_generator.rb +48 -7
  44. data/spaceship/lib/spaceship/connect_api/api_client.rb +2 -1
  45. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +2 -0
  46. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +4 -4
  47. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -2
  48. data/spaceship/lib/spaceship/connect_api/models/device.rb +2 -2
  49. data/spaceship/lib/spaceship/connect_api/models/profile.rb +3 -2
  50. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +14 -8
  51. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +0 -3
  52. data/supply/lib/supply/uploader.rb +28 -13
  53. data/trainer/lib/trainer/xcresult.rb +1 -1
  54. metadata +27 -30
  55. data/fastlane/lib/fastlane/.features.rb.swp +0 -0
  56. data/fastlane_core/lib/fastlane_core/.env.rb.swp +0 -0
  57. data/supply/lib/supply/.client.rb.swp +0 -0
@@ -148,7 +148,7 @@ module Match
148
148
  self.files_to_commit << cert_path
149
149
  self.files_to_commit << private_key_path
150
150
  else
151
- cert_path = certs.last
151
+ cert_path = select_cert_or_key(paths: certs)
152
152
 
153
153
  # Check validity of certificate
154
154
  if Utils.is_cert_valid?(cert_path)
@@ -172,7 +172,7 @@ module Match
172
172
  # Import the private key
173
173
  # there seems to be no good way to check if it's already installed - so just install it
174
174
  # Key will only be added to the partition list if it isn't already installed
175
- Utils.import(keys.last, params[:keychain_name], password: params[:keychain_password])
175
+ Utils.import(select_cert_or_key(paths: keys), params[:keychain_name], password: params[:keychain_password])
176
176
  end
177
177
  else
178
178
  UI.message("Skipping installation of certificate as it would not work on this operating system.")
@@ -180,7 +180,7 @@ module Match
180
180
 
181
181
  if params[:output_path]
182
182
  FileUtils.cp(cert_path, params[:output_path])
183
- FileUtils.cp(keys.last, params[:output_path])
183
+ FileUtils.cp(select_cert_or_key(paths: keys), params[:output_path])
184
184
  end
185
185
 
186
186
  # Get and print info of certificate
@@ -191,6 +191,12 @@ module Match
191
191
  return File.basename(cert_path).gsub(".cer", "") # Certificate ID
192
192
  end
193
193
 
194
+ # @return [String] Path to certificate or P12 key
195
+ def select_cert_or_key(paths:)
196
+ cert_id_path = ENV['MATCH_CERTIFICATE_ID'] ? paths.find { |path| path.include?(ENV['MATCH_CERTIFICATE_ID']) } : nil
197
+ cert_id_path || paths.last
198
+ end
199
+
194
200
  # rubocop:disable Metrics/PerceivedComplexity
195
201
  # @return [String] The UUID of the provisioning profile so we can verify it with the Apple Developer Portal
196
202
  def fetch_provisioning_profile(params: nil, certificate_id: nil, app_identifier: nil, working_directory: nil)
@@ -331,7 +337,7 @@ module Match
331
337
  portal_profile = all_profiles.detect { |i| i.uuid == uuid }
332
338
 
333
339
  if portal_profile
334
- profile_device_count = portal_profile.fetch_all_devices.count
340
+ profile_device_count = portal_profile.devices.count
335
341
 
336
342
  device_classes =
337
343
  case platform
@@ -412,7 +418,7 @@ module Match
412
418
  # * For portal certificates, we filter out the expired one but includes a new certificate;
413
419
  # * Profile still contains an expired certificate and is valid.
414
420
  # Thus, we need to check the validity of profile certificates too.
415
- profile_certs_count = portal_profile.fetch_all_certificates.select(&:valid?).count
421
+ profile_certs_count = portal_profile.certificates.select(&:valid?).count
416
422
 
417
423
  certificate_types =
418
424
  case platform
@@ -59,12 +59,20 @@ module Match
59
59
  self.clone_branch_directly = clone_branch_directly
60
60
  self.git_basic_authorization = git_basic_authorization
61
61
  self.git_bearer_authorization = git_bearer_authorization
62
- self.git_private_key = git_private_key
62
+ self.git_private_key = convert_private_key_path_to_absolute(git_private_key)
63
63
 
64
64
  self.type = type if type
65
65
  self.platform = platform if platform
66
66
  end
67
67
 
68
+ def convert_private_key_path_to_absolute(git_private_key)
69
+ if !git_private_key.nil? && File.file?(File.expand_path(git_private_key))
70
+ File.expand_path(git_private_key).shellescape.to_s
71
+ else
72
+ git_private_key
73
+ end
74
+ end
75
+
68
76
  def prefixed_working_directory
69
77
  return working_directory
70
78
  end
@@ -33,7 +33,7 @@ module Precheck
33
33
  connection.use(FaradayMiddleware::FollowRedirects)
34
34
  connection.adapter(:net_http)
35
35
  end
36
- return RuleReturn.new(validation_state: Precheck::VALIDATION_STATES[:failed], failure_data: url) unless request.head.status == 200
36
+ return RuleReturn.new(validation_state: Precheck::VALIDATION_STATES[:failed], failure_data: "HTTP #{request.head.status}: #{url}") unless request.head.status == 200
37
37
  rescue StandardError => e
38
38
  UI.verbose("URL #{url} not reachable 😵: #{e.message}")
39
39
  # I can only return :fail here, but I also want to return #{url}
@@ -15,13 +15,12 @@
15
15
  import Foundation
16
16
  import XCTest
17
17
 
18
- var deviceLanguage = ""
19
- var locale = ""
20
-
18
+ @MainActor
21
19
  func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) {
22
20
  Snapshot.setupSnapshot(app, waitForAnimations: waitForAnimations)
23
21
  }
24
22
 
23
+ @MainActor
25
24
  func snapshot(_ name: String, waitForLoadingIndicator: Bool) {
26
25
  if waitForLoadingIndicator {
27
26
  Snapshot.snapshot(name)
@@ -33,6 +32,7 @@ func snapshot(_ name: String, waitForLoadingIndicator: Bool) {
33
32
  /// - Parameters:
34
33
  /// - name: The name of the snapshot
35
34
  /// - timeout: Amount of seconds to wait until the network loading indicator disappears. Pass `0` if you don't want to wait.
35
+ @MainActor
36
36
  func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) {
37
37
  Snapshot.snapshot(name, timeWaitingForIdle: timeout)
38
38
  }
@@ -52,6 +52,7 @@ enum SnapshotError: Error, CustomDebugStringConvertible {
52
52
  }
53
53
 
54
54
  @objcMembers
55
+ @MainActor
55
56
  open class Snapshot: NSObject {
56
57
  static var app: XCUIApplication?
57
58
  static var waitForAnimations = true
@@ -59,6 +60,8 @@ open class Snapshot: NSObject {
59
60
  static var screenshotsDirectory: URL? {
60
61
  return cacheDirectory?.appendingPathComponent("screenshots", isDirectory: true)
61
62
  }
63
+ static var deviceLanguage = ""
64
+ static var currentLocale = ""
62
65
 
63
66
  open class func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) {
64
67
 
@@ -103,17 +106,17 @@ open class Snapshot: NSObject {
103
106
 
104
107
  do {
105
108
  let trimCharacterSet = CharacterSet.whitespacesAndNewlines
106
- locale = try String(contentsOf: path, encoding: .utf8).trimmingCharacters(in: trimCharacterSet)
109
+ currentLocale = try String(contentsOf: path, encoding: .utf8).trimmingCharacters(in: trimCharacterSet)
107
110
  } catch {
108
111
  NSLog("Couldn't detect/set locale...")
109
112
  }
110
113
 
111
- if locale.isEmpty && !deviceLanguage.isEmpty {
112
- locale = Locale(identifier: deviceLanguage).identifier
114
+ if currentLocale.isEmpty && !deviceLanguage.isEmpty {
115
+ currentLocale = Locale(identifier: deviceLanguage).identifier
113
116
  }
114
117
 
115
- if !locale.isEmpty {
116
- app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
118
+ if !currentLocale.isEmpty {
119
+ app.launchArguments += ["-AppleLocale", "\"\(currentLocale)\""]
117
120
  }
118
121
  }
119
122
 
@@ -281,6 +284,7 @@ private extension XCUIElementQuery {
281
284
  return self.containing(isNetworkLoadingIndicator)
282
285
  }
283
286
 
287
+ @MainActor
284
288
  var deviceStatusBars: XCUIElementQuery {
285
289
  guard let app = Snapshot.app else {
286
290
  fatalError("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().")
@@ -306,4 +310,4 @@ private extension CGFloat {
306
310
 
307
311
  // Please don't remove the lines below
308
312
  // They are used to detect outdated configuration files
309
- // SnapshotHelperVersion [1.29]
313
+ // SnapshotHelperVersion [1.30]
@@ -84,6 +84,15 @@ module Snapshot
84
84
  {
85
85
  # snapshot in Xcode 9 saves screenshots with the SIMULATOR_DEVICE_NAME
86
86
  # which includes spaces
87
+ 'iPhone 15 Pro Max' => "iPhone 15 Pro Max",
88
+ 'iPhone 15 Pro' => "iPhone 15 Pro",
89
+ 'iPhone 15 Plus' => "iPhone 15 Plus",
90
+ 'iPhone 15' => "iPhone 15",
91
+ 'iPhone 14 Pro Max' => "iPhone 14 Pro Max",
92
+ 'iPhone 14 Pro' => "iPhone 14 Pro",
93
+ 'iPhone 14 Plus' => "iPhone 14 Plus",
94
+ 'iPhone 14' => "iPhone 14",
95
+ 'iPhone SE (3rd generation)' => "iPhone SE (3rd generation)",
87
96
  'iPhone 13 Pro Max' => "iPhone 13 Pro Max",
88
97
  'iPhone 13 Pro' => "iPhone 13 Pro",
89
98
  'iPhone 13 mini' => "iPhone 13 mini",
@@ -92,6 +101,7 @@ module Snapshot
92
101
  'iPhone 12 Pro' => "iPhone 12 Pro",
93
102
  'iPhone 12 mini' => "iPhone 12 mini",
94
103
  'iPhone 12' => "iPhone 12",
104
+ 'iPhone SE (2nd generation)' => "iPhone SE (2nd generation)",
95
105
  'iPhone 11 Pro Max' => "iPhone 11 Pro Max",
96
106
  'iPhone 11 Pro' => "iPhone 11 Pro",
97
107
  'iPhone 11' => "iPhone 11",
@@ -112,20 +122,34 @@ module Snapshot
112
122
  'iPhone SE' => "iPhone SE",
113
123
  'iPhone 4s' => "iPhone 4s (3.5-Inch)",
114
124
  'iPad 2' => 'iPad 2',
125
+ 'iPad Air (5th generation)' => 'iPad Air (5th generation)',
126
+ 'iPad Air (4th generation)' => 'iPad Air (4th generation)',
115
127
  'iPad Air (3rd generation)' => 'iPad Air (3rd generation)',
116
128
  'iPad Air 2' => 'iPad Air 2',
117
129
  'iPad Air' => 'iPad Air',
118
- 'iPad (5th generation)' => 'iPad (5th generation)',
130
+ 'iPad (10th generation)' => 'iPad (10th generation)',
131
+ 'iPad (9th generation)' => 'iPad (9th generation)',
132
+ 'iPad (8th generation)' => 'iPad (8th generation)',
119
133
  'iPad (7th generation)' => 'iPad (7th generation)',
120
- 'iPad mini 2' => 'iPad mini 2',
121
- 'iPad mini 3' => 'iPad mini 3',
122
- 'iPad mini 4' => 'iPad mini 4',
134
+ 'iPad (6th generation)' => 'iPad (6th generation)',
135
+ 'iPad (5th generation)' => 'iPad (5th generation)',
123
136
  'iPad mini (6th generation)' => 'iPad mini (6th generation)',
137
+ 'iPad mini (5th generation)' => 'iPad mini (5th generation)',
138
+ 'iPad mini 4' => 'iPad mini 4',
139
+ 'iPad mini 3' => 'iPad mini 3',
140
+ 'iPad mini 2' => 'iPad mini 2',
124
141
  'iPad Pro (9.7-inch)' => 'iPad Pro (9.7-inch)',
125
142
  'iPad Pro (9.7 inch)' => 'iPad Pro (9.7-inch)', # iOS 10.3.1 simulator
126
143
  'iPad Pro (10.5-inch)' => 'iPad Pro (10.5-inch)',
144
+ 'iPad Pro (11-inch) (4th generation) (16GB)' => 'iPad Pro (11-inch) (4th generation) (16GB)',
145
+ 'iPad Pro (11-inch) (4th generation)' => 'iPad Pro (11-inch) (4th generation)',
146
+ 'iPad Pro (11-inch) (3rd generation)' => 'iPad Pro (11-inch) (3rd generation)',
127
147
  'iPad Pro (11-inch) (2nd generation)' => 'iPad Pro (11-inch) (2nd generation)',
148
+ 'iPad Pro (11-inch) (1st generation)' => 'iPad Pro (11-inch) (1st generation)',
128
149
  'iPad Pro (11-inch)' => 'iPad Pro (11-inch)',
150
+ 'iPad Pro (12.9-inch) (6th generation) (16GB)' => 'iPad Pro (12.9-inch) (6th generation) (16GB)',
151
+ 'iPad Pro (12.9-inch) (6th generation)' => 'iPad Pro (12.9-inch) (6th generation)',
152
+ 'iPad Pro (12.9-inch) (5th generation)' => 'iPad Pro (12.9-inch) (5th generation)',
129
153
  'iPad Pro (12.9-inch) (4th generation)' => 'iPad Pro (12.9-inch) (4th generation)',
130
154
  'iPad Pro (12.9-inch) (3rd generation)' => 'iPad Pro (12.9-inch) (3rd generation)',
131
155
  'iPad Pro (12.9-inch) (2nd generation)' => 'iPad Pro (12.9-inch) (2nd generation)',
@@ -133,13 +157,30 @@ module Snapshot
133
157
  'iPad Pro (12.9 inch)' => 'iPad Pro (12.9-inch)', # iOS 10.3.1 simulator
134
158
  'iPad Pro' => 'iPad Pro (12.9-inch)', # iOS 9.3 simulator
135
159
  'iPod touch (7th generation)' => 'iPod touch (7th generation)',
136
- 'Apple TV 1080p' => 'Apple TV',
160
+ 'Apple TV 4K (3rd generation)' => 'Apple TV 4K (3rd generation)',
161
+ 'Apple TV 4K (3rd generation) (at 1080p)' => 'Apple TV 4K (3rd generation) (at 1080p)',
162
+ 'Apple TV 4K (2nd generation)' => 'Apple TV 4K (2nd generation)',
163
+ 'Apple TV 4K (2nd generation) (at 1080p)' => 'Apple TV 4K (2nd generation) (at 1080p)',
137
164
  'Apple TV 4K (at 1080p)' => 'Apple TV 4K (at 1080p)',
138
165
  'Apple TV 4K' => 'Apple TV 4K',
166
+ 'Apple TV 1080p' => 'Apple TV',
139
167
  'Apple TV' => 'Apple TV',
140
168
  'Mac' => 'Mac',
141
- 'Apple Watch Series 5 - 44mm' => 'Apple Watch Series 5 - 44mm',
142
- 'Apple Watch Series 6 - 44mm' => 'Apple Watch Series 6 - 44mm'
169
+ 'Apple Watch Ultra 2 (49mm)' => 'Apple Watch Ultra 2 (49mm)',
170
+ 'Apple Watch SE (44mm)' => 'Apple Watch SE (44mm)',
171
+ 'Apple Watch SE (40mm)' => 'Apple Watch SE (40mm)',
172
+ 'Apple Watch Series 9 (45mm)' => 'Apple Watch Series 9 (45mm)',
173
+ 'Apple Watch Series 9 (41mm)' => 'Apple Watch Series 9 (41mm)',
174
+ 'Apple Watch Series 8 (45mm)' => 'Apple Watch Series 8 (45mm)',
175
+ 'Apple Watch Series 8 (41mm)' => 'Apple Watch Series 8 (41mm)',
176
+ 'Apple Watch Series 7 (45mm)' => 'Apple Watch Series 7 (45mm)',
177
+ 'Apple Watch Series 7 (41mm)' => 'Apple Watch Series 7 (41mm)',
178
+ 'Apple Watch Series 6 (44mm)' => 'Apple Watch Series 6 (44mm)',
179
+ 'Apple Watch Series 6 (40mm)' => 'Apple Watch Series 6 (40mm)',
180
+ 'Apple Watch Series 5 (44mm)' => 'Apple Watch Series 5 (44mm)',
181
+ 'Apple Watch Series 5 (40mm)' => 'Apple Watch Series 5 (40mm)',
182
+ 'Apple Watch Series 6 - 44mm' => 'Apple Watch Series 6 - 44mm',
183
+ 'Apple Watch Series 5 - 44mm' => 'Apple Watch Series 5 - 44mm'
143
184
  }
144
185
  end
145
186
 
@@ -87,13 +87,14 @@ module Spaceship
87
87
  return @token.nil?
88
88
  end
89
89
 
90
- def build_params(filter: nil, includes: nil, limit: nil, sort: nil, cursor: nil)
90
+ def build_params(filter: nil, includes: nil, fields: nil, limit: nil, sort: nil, cursor: nil)
91
91
  params = {}
92
92
 
93
93
  filter = filter.delete_if { |k, v| v.nil? } if filter
94
94
 
95
95
  params[:filter] = filter if filter && !filter.empty?
96
96
  params[:include] = includes if includes
97
+ params[:fields] = fields if fields
97
98
  params[:limit] = limit if limit
98
99
  params[:sort] = sort if sort
99
100
  params[:cursor] = cursor if cursor
@@ -43,6 +43,7 @@ module Spaceship
43
43
  APP_WATCH_SERIES_3 = "APP_WATCH_SERIES_3"
44
44
  APP_WATCH_SERIES_4 = "APP_WATCH_SERIES_4"
45
45
  APP_WATCH_SERIES_7 = "APP_WATCH_SERIES_7"
46
+ APP_WATCH_ULTRA = "APP_WATCH_ULTRA"
46
47
 
47
48
  APP_APPLE_TV = "APP_APPLE_TV"
48
49
 
@@ -97,6 +98,7 @@ module Spaceship
97
98
  APP_WATCH_SERIES_3,
98
99
  APP_WATCH_SERIES_4,
99
100
  APP_WATCH_SERIES_7,
101
+ APP_WATCH_ULTRA,
100
102
 
101
103
  APP_DESKTOP
102
104
  ]
@@ -39,15 +39,15 @@ module Spaceship
39
39
  # API
40
40
  #
41
41
 
42
- def self.all(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
42
+ def self.all(client: nil, filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
43
43
  client ||= Spaceship::ConnectAPI
44
- resps = client.get_bundle_ids(filter: filter, includes: includes).all_pages
44
+ resps = client.get_bundle_ids(filter: filter, includes: includes, fields: fields, limit: nil, sort: nil).all_pages
45
45
  return resps.flat_map(&:to_models)
46
46
  end
47
47
 
48
- def self.find(identifier, includes: nil, client: nil)
48
+ def self.find(identifier, includes: nil, fields: nil, client: nil)
49
49
  client ||= Spaceship::ConnectAPI
50
- return all(client: client, filter: { identifier: identifier }, includes: includes).find do |app|
50
+ return all(client: client, filter: { identifier: identifier }, includes: includes, fields: fields).find do |app|
51
51
  app.identifier == identifier
52
52
  end
53
53
  end
@@ -79,9 +79,9 @@ module Spaceship
79
79
  # API
80
80
  #
81
81
 
82
- def self.all(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
82
+ def self.all(client: nil, filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
83
83
  client ||= Spaceship::ConnectAPI
84
- resps = client.get_certificates(filter: filter, includes: includes).all_pages
84
+ resps = client.get_certificates(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort).all_pages
85
85
  return resps.flat_map(&:to_models)
86
86
  end
87
87
 
@@ -51,9 +51,9 @@ module Spaceship
51
51
  # API
52
52
  #
53
53
 
54
- def self.all(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
54
+ def self.all(client: nil, filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
55
55
  client ||= Spaceship::ConnectAPI
56
- resps = client.get_devices(filter: filter, includes: includes).all_pages
56
+ resps = client.get_devices(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort).all_pages
57
57
  return resps.flat_map(&:to_models)
58
58
  end
59
59
 
@@ -15,6 +15,7 @@ module Spaceship
15
15
 
16
16
  attr_accessor :bundle_id
17
17
  attr_accessor :certificates
18
+ attr_accessor :devices
18
19
 
19
20
  attr_mapping({
20
21
  "name" => "name",
@@ -69,9 +70,9 @@ module Spaceship
69
70
  # API
70
71
  #
71
72
 
72
- def self.all(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
73
+ def self.all(client: nil, filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
73
74
  client ||= Spaceship::ConnectAPI
74
- resps = client.get_profiles(filter: filter, includes: includes).all_pages
75
+ resps = client.get_profiles(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort).all_pages
75
76
  return resps.flat_map(&:to_models)
76
77
  end
77
78
 
@@ -17,8 +17,8 @@ module Spaceship
17
17
  # bundleIds
18
18
  #
19
19
 
20
- def get_bundle_ids(filter: {}, includes: nil, limit: nil, sort: nil)
21
- params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
20
+ def get_bundle_ids(filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
21
+ params = provisioning_request_client.build_params(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort)
22
22
  provisioning_request_client.get("bundleIds", params)
23
23
  end
24
24
 
@@ -129,8 +129,8 @@ module Spaceship
129
129
  # certificates
130
130
  #
131
131
 
132
- def get_certificates(profile_id: nil, filter: {}, includes: nil, limit: nil, sort: nil)
133
- params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
132
+ def get_certificates(profile_id: nil, filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
133
+ params = provisioning_request_client.build_params(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort)
134
134
  if profile_id.nil?
135
135
  provisioning_request_client.get("certificates", params)
136
136
  else
@@ -164,8 +164,8 @@ module Spaceship
164
164
  # devices
165
165
  #
166
166
 
167
- def get_devices(profile_id: nil, filter: {}, includes: nil, limit: nil, sort: nil)
168
- params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
167
+ def get_devices(profile_id: nil, filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
168
+ params = provisioning_request_client.build_params(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort)
169
169
  if profile_id.nil?
170
170
  provisioning_request_client.get("devices", params)
171
171
  else
@@ -213,8 +213,8 @@ module Spaceship
213
213
  # profiles
214
214
  #
215
215
 
216
- def get_profiles(filter: {}, includes: nil, limit: nil, sort: nil)
217
- params = provisioning_request_client.build_params(filter: filter, includes: includes, limit: limit, sort: sort)
216
+ def get_profiles(filter: {}, includes: nil, fields: nil, limit: nil, sort: nil)
217
+ params = provisioning_request_client.build_params(filter: filter, includes: includes, fields: fields, limit: limit, sort: sort)
218
218
  provisioning_request_client.get("profiles", params)
219
219
  end
220
220
 
@@ -253,6 +253,12 @@ module Spaceship
253
253
  provisioning_request_client.post("profiles", body)
254
254
  end
255
255
 
256
+ def get_profile_bundle_id(profile_id: nil)
257
+ raise "Profile id is nil" if profile_id.nil?
258
+
259
+ provisioning_request_client.get("profiles/#{profile_id}/bundleId")
260
+ end
261
+
256
262
  def delete_profile(profile_id: nil)
257
263
  raise "Profile id is nil" if profile_id.nil?
258
264
 
@@ -160,9 +160,6 @@ module Spaceship
160
160
  included << {
161
161
  type: "appPrices",
162
162
  id: "${price1}",
163
- attributes: {
164
- startDate: nil
165
- },
166
163
  relationships: {
167
164
  app: {
168
165
  data: {
@@ -1,6 +1,10 @@
1
+ require 'fastlane_core'
2
+
1
3
  module Supply
2
4
  # rubocop:disable Metrics/ClassLength
3
5
  class Uploader
6
+ UploadJob = Struct.new(:language, :version_code, :release_notes_queue)
7
+
4
8
  def perform_upload
5
9
  FastlaneCore::PrintTable.print_values(config: Supply.config, hide_keys: [:issuer], mask_keys: [:json_key_data], title: "Summary for supply #{Fastlane::VERSION}")
6
10
 
@@ -88,19 +92,15 @@ module Supply
88
92
  UI.user_error!("Unable to find the requested track - '#{Supply.config[:track]}'") unless track
89
93
  UI.user_error!("Could not find release for version code '#{version_code}' to update changelog") unless release
90
94
 
91
- release_notes = []
92
- all_languages.each do |language|
93
- next if language.start_with?('.') # e.g. . or .. or hidden folders
94
- UI.message("Preparing to upload for language '#{language}'...")
95
-
96
- listing = client.listing_for_language(language)
97
-
98
- upload_metadata(language, listing) unless Supply.config[:skip_upload_metadata]
99
- upload_images(language) unless Supply.config[:skip_upload_images]
100
- upload_screenshots(language) unless Supply.config[:skip_upload_screenshots]
101
- release_notes << upload_changelog(language, version_code) unless Supply.config[:skip_upload_changelogs]
102
- end
95
+ release_notes_queue = Queue.new
96
+ upload_worker = create_meta_upload_worker
97
+ upload_worker.batch_enqueue(
98
+ # skip . or .. or hidden folders
99
+ all_languages.reject { |lang| lang.start_with?('.') }.map { |lang| UploadJob.new(lang, version_code, release_notes_queue) }
100
+ )
101
+ upload_worker.start
103
102
 
103
+ release_notes = Array.new(release_notes_queue.size) { release_notes_queue.pop } # Queue to Array
104
104
  upload_changelogs(release_notes, release, track, track_name) unless release_notes.empty?
105
105
  end
106
106
  end
@@ -128,7 +128,7 @@ module Supply
128
128
  UI.user_error!("Unable to find the requested track - '#{Supply.config[:track]}'") unless track
129
129
  UI.user_error!("Unable to find the requested release on track - '#{Supply.config[:track]}'") unless release
130
130
 
131
- version_code = release.version_codes.first
131
+ version_code = release.version_codes.max
132
132
 
133
133
  UI.message("Updating #{version_code}'s rollout to '#{Supply.config[:rollout]}' on track '#{Supply.config[:track]}'...")
134
134
 
@@ -511,6 +511,21 @@ module Supply
511
511
  'patch'
512
512
  end
513
513
  end
514
+
515
+ def create_meta_upload_worker
516
+ FastlaneCore::QueueWorker.new do |job|
517
+ UI.message("Preparing uploads for language '#{job.language}'...")
518
+ start_time = Time.now
519
+ listing = client.listing_for_language(job.language)
520
+ upload_metadata(job.language, listing) unless Supply.config[:skip_upload_metadata]
521
+ upload_images(job.language) unless Supply.config[:skip_upload_images]
522
+ upload_screenshots(job.language) unless Supply.config[:skip_upload_screenshots]
523
+ job.release_notes_queue << upload_changelog(job.language, job.version_code) unless Supply.config[:skip_upload_changelogs]
524
+ UI.message("Uploaded all items for language '#{job.language}'... (#{Time.now - start_time} secs)")
525
+ rescue => error
526
+ UI.abort_with_message!("#{job.language} - #{error}")
527
+ end
528
+ end
514
529
  end
515
530
  # rubocop:enable Metrics/ClassLength
516
531
  end
@@ -391,7 +391,7 @@ module Trainer
391
391
 
392
392
  def failure_message
393
393
  new_message = self.message
394
- if self.document_location_in_creating_workspace
394
+ if self.document_location_in_creating_workspace&.url
395
395
  file_path = self.document_location_in_creating_workspace.url.gsub("file://", "")
396
396
  new_message += " (#{file_path})"
397
397
  end
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.215.1
4
+ version: 2.217.0
5
5
  platform: ruby
6
6
  authors:
7
- - Satoshi Namai
8
- - Felix Krause
9
- - Matthew Ellis
10
- - Manish Rathi
11
- - Aaron Brager
12
- - Jimmy Dee
13
- - Iulian Onofrei
14
7
  - Fumiya Nakamura
15
- - Andrew McBurney
16
- - Joshua Liebowitz
17
- - Jérôme Lacoste
8
+ - Felix Krause
9
+ - Stefan Natchev
10
+ - Roger Oba
11
+ - Satoshi Namai
18
12
  - Josh Holtz
13
+ - Danielle Tomlinson
14
+ - Manu Wallner
15
+ - Andrew McBurney
16
+ - Kohki Miki
17
+ - Olivier Halligon
18
+ - Aaron Brager
19
+ - Jan Piotrowski
20
+ - Maksym Grebenets
19
21
  - Daniel Jankowski
20
- - Max Ott
21
- - Helmut Januschka
22
+ - Luka Mirosevic
23
+ - Jimmy Dee
22
24
  - Jorge Revuelta H
25
+ - Manish Rathi
26
+ - Matthew Ellis
27
+ - Helmut Januschka
28
+ - Max Ott
29
+ - Jérôme Lacoste
30
+ - Joshua Liebowitz
23
31
  - Łukasz Grabowski
24
- - Olivier Halligon
25
- - Roger Oba
26
- - Luka Mirosevic
27
- - Manu Wallner
28
- - Danielle Tomlinson
29
- - Stefan Natchev
30
- - Maksym Grebenets
31
- - Jan Piotrowski
32
- - Kohki Miki
32
+ - Iulian Onofrei
33
33
  autorequire:
34
34
  bindir: bin
35
35
  cert_chain: []
36
- date: 2023-09-17 00:00:00.000000000 Z
36
+ date: 2023-11-15 00:00:00.000000000 Z
37
37
  dependencies:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: addressable
@@ -721,16 +721,16 @@ dependencies:
721
721
  name: fakefs
722
722
  requirement: !ruby/object:Gem::Requirement
723
723
  requirements:
724
- - - "~>"
724
+ - - '='
725
725
  - !ruby/object:Gem::Version
726
- version: '1.2'
726
+ version: '1.8'
727
727
  type: :development
728
728
  prerelease: false
729
729
  version_requirements: !ruby/object:Gem::Requirement
730
730
  requirements:
731
- - - "~>"
731
+ - - '='
732
732
  - !ruby/object:Gem::Version
733
- version: '1.2'
733
+ version: '1.8'
734
734
  - !ruby/object:Gem::Dependency
735
735
  name: pry-byebug
736
736
  requirement: !ruby/object:Gem::Requirement
@@ -1026,7 +1026,6 @@ files:
1026
1026
  - fastlane/lib/assets/s3_plist_template.erb
1027
1027
  - fastlane/lib/assets/s3_version_template.erb
1028
1028
  - fastlane/lib/fastlane.rb
1029
- - fastlane/lib/fastlane/.features.rb.swp
1030
1029
  - fastlane/lib/fastlane/action.rb
1031
1030
  - fastlane/lib/fastlane/action_collector.rb
1032
1031
  - fastlane/lib/fastlane/actions/README.md
@@ -1411,7 +1410,6 @@ files:
1411
1410
  - fastlane_core/README.md
1412
1411
  - fastlane_core/lib/assets/XMLTemplate.xml.erb
1413
1412
  - fastlane_core/lib/fastlane_core.rb
1414
- - fastlane_core/lib/fastlane_core/.env.rb.swp
1415
1413
  - fastlane_core/lib/fastlane_core/analytics/action_completion_context.rb
1416
1414
  - fastlane_core/lib/fastlane_core/analytics/action_launch_context.rb
1417
1415
  - fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb
@@ -1858,7 +1856,6 @@ files:
1858
1856
  - spaceship/lib/spaceship/upgrade_2fa_later_client.rb
1859
1857
  - supply/README.md
1860
1858
  - supply/lib/supply.rb
1861
- - supply/lib/supply/.client.rb.swp
1862
1859
  - supply/lib/supply/apk_listing.rb
1863
1860
  - supply/lib/supply/client.rb
1864
1861
  - supply/lib/supply/commands_generator.rb
Binary file
Binary file