fastlane 2.192.0 → 2.195.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +86 -86
  3. data/cert/lib/cert/options.rb +1 -1
  4. data/deliver/lib/deliver/options.rb +1 -1
  5. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +1 -1
  6. data/fastlane/lib/fastlane/actions/get_provisioning_profile.rb +1 -1
  7. data/fastlane/lib/fastlane/actions/gradle.rb +16 -3
  8. data/fastlane/lib/fastlane/actions/last_git_commit.rb +1 -1
  9. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +1 -1
  10. data/fastlane/lib/fastlane/actions/notarize.rb +27 -18
  11. data/fastlane/lib/fastlane/actions/prompt.rb +1 -1
  12. data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/register_devices.rb +1 -1
  14. data/fastlane/lib/fastlane/actions/set_changelog.rb +1 -1
  15. data/fastlane/lib/fastlane/actions/slather.rb +6 -0
  16. data/fastlane/lib/fastlane/actions/sync_code_signing.rb +1 -1
  17. data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +3 -1
  18. data/fastlane/lib/fastlane/actions/zip.rb +2 -2
  19. data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +11 -5
  20. data/fastlane/lib/fastlane/version.rb +1 -1
  21. data/fastlane/swift/Deliverfile.swift +1 -1
  22. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  23. data/fastlane/swift/Fastlane.swift +89 -98
  24. data/fastlane/swift/Gymfile.swift +1 -1
  25. data/fastlane/swift/GymfileProtocol.swift +1 -1
  26. data/fastlane/swift/Matchfile.swift +1 -1
  27. data/fastlane/swift/MatchfileProtocol.swift +11 -3
  28. data/fastlane/swift/Precheckfile.swift +1 -1
  29. data/fastlane/swift/PrecheckfileProtocol.swift +2 -2
  30. data/fastlane/swift/Scanfile.swift +1 -1
  31. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  32. data/fastlane/swift/Screengrabfile.swift +1 -1
  33. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  34. data/fastlane/swift/Snapshotfile.swift +1 -1
  35. data/fastlane/swift/SnapshotfileProtocol.swift +2 -2
  36. data/fastlane/swift/formatting/Brewfile.lock.json +5 -5
  37. data/fastlane_core/lib/fastlane_core/build_watcher.rb +25 -6
  38. data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +5 -0
  39. data/match/lib/match/generator.rb +2 -1
  40. data/match/lib/match/options.rb +12 -2
  41. data/match/lib/match/runner.rb +100 -15
  42. data/pilot/lib/pilot/build_manager.rb +14 -3
  43. data/pilot/lib/pilot/manager.rb +3 -1
  44. data/pilot/lib/pilot/options.rb +21 -2
  45. data/precheck/lib/precheck/options.rb +1 -1
  46. data/sigh/lib/assets/resign.sh +1 -1
  47. data/sigh/lib/sigh/options.rb +6 -1
  48. data/sigh/lib/sigh/runner.rb +2 -2
  49. data/snapshot/lib/snapshot/options.rb +1 -1
  50. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +9 -1
  51. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +1 -1
  52. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -0
  53. data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +4 -0
  54. data/supply/lib/supply/uploader.rb +9 -6
  55. metadata +22 -25
  56. data/fastlane/lib/fastlane/actions/crashlytics.rb +0 -207
  57. data/fastlane/lib/fastlane/helper/crashlytics_helper.rb +0 -157
  58. data/spaceship/lib/spaceship/connect_api/testflight/.testflight.rb.swp +0 -0
@@ -17,4 +17,4 @@ public class Gymfile: GymfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.192.0
20
+ // Generated with fastlane 2.195.0
@@ -196,4 +196,4 @@ public extension GymfileProtocol {
196
196
 
197
197
  // Please don't remove the lines below
198
198
  // They are used to detect outdated files
199
- // FastlaneRunnerAPIVersion [0.9.83]
199
+ // FastlaneRunnerAPIVersion [0.9.87]
@@ -17,4 +17,4 @@ public class Matchfile: MatchfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.192.0
20
+ // Generated with fastlane 2.195.0
@@ -23,7 +23,7 @@ public protocol MatchfileProtocol: class {
23
23
  /// Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
24
24
  var apiKeyPath: String? { get }
25
25
 
26
- /// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)
26
+ /// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
27
27
  var apiKey: [String: Any]? { get }
28
28
 
29
29
  /// Your Apple ID Username
@@ -98,9 +98,15 @@ public protocol MatchfileProtocol: class {
98
98
  /// Renew the provisioning profiles every time you run match
99
99
  var force: Bool { get }
100
100
 
101
- /// Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile type 'appstore'
101
+ /// Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile types 'appstore' and 'developer_id'
102
102
  var forceForNewDevices: Bool { get }
103
103
 
104
+ /// Include all matching certificates in the provisioning profile. Works only for the 'development' provisioning profile type
105
+ var includeAllCertificates: Bool { get }
106
+
107
+ /// Renew the provisioning profiles if the device count on the developer portal has changed. Works only for the 'development' provisioning profile type. Requires 'include_all_certificates' option to be 'true'
108
+ var forceForNewCertificates: Bool { get }
109
+
104
110
  /// Disables confirmation prompts during nuke, answering them with yes
105
111
  var skipConfirmation: Bool { get }
106
112
 
@@ -169,6 +175,8 @@ public extension MatchfileProtocol {
169
175
  var keychainPassword: String? { return nil }
170
176
  var force: Bool { return false }
171
177
  var forceForNewDevices: Bool { return false }
178
+ var includeAllCertificates: Bool { return false }
179
+ var forceForNewCertificates: Bool { return false }
172
180
  var skipConfirmation: Bool { return false }
173
181
  var skipDocs: Bool { return false }
174
182
  var platform: String { return "ios" }
@@ -184,4 +192,4 @@ public extension MatchfileProtocol {
184
192
 
185
193
  // Please don't remove the lines below
186
194
  // They are used to detect outdated files
187
- // FastlaneRunnerAPIVersion [0.9.77]
195
+ // FastlaneRunnerAPIVersion [0.9.81]
@@ -17,4 +17,4 @@ public class Precheckfile: PrecheckfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.192.0
20
+ // Generated with fastlane 2.195.0
@@ -5,7 +5,7 @@ public protocol PrecheckfileProtocol: class {
5
5
  /// Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
6
6
  var apiKeyPath: String? { get }
7
7
 
8
- /// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)
8
+ /// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
9
9
  var apiKey: [String: Any]? { get }
10
10
 
11
11
  /// The bundle identifier of your app
@@ -52,4 +52,4 @@ public extension PrecheckfileProtocol {
52
52
 
53
53
  // Please don't remove the lines below
54
54
  // They are used to detect outdated files
55
- // FastlaneRunnerAPIVersion [0.9.76]
55
+ // FastlaneRunnerAPIVersion [0.9.80]
@@ -17,4 +17,4 @@ public class Scanfile: ScanfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.192.0
20
+ // Generated with fastlane 2.195.0
@@ -296,4 +296,4 @@ public extension ScanfileProtocol {
296
296
 
297
297
  // Please don't remove the lines below
298
298
  // They are used to detect outdated files
299
- // FastlaneRunnerAPIVersion [0.9.88]
299
+ // FastlaneRunnerAPIVersion [0.9.92]
@@ -17,4 +17,4 @@ public class Screengrabfile: ScreengrabfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.192.0
20
+ // Generated with fastlane 2.195.0
@@ -96,4 +96,4 @@ public extension ScreengrabfileProtocol {
96
96
 
97
97
  // Please don't remove the lines below
98
98
  // They are used to detect outdated files
99
- // FastlaneRunnerAPIVersion [0.9.78]
99
+ // FastlaneRunnerAPIVersion [0.9.82]
@@ -17,4 +17,4 @@ public class Snapshotfile: SnapshotfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.192.0
20
+ // Generated with fastlane 2.195.0
@@ -50,7 +50,7 @@ public protocol SnapshotfileProtocol: class {
50
50
  /// Enabling this option will prevent displaying the simulator window
51
51
  var headless: Bool { get }
52
52
 
53
- /// Enabling this option will automatically override the status bar to show 9:41 AM, full battery, and full reception
53
+ /// Enabling this option will automatically override the status bar to show 9:41 AM, full battery, and full reception (Adjust 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environment variable if override status bar is not working. Might be because simulator is not fully booted. Defaults to 10 seconds)
54
54
  var overrideStatusBar: Bool { get }
55
55
 
56
56
  /// Fully customize the status bar by setting each option here. See `xcrun simctl status_bar --help`
@@ -200,4 +200,4 @@ public extension SnapshotfileProtocol {
200
200
 
201
201
  // Please don't remove the lines below
202
202
  // They are used to detect outdated files
203
- // FastlaneRunnerAPIVersion [0.9.72]
203
+ // FastlaneRunnerAPIVersion [0.9.76]
@@ -43,18 +43,18 @@
43
43
  "macOS": "10.15.7"
44
44
  },
45
45
  "big_sur": {
46
- "HOMEBREW_VERSION": "3.2.9",
46
+ "HOMEBREW_VERSION": "3.2.10-50-ge3f851d",
47
47
  "HOMEBREW_PREFIX": "/opt/homebrew",
48
- "Homebrew/homebrew-core": "d2c0a344f23a132f6fdf06a8b1d6d0eaaec54a21",
48
+ "Homebrew/homebrew-core": "73588fb5f5edccfe62f1b290a3298b402fbd71d5",
49
49
  "CLT": "12.5.1.0.1.1623191612",
50
50
  "Xcode": "13.0",
51
51
  "macOS": "11.5.2"
52
52
  },
53
53
  "monterey": {
54
- "HOMEBREW_VERSION": "3.2.6-34-g6bb3699",
54
+ "HOMEBREW_VERSION": "3.2.13-55-ga6959e4",
55
55
  "HOMEBREW_PREFIX": "/usr/local",
56
- "Homebrew/homebrew-core": "b7523de28df0f0f819ff2c49c84611eec19f5455",
57
- "CLT": "13.0.0.0.1.1626155413",
56
+ "Homebrew/homebrew-core": "3fb109275770551bba03c7055d75ceec2c38b1b2",
57
+ "CLT": "13.0.0.0.1.1628499445",
58
58
  "Xcode": "13.0",
59
59
  "macOS": "12.0"
60
60
  }
@@ -11,7 +11,7 @@ module FastlaneCore
11
11
 
12
12
  class << self
13
13
  # @return The build we waited for. This method will always return a build
14
- def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, timeout_duration: nil, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true, select_latest: false)
14
+ def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, timeout_duration: nil, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true, select_latest: false, wait_for_build_beta_detail_processing: false)
15
15
  # Warn about train_version being removed in the future
16
16
  if train_version
17
17
  UI.deprecated(":train_version is no longer a used argument on FastlaneCore::BuildWatcher. Please use :app_version instead.")
@@ -41,13 +41,13 @@ module FastlaneCore
41
41
  showed_info = true
42
42
  end
43
43
 
44
- report_status(build: matched_build)
44
+ report_status(build: matched_build, wait_for_build_beta_detail_processing: wait_for_build_beta_detail_processing)
45
45
 
46
46
  # Processing of builds by AppStoreConnect can be a very time consuming task and will
47
47
  # block the worker running this task until it is completed. In some cases,
48
48
  # having a build resource appear in AppStoreConnect (matched_build) may be enough (i.e. setting a changelog)
49
49
  # so here we may choose to skip the full processing of the build if return_when_build_appears is true
50
- if matched_build && (return_when_build_appears || matched_build.processed?)
50
+ if matched_build && (return_when_build_appears || processed?(build: matched_build, wait_for_build_beta_detail_processing: wait_for_build_beta_detail_processing))
51
51
 
52
52
  if !app_version.nil? && app_version != app_version_queried
53
53
  UI.important("App version is #{app_version} but build was found while querying #{app_version_queried}")
@@ -145,10 +145,29 @@ module FastlaneCore
145
145
  return nil
146
146
  end
147
147
 
148
- def report_status(build: nil)
149
- if build && !build.processed?
148
+ def processed?(build: nil, wait_for_build_beta_detail_processing: false)
149
+ return false unless build
150
+
151
+ is_processed = build.processed?
152
+
153
+ # App Store Connect API has multiple build processing states
154
+ # builds have one processing status
155
+ # buildBetaDetails have two processing statues (internal and external testing)
156
+ #
157
+ # If set, this method will only return true if all three statuses are complete
158
+ if wait_for_build_beta_detail_processing
159
+ is_processed &&= (build.build_beta_detail&.processed? || false)
160
+ end
161
+
162
+ return is_processed
163
+ end
164
+
165
+ def report_status(build: nil, wait_for_build_beta_detail_processing: false)
166
+ is_processed = processed?(build: build, wait_for_build_beta_detail_processing: wait_for_build_beta_detail_processing)
167
+
168
+ if build && !is_processed
150
169
  UI.message("Waiting for App Store Connect to finish processing the new build (#{build.app_version} - #{build.version}) for #{build.platform}")
151
- elsif build && build.processed?
170
+ elsif build && is_processed
152
171
  UI.success("Successfully finished processing the build #{build.app_version} - #{build.version} for #{build.platform}")
153
172
  else
154
173
  UI.message("Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)")
@@ -10,6 +10,11 @@ module FastlaneCore
10
10
  return nil
11
11
  end
12
12
 
13
+ # Fetches the app platform from the given pkg file.
14
+ def self.fetch_app_platform(path)
15
+ return "osx"
16
+ end
17
+
13
18
  # Fetches the app version from the given pkg file.
14
19
  def self.fetch_app_version(path)
15
20
  xml = self.fetch_distribution_xml_file(path)
@@ -88,7 +88,8 @@ module Match
88
88
  team_id: params[:team_id],
89
89
  team_name: params[:team_name],
90
90
  template_name: params[:template_name],
91
- fail_on_name_taken: params[:fail_on_name_taken]
91
+ fail_on_name_taken: params[:fail_on_name_taken],
92
+ include_all_certificates: params[:include_all_certificates],
92
93
  }
93
94
 
94
95
  values[:platform] = params[:platform]
@@ -83,7 +83,7 @@ module Match
83
83
  end),
84
84
  FastlaneCore::ConfigItem.new(key: :api_key,
85
85
  env_names: ["SIGH_API_KEY", "APP_STORE_CONNECT_API_KEY"],
86
- 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)",
86
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)",
87
87
  type: Hash,
88
88
  optional: true,
89
89
  sensitive: true,
@@ -239,7 +239,17 @@ module Match
239
239
  default_value: false),
240
240
  FastlaneCore::ConfigItem.new(key: :force_for_new_devices,
241
241
  env_name: "MATCH_FORCE_FOR_NEW_DEVICES",
242
- description: "Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile type 'appstore'",
242
+ description: "Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile types 'appstore' and 'developer_id'",
243
+ type: Boolean,
244
+ default_value: false),
245
+ FastlaneCore::ConfigItem.new(key: :include_all_certificates,
246
+ env_name: "MATCH_INCLUDE_ALL_CERTIFICATES",
247
+ description: "Include all matching certificates in the provisioning profile. Works only for the 'development' provisioning profile type",
248
+ type: Boolean,
249
+ default_value: false),
250
+ FastlaneCore::ConfigItem.new(key: :force_for_new_certificates,
251
+ env_name: "MATCH_FORCE_FOR_NEW_CERTIFICATES",
252
+ description: "Renew the provisioning profiles if the device count on the developer portal has changed. Works only for the 'development' provisioning profile type. Requires 'include_all_certificates' option to be 'true'",
243
253
  type: Boolean,
244
254
  default_value: false),
245
255
  FastlaneCore::ConfigItem.new(key: :skip_confirmation,
@@ -12,6 +12,7 @@ require_relative 'storage'
12
12
  require_relative 'encryption'
13
13
 
14
14
  module Match
15
+ # rubocop:disable Metrics/ClassLength
15
16
  class Runner
16
17
  attr_accessor :files_to_commit
17
18
  attr_accessor :spaceship
@@ -191,12 +192,12 @@ module Match
191
192
  UI.verbose("Certificate '#{File.basename(cert_path)}' is already installed on this machine")
192
193
  else
193
194
  Utils.import(cert_path, params[:keychain_name], password: params[:keychain_password])
194
- end
195
195
 
196
- # Import the private key
197
- # there seems to be no good way to check if it's already installed - so just install it
198
- # Key will only be added to the partition list if it isn't already installed
199
- Utils.import(keys.last, params[:keychain_name], password: params[:keychain_password])
196
+ # Import the private key
197
+ # there seems to be no good way to check if it's already installed - so just install it
198
+ # Key will only be added to the partition list if it isn't already installed
199
+ Utils.import(keys.last, params[:keychain_name], password: params[:keychain_password])
200
+ end
200
201
  else
201
202
  UI.message("Skipping installation of certificate as it would not work on this operating system.")
202
203
  end
@@ -242,15 +243,14 @@ module Match
242
243
  profile = profiles.last
243
244
  force = params[:force]
244
245
 
245
- if params[:force_for_new_devices] && !params[:readonly]
246
- if prov_type != :appstore && !params[:force]
247
- force = device_count_different?(profile: profile, keychain_path: keychain_path, platform: params[:platform].to_sym)
248
- else
249
- # App Store provisioning profiles don't contain device identifiers and
250
- # thus shouldn't be renewed if the device count has changed.
251
- UI.important("Warning: `force_for_new_devices` is set but is ignored for App Store provisioning profiles.")
252
- UI.important("You can safely stop specifying `force_for_new_devices` when running Match for type 'appstore'.")
253
- end
246
+ if params[:force_for_new_devices]
247
+ force = should_force_include_all_devices(params: params, prov_type: prov_type, profile: profile, keychain_path: keychain_path) unless force
248
+ end
249
+
250
+ if params[:include_all_certificates]
251
+ # Clearing specified certificate id which will prevent a profile being created with only one certificate
252
+ certificate_id = nil
253
+ force = should_force_include_all_certificates(params: params, prov_type: prov_type, profile: profile, keychain_path: keychain_path) unless force
254
254
  end
255
255
 
256
256
  if profile.nil? || force
@@ -318,6 +318,24 @@ module Match
318
318
  end
319
319
  # rubocop:enable Metrics/PerceivedComplexity
320
320
 
321
+ def should_force_include_all_devices(params: nil, prov_type: nil, profile: nil, keychain_path: nil)
322
+ return false unless params[:force_for_new_devices] && !params[:readonly]
323
+
324
+ force = false
325
+
326
+ prov_types_without_devices = [:appstore, :developer_id]
327
+ if !prov_types_without_devices.include?(prov_type) && !params[:force]
328
+ force = device_count_different?(profile: profile, keychain_path: keychain_path, platform: params[:platform].to_sym)
329
+ else
330
+ # App Store provisioning profiles don't contain device identifiers and
331
+ # thus shouldn't be renewed if the device count has changed.
332
+ UI.important("Warning: `force_for_new_devices` is set but is ignored for App Store & Developer ID provisioning profiles.")
333
+ UI.important("You can safely stop specifying `force_for_new_devices` when running Match for type 'appstore' or 'developer_id'.")
334
+ end
335
+
336
+ return force
337
+ end
338
+
321
339
  def device_count_different?(profile: nil, keychain_path: nil, platform: nil)
322
340
  return false unless profile
323
341
 
@@ -343,7 +361,7 @@ module Match
343
361
  [
344
362
  Spaceship::ConnectAPI::Device::DeviceClass::APPLE_TV
345
363
  ]
346
- when :mac, :catalyst
364
+ when :macos, :catalyst
347
365
  [
348
366
  Spaceship::ConnectAPI::Device::DeviceClass::MAC
349
367
  ]
@@ -364,5 +382,72 @@ module Match
364
382
  end
365
383
  return false
366
384
  end
385
+
386
+ def should_force_include_all_certificates(params: nil, prov_type: nil, profile: nil, keychain_path: nil)
387
+ unless params[:include_all_certificates]
388
+ if params[:force_for_new_certificates]
389
+ UI.important("You specified 'force_for_new_certificates: true', but new certificates will not be added, cause 'include_all_certificates' is 'false'")
390
+ end
391
+ return false
392
+ end
393
+
394
+ force = false
395
+
396
+ if params[:force_for_new_certificates] && !params[:readonly]
397
+ if prov_type == :development && !params[:force]
398
+ force = certificate_count_different?(profile: profile, keychain_path: keychain_path, platform: params[:platform].to_sym)
399
+ else
400
+ # All other (not development) provisioning profiles don't contain
401
+ # multiple certificates, thus shouldn't be renewed
402
+ # if the certificates count has changed.
403
+ UI.important("Warning: `force_for_new_certificates` is set but is ignored for non-'development' provisioning profiles.")
404
+ UI.important("You can safely stop specifying `force_for_new_certificates` when running Match for '#{prov_type}' provisioning profiles.")
405
+ end
406
+ end
407
+
408
+ return force
409
+ end
410
+
411
+ def certificate_count_different?(profile: nil, keychain_path: nil, platform: nil)
412
+ return false unless profile
413
+
414
+ parsed = FastlaneCore::ProvisioningProfile.parse(profile, keychain_path)
415
+ uuid = parsed["UUID"]
416
+
417
+ all_profiles = Spaceship::ConnectAPI::Profile.all(includes: "certificates")
418
+ portal_profile = all_profiles.detect { |i| i.uuid == uuid }
419
+
420
+ return false unless portal_profile
421
+
422
+ profile_certs_count = portal_profile.fetch_all_certificates.count
423
+
424
+ certificate_types =
425
+ case platform
426
+ when :ios, :tvos
427
+ [
428
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT,
429
+ Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT
430
+ ]
431
+ when :macos, :catalyst
432
+ [
433
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT,
434
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DEVELOPMENT
435
+ ]
436
+ else
437
+ []
438
+ end
439
+
440
+ certificates = Spaceship::ConnectAPI::Certificate.all
441
+ unless certificate_types.empty?
442
+ certificates = certificates.select do |certificate|
443
+ certificate_types.include?(certificate.certificateType) && certificate.valid?
444
+ end
445
+ end
446
+
447
+ portal_certs_count = certificates.size
448
+
449
+ return portal_certs_count != profile_certs_count
450
+ end
367
451
  end
452
+ # rubocop:enable Metrics/ClassLength
368
453
  end
@@ -16,7 +16,7 @@ module Pilot
16
16
  should_login_in_start = options[:apple_id].nil?
17
17
  start(options, should_login: should_login_in_start)
18
18
 
19
- UI.user_error!("No ipa file given") unless config[:ipa]
19
+ UI.user_error!("No ipa or pkg file given") if config[:ipa].nil? && config[:pkg].nil?
20
20
 
21
21
  check_for_changelog_or_whats_new!(options)
22
22
 
@@ -25,10 +25,17 @@ module Pilot
25
25
  dir = Dir.mktmpdir
26
26
 
27
27
  platform = fetch_app_platform
28
- package_path = FastlaneCore::IpaUploadPackageBuilder.new.generate(app_id: fetch_app_id,
28
+ if options[:ipa]
29
+ package_path = FastlaneCore::IpaUploadPackageBuilder.new.generate(app_id: fetch_app_id,
29
30
  ipa_path: options[:ipa],
30
31
  package_path: dir,
31
32
  platform: platform)
33
+ else
34
+ package_path = FastlaneCore::PkgUploadPackageBuilder.new.generate(app_id: fetch_app_id,
35
+ pkg_path: options[:pkg],
36
+ package_path: dir,
37
+ platform: platform)
38
+ end
32
39
 
33
40
  transporter = transporter_for_selected_team(options)
34
41
  result = transporter.upload(package_path: package_path)
@@ -94,6 +101,9 @@ module Pilot
94
101
  if config[:ipa]
95
102
  app_version = FastlaneCore::IpaFileAnalyser.fetch_app_version(config[:ipa])
96
103
  app_build = FastlaneCore::IpaFileAnalyser.fetch_app_build(config[:ipa])
104
+ elsif config[:pkg]
105
+ app_version = FastlaneCore::PkgFileAnalyser.fetch_app_version(config[:pkg])
106
+ app_build = FastlaneCore::PkgFileAnalyser.fetch_app_build(config[:pkg])
97
107
  else
98
108
  app_version = config[:app_version]
99
109
  app_build = config[:build_number]
@@ -108,7 +118,8 @@ module Pilot
108
118
  timeout_duration: config[:wait_processing_timeout_duration],
109
119
  return_when_build_appears: return_when_build_appears,
110
120
  return_spaceship_testflight_build: false,
111
- select_latest: config[:distribute_only]
121
+ select_latest: config[:distribute_only],
122
+ wait_for_build_beta_detail_processing: true
112
123
  )
113
124
 
114
125
  unless latest_build.app_version == app_version && latest_build.version == app_build
@@ -73,7 +73,8 @@ module Pilot
73
73
 
74
74
  def fetch_app_identifier
75
75
  result = config[:app_identifier]
76
- result ||= FastlaneCore::IpaFileAnalyser.fetch_app_identifier(config[:ipa])
76
+ result ||= FastlaneCore::IpaFileAnalyser.fetch_app_identifier(config[:ipa]) if config[:ipa]
77
+ result ||= FastlaneCore::PkgFileAnalyser.fetch_app_identifier(config[:pkg]) if config[:pkg]
77
78
  result ||= UI.input("Please enter the app's bundle identifier: ")
78
79
  UI.verbose("App identifier (#{result})")
79
80
  return result
@@ -82,6 +83,7 @@ module Pilot
82
83
  def fetch_app_platform(required: true)
83
84
  result = config[:app_platform]
84
85
  result ||= FastlaneCore::IpaFileAnalyser.fetch_app_platform(config[:ipa]) if config[:ipa]
86
+ result ||= FastlaneCore::PkgFileAnalyser.fetch_app_platform(config[:pkg]) if config[:pkg]
85
87
  if required
86
88
  result ||= UI.input("Please enter the app's platform (appletvos, ios, osx): ")
87
89
  UI.user_error!("App Platform must be ios, appletvos, or osx") unless ['ios', 'appletvos', 'osx'].include?(result)
@@ -20,7 +20,7 @@ module Pilot
20
20
  end),
21
21
  FastlaneCore::ConfigItem.new(key: :api_key,
22
22
  env_names: ["PILOT_API_KEY", "APP_STORE_CONNECT_API_KEY"],
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)",
23
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)",
24
24
  type: Hash,
25
25
  optional: true,
26
26
  sensitive: true,
@@ -48,7 +48,6 @@ module Pilot
48
48
  env_name: "PILOT_PLATFORM",
49
49
  description: "The platform to use (optional)",
50
50
  optional: true,
51
- default_value: 'ios',
52
51
  verify_block: proc do |value|
53
52
  UI.user_error!("The platform can only be ios, appletvos, or osx") unless ['ios', 'appletvos', 'osx'].include?(value)
54
53
  end),
@@ -82,6 +81,26 @@ module Pilot
82
81
  value = File.expand_path(value)
83
82
  UI.user_error!("Could not find ipa file at path '#{value}'") unless File.exist?(value)
84
83
  UI.user_error!("'#{value}' doesn't seem to be an ipa file") unless value.end_with?(".ipa")
84
+ end,
85
+ conflicting_options: [:pkg],
86
+ conflict_block: proc do |value|
87
+ UI.user_error!("You can't use 'ipa' and '#{value.key}' options in one run.")
88
+ end),
89
+ FastlaneCore::ConfigItem.new(key: :pkg,
90
+ short_option: "-P",
91
+ optional: true,
92
+ env_name: "PILOT_PKG",
93
+ description: "Path to your pkg file",
94
+ code_gen_sensitive: true,
95
+ default_value: Dir["*.pkg"].sort_by { |x| File.mtime(x) }.last,
96
+ default_value_dynamic: true,
97
+ verify_block: proc do |value|
98
+ UI.user_error!("Could not find pkg file at path '#{File.expand_path(value)}'") unless File.exist?(value)
99
+ UI.user_error!("'#{value}' doesn't seem to be a pkg file") unless value.end_with?(".pkg")
100
+ end,
101
+ conflicting_options: [:ipa],
102
+ conflict_block: proc do |value|
103
+ UI.user_error!("You can't use 'pkg' and '#{value.key}' options in one run.")
85
104
  end),
86
105
 
87
106
  # app review info
@@ -35,7 +35,7 @@ module Precheck
35
35
  end),
36
36
  FastlaneCore::ConfigItem.new(key: :api_key,
37
37
  env_names: ["PRECHECK_API_KEY", "APP_STORE_CONNECT_API_KEY"],
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)",
38
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)",
39
39
  type: Hash,
40
40
  optional: true,
41
41
  sensitive: true,
@@ -644,7 +644,7 @@ function resign {
644
644
  # Get the old and new app identifier (prefix)
645
645
  APP_ID_KEY="application-identifier"
646
646
  # Extract just the identifier from the value
647
- # Use the fact that we are after some identifer, which is always at the start of the string
647
+ # Use the fact that we are after some identifier, which is always at the start of the string
648
648
  OLD_APP_ID=$(PlistBuddy -c "Print $APP_ID_KEY" "$APP_ENTITLEMENTS" | grep -E '^[A-Z0-9]*' -o | tr -d '\n')
649
649
  NEW_APP_ID=$(PlistBuddy -c "Print $APP_ID_KEY" "$PROFILE_ENTITLEMENTS" | grep -E '^[A-Z0-9]*' -o | tr -d '\n')
650
650
 
@@ -66,7 +66,7 @@ module Sigh
66
66
  end),
67
67
  FastlaneCore::ConfigItem.new(key: :api_key,
68
68
  env_names: ["SIGH_API_KEY", "APP_STORE_CONNECT_API_KEY"],
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)",
69
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)",
70
70
  type: Hash,
71
71
  optional: true,
72
72
  sensitive: true,
@@ -144,6 +144,11 @@ module Sigh
144
144
  is_string: false,
145
145
  default_value: false,
146
146
  short_option: "-w"),
147
+ FastlaneCore::ConfigItem.new(key: :include_all_certificates,
148
+ env_name: "SIGH_INCLUDE_ALL_CERTIFICATES",
149
+ description: "Include all matching certificates in the provisioning profile. Works only for the 'development' provisioning profile type",
150
+ is_string: false,
151
+ default_value: false),
147
152
  FastlaneCore::ConfigItem.new(key: :skip_certificate_verification,
148
153
  short_option: '-z',
149
154
  env_name: "SIGH_SKIP_CERTIFICATE_VERIFICATION",
@@ -114,7 +114,7 @@ module Sigh
114
114
 
115
115
  # Take the provisioning profile name into account
116
116
  results = filter_profiles_by_name(results) if Sigh.config[:provisioning_name].to_s.length > 0
117
- return results if Sigh.config[:skip_certificate_verification]
117
+ return results if Sigh.config[:skip_certificate_verification] || Sigh.config[:include_all_certificates]
118
118
 
119
119
  UI.message("Verifying certificates...")
120
120
  return results.find_all do |current_profile|
@@ -311,7 +311,7 @@ module Sigh
311
311
 
312
312
  # verify certificates
313
313
  if Helper.mac?
314
- unless Sigh.config[:skip_certificate_verification]
314
+ unless Sigh.config[:skip_certificate_verification] || Sigh.config[:include_all_certificates]
315
315
  certificates = certificates.find_all do |c|
316
316
  file = Tempfile.new('cert')
317
317
  raw_data = Base64.decode64(c.certificate_content)
@@ -123,7 +123,7 @@ module Snapshot
123
123
  type: Boolean),
124
124
  FastlaneCore::ConfigItem.new(key: :override_status_bar,
125
125
  env_name: 'SNAPSHOT_OVERRIDE_STATUS_BAR',
126
- description: "Enabling this option will automatically override the status bar to show 9:41 AM, full battery, and full reception",
126
+ description: "Enabling this option will automatically override the status bar to show 9:41 AM, full battery, and full reception (Adjust 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environment variable if override status bar is not working. Might be because simulator is not fully booted. Defaults to 10 seconds)",
127
127
  default_value: false,
128
128
  is_string: false),
129
129
  FastlaneCore::ConfigItem.new(key: :override_status_bar_arguments,
@@ -116,7 +116,15 @@ module Snapshot
116
116
  device_udid = TestCommandGenerator.device_udid(device_type)
117
117
 
118
118
  UI.message("Launch Simulator #{device_type}")
119
- Helper.backticks("xcrun instruments -w #{device_udid} &> /dev/null")
119
+ # Boot the simulator and wait for it to finish booting
120
+ Helper.backticks("xcrun simctl bootstatus #{device_udid} -b &> /dev/null")
121
+
122
+ # "Booted" status is not enough for to adjust the status bar
123
+ # Simulator could stil be booting with Apple logo
124
+ # Need to wait "some amount of time" until home screen shows
125
+ boot_sleep = ENV["SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT"].to_i || 10
126
+ UI.message("Waiting #{boot_sleep} seconds for device to fully boot before overriding status bar... Set 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environemnt variable to adjust timeout")
127
+ sleep(boot_sleep) if boot_sleep > 0
120
128
 
121
129
  UI.message("Overriding Status Bar")
122
130