fastlane 2.192.0 → 2.195.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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