fastlane 2.240.1 → 2.241.1

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +51 -171
  3. data/bin/fastlane +4 -2
  4. data/credentials_manager/README.md +1 -1
  5. data/deliver/lib/deliver/app_screenshot.rb +8 -4
  6. data/deliver/lib/deliver/commands_generator.rb +1 -1
  7. data/deliver/lib/deliver/download_screenshots.rb +8 -1
  8. data/deliver/lib/deliver/sync_screenshots.rb +27 -28
  9. data/deliver/lib/deliver/upload_app_clip_default_experience_header_images.rb +3 -3
  10. data/deliver/lib/deliver/upload_metadata.rb +12 -16
  11. data/deliver/lib/deliver/upload_screenshots.rb +12 -14
  12. data/docs/README.md +25 -0
  13. data/fastlane/lib/assets/TeamTable.md.erb +28 -0
  14. data/fastlane/lib/fastlane/actions/appaloosa.rb +2 -1
  15. data/fastlane/lib/fastlane/actions/appium.rb +1 -1
  16. data/fastlane/lib/fastlane/actions/apteligent.rb +8 -1
  17. data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +3 -0
  19. data/fastlane/lib/fastlane/actions/danger.rb +5 -5
  20. data/fastlane/lib/fastlane/actions/docs/build_app.md +1 -2
  21. data/fastlane/lib/fastlane/actions/docs/create_app_online.md +1 -2
  22. data/fastlane/lib/fastlane/actions/docs/get_certificates.md +0 -2
  23. data/fastlane/lib/fastlane/actions/docs/get_push_certificate.md +1 -3
  24. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +13 -3
  25. data/fastlane/lib/fastlane/actions/ensure_no_debug_code.rb +2 -2
  26. data/fastlane/lib/fastlane/actions/get_managed_play_store_publishing_rights.rb +1 -0
  27. data/fastlane/lib/fastlane/actions/github_api.rb +1 -2
  28. data/fastlane/lib/fastlane/actions/hg_commit_version_bump.rb +1 -1
  29. data/fastlane/lib/fastlane/actions/increment_build_number.rb +1 -1
  30. data/fastlane/lib/fastlane/actions/increment_version_number.rb +1 -1
  31. data/fastlane/lib/fastlane/actions/install_xcode_plugin.rb +16 -6
  32. data/fastlane/lib/fastlane/actions/lcov.rb +9 -2
  33. data/fastlane/lib/fastlane/actions/nexus_upload.rb +16 -4
  34. data/fastlane/lib/fastlane/actions/notification.rb +3 -2
  35. data/fastlane/lib/fastlane/actions/oclint.rb +8 -8
  36. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -4
  37. data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
  38. data/fastlane/lib/fastlane/actions/say.rb +2 -4
  39. data/fastlane/lib/fastlane/actions/set_pod_key.rb +3 -3
  40. data/fastlane/lib/fastlane/actions/sonar.rb +16 -16
  41. data/fastlane/lib/fastlane/actions/sourcedocs.rb +8 -8
  42. data/fastlane/lib/fastlane/actions/splunkmint.rb +8 -1
  43. data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +1 -1
  44. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +5 -2
  45. data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +5 -2
  46. data/fastlane/lib/fastlane/actions/verify_build.rb +1 -4
  47. data/fastlane/lib/fastlane/actions/verify_pod_keys.rb +3 -1
  48. data/fastlane/lib/fastlane/actions/xcode_server_get_assets.rb +20 -19
  49. data/fastlane/lib/fastlane/actions/xcodebuild.rb +5 -6
  50. data/fastlane/lib/fastlane/actions/zip.rb +2 -1
  51. data/fastlane/lib/fastlane/auto_complete.rb +1 -1
  52. data/fastlane/lib/fastlane/cli_tools_distributor.rb +14 -0
  53. data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +23 -0
  54. data/fastlane/lib/fastlane/environment_printer.rb +12 -25
  55. data/fastlane/lib/fastlane/fast_file.rb +2 -1
  56. data/fastlane/lib/fastlane/fastlane_require.rb +5 -1
  57. data/fastlane/lib/fastlane/helper/sh_helper.rb +16 -6
  58. data/fastlane/lib/fastlane/new_action.rb +1 -1
  59. data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +1 -1
  60. data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +1 -1
  61. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +36 -4
  62. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
  63. data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +1 -1
  64. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +3 -7
  65. data/fastlane/lib/fastlane/swift_lane_manager.rb +22 -4
  66. data/fastlane/lib/fastlane/version.rb +3 -2
  67. data/fastlane/swift/Deliverfile.swift +1 -1
  68. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  69. data/fastlane/swift/Fastlane.swift +39 -9
  70. data/fastlane/swift/Gymfile.swift +1 -1
  71. data/fastlane/swift/GymfileProtocol.swift +1 -1
  72. data/fastlane/swift/MainProcess.swift +190 -20
  73. data/fastlane/swift/Matchfile.swift +1 -1
  74. data/fastlane/swift/MatchfileProtocol.swift +10 -3
  75. data/fastlane/swift/Precheckfile.swift +1 -1
  76. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  77. data/fastlane/swift/Scanfile.swift +1 -1
  78. data/fastlane/swift/ScanfileProtocol.swift +8 -1
  79. data/fastlane/swift/Screengrabfile.swift +1 -1
  80. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  81. data/fastlane/swift/Snapshotfile.swift +1 -1
  82. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  83. data/fastlane/swift/formatting/Rakefile +1 -0
  84. data/fastlane/swift/main.swift +4 -1
  85. data/fastlane_core/README.md +1 -1
  86. data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +1 -17
  87. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +11 -8
  88. data/fastlane_core/lib/fastlane_core/device_manager.rb +2 -2
  89. data/fastlane_core/lib/fastlane_core/helper.rb +34 -5
  90. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +0 -14
  91. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +24 -27
  92. data/fastlane_core/lib/fastlane_core/languages.rb +0 -1
  93. data/fastlane_core/lib/fastlane_core/print_table.rb +5 -2
  94. data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +10 -19
  95. data/fastlane_core/lib/fastlane_core/secrets.rb +77 -0
  96. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +3 -3
  97. data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +1 -1
  98. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +2 -1
  99. data/fastlane_core/lib/fastlane_core.rb +1 -0
  100. data/frameit/lib/frameit/device.rb +1 -1
  101. data/frameit/lib/frameit/frame_downloader.rb +2 -0
  102. data/frameit/lib/frameit/runner.rb +3 -2
  103. data/frameit/lib/frameit/screenshot.rb +0 -1
  104. data/gym/lib/gym/generators/build_command_generator.rb +4 -4
  105. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +3 -3
  106. data/gym/lib/gym/runner.rb +1 -1
  107. data/internal/README.md +1 -1
  108. data/match/lib/match/generator.rb +1 -0
  109. data/match/lib/match/options.rb +13 -5
  110. data/match/lib/match/storage/git_storage.rb +43 -7
  111. data/match/lib/match/storage/gitlab/secure_file.rb +2 -1
  112. data/pem/lib/pem/module.rb +0 -4
  113. data/precheck/lib/precheck/rule_processor.rb +1 -0
  114. data/produce/lib/produce/itunes_connect.rb +1 -1
  115. data/produce/lib/produce/service.rb +0 -1
  116. data/produce/lib/produce.rb +0 -1
  117. data/scan/lib/scan/options.rb +7 -0
  118. data/scan/lib/scan/runner.rb +1 -1
  119. data/scan/lib/scan/test_command_generator.rb +12 -9
  120. data/scan/lib/scan/test_result_parser.rb +1 -0
  121. data/scan/lib/scan/xcpretty_reporter_options_generator.rb +2 -2
  122. data/screengrab/lib/screengrab/page.html.erb +12 -7
  123. data/screengrab/lib/screengrab/reports_generator.rb +1 -1
  124. data/sigh/lib/assets/resign.sh +17 -0
  125. data/sigh/lib/sigh/local_manage.rb +1 -1
  126. data/sigh/lib/sigh/options.rb +5 -0
  127. data/sigh/lib/sigh/resign.rb +3 -3
  128. data/sigh/lib/sigh/runner.rb +6 -1
  129. data/snapshot/lib/snapshot/page.html.erb +17 -12
  130. data/snapshot/lib/snapshot/reports_generator.rb +3 -1
  131. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +1 -1
  132. data/snapshot/lib/snapshot.rb +0 -2
  133. data/spaceship/README.md +2 -3
  134. data/spaceship/lib/spaceship/base.rb +3 -1
  135. data/spaceship/lib/spaceship/client.rb +65 -47
  136. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +2 -0
  137. data/spaceship/lib/spaceship/connect_api/models/profile.rb +7 -5
  138. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +9 -0
  139. data/spaceship/lib/spaceship/du/upload_file.rb +1 -1
  140. data/spaceship/lib/spaceship/errors.rb +7 -1
  141. data/spaceship/lib/spaceship/globals.rb +2 -2
  142. data/spaceship/lib/spaceship/portal/merchant.rb +127 -2
  143. data/spaceship/lib/spaceship/portal/portal_client.rb +58 -0
  144. data/spaceship/lib/spaceship/portal/ui/select_team.rb +0 -2
  145. data/spaceship/lib/spaceship/portal/website_push.rb +8 -2
  146. data/spaceship/lib/spaceship/test_flight/client.rb +0 -22
  147. data/spaceship/lib/spaceship/test_flight.rb +0 -1
  148. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +11 -0
  149. data/supply/lib/supply/options.rb +1 -0
  150. data/supply/lib/supply.rb +0 -1
  151. metadata +55 -37
  152. data/produce/lib/produce/available_default_languages.rb +0 -62
  153. data/snapshot/lib/snapshot/screenshot_flatten.rb +0 -20
  154. data/snapshot/lib/snapshot/screenshot_rotate.rb +0 -36
  155. data/spaceship/lib/spaceship/test_flight/app_test_info.rb +0 -40
  156. data/supply/lib/supply/apk_listing.rb +0 -14
  157. /data/fastlane/lib/assets/{custom_action_template.rb → custom_action_template.rb.template} +0 -0
@@ -3068,6 +3068,8 @@ public func chatwork(apiToken: String,
3068
3068
 
3069
3069
  This action deletes the files that get created in your repo as a result of running the _gym_ and _sigh_ commands. It doesn't delete the `fastlane/report.xml` though, this is probably more suited for the .gitignore.
3070
3070
 
3071
+ From _cert_ it only deletes the `.cer` file. The private key (`<certificate id>.p12`, despite its name an unencrypted PEM key) and the `.certSigningRequest` that _cert_ writes to its `output_path` when it creates a certificate are kept: _cert_ uses that `.p12` to install the certificate on a machine that doesn't have it, and on systems other than macOS it is the only copy of the key. Keep them out of version control.
3072
+
3071
3073
  Useful if you quickly want to send out a test build by dropping down to the command line and typing something like `fastlane beta`, without leaving your repo in a messy state afterwards.
3072
3074
  */
3073
3075
  public func cleanBuildArtifacts(excludePattern: OptionalConfigValue<String?> = .fastlaneDefault(nil)) {
@@ -5214,6 +5216,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
5214
5216
  - force: Renew provisioning profiles regardless of its state - to automatically add all devices for ad hoc profiles
5215
5217
  - includeMacInProfiles: Include Apple Silicon Mac devices in provisioning profiles for iOS/iPadOS apps
5216
5218
  - appIdentifier: The bundle identifier of your app
5219
+ - offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
5217
5220
  - apiKeyPath: Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
5218
5221
  - apiKey: Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
5219
5222
  - username: Your Apple ID Username
@@ -5248,6 +5251,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
5248
5251
  force: OptionalConfigValue<Bool> = .fastlaneDefault(false),
5249
5252
  includeMacInProfiles: OptionalConfigValue<Bool> = .fastlaneDefault(false),
5250
5253
  appIdentifier: String,
5254
+ offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
5251
5255
  apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
5252
5256
  apiKey: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
5253
5257
  username: OptionalConfigValue<String?> = .fastlaneDefault(nil),
@@ -5278,6 +5282,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
5278
5282
  let forceArg = force.asRubyArgument(name: "force", type: nil)
5279
5283
  let includeMacInProfilesArg = includeMacInProfiles.asRubyArgument(name: "include_mac_in_profiles", type: nil)
5280
5284
  let appIdentifierArg = RubyCommand.Argument(name: "app_identifier", value: appIdentifier, type: nil)
5285
+ let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
5281
5286
  let apiKeyPathArg = apiKeyPath.asRubyArgument(name: "api_key_path", type: nil)
5282
5287
  let apiKeyArg = apiKey.asRubyArgument(name: "api_key", type: nil)
5283
5288
  let usernameArg = username.asRubyArgument(name: "username", type: nil)
@@ -5307,6 +5312,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
5307
5312
  forceArg,
5308
5313
  includeMacInProfilesArg,
5309
5314
  appIdentifierArg,
5315
+ offlineProfileArg,
5310
5316
  apiKeyPathArg,
5311
5317
  apiKeyArg,
5312
5318
  usernameArg,
@@ -6923,8 +6929,8 @@ public func makeChangelogFromJenkins(fallbackChangelog: String = "",
6923
6929
  - gitUserEmail: git user email to commit
6924
6930
  - shallowClone: Make a shallow clone of the repository (truncate the history to 1 revision)
6925
6931
  - cloneBranchDirectly: Clone just the branch specified, instead of the whole repo. This requires that the branch already exists. Otherwise the command will fail
6926
- - gitBasicAuthorization: Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64
6927
- - gitBearerAuthorization: Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64
6932
+ - gitBasicAuthorization: Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64. Needs git 2.31 or later
6933
+ - gitBearerAuthorization: Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64. Needs git 2.31 or later
6928
6934
  - gitPrivateKey: Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof
6929
6935
  - googleCloudBucketName: Name of the Google Cloud Storage bucket to use
6930
6936
  - googleCloudKeysFile: Path to the gc_keys.json file
@@ -6962,6 +6968,7 @@ public func makeChangelogFromJenkins(fallbackChangelog: String = "",
6962
6968
  - outputPath: Path in which to export certificates, key and profile
6963
6969
  - skipSetPartitionList: Skips setting the partition list (which can sometimes take a long time). Setting the partition list is usually needed to prevent Xcode from prompting to allow a cert to be used for signing
6964
6970
  - forceLegacyEncryption: Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
6971
+ - offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
6965
6972
  - verbose: Print out extra information and all commands
6966
6973
 
6967
6974
  More information: https://docs.fastlane.tools/actions/match/
@@ -7023,6 +7030,7 @@ public func match(type: String = matchfile.type,
7023
7030
  outputPath: OptionalConfigValue<String?> = .fastlaneDefault(matchfile.outputPath),
7024
7031
  skipSetPartitionList: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.skipSetPartitionList),
7025
7032
  forceLegacyEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.forceLegacyEncryption),
7033
+ offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.offlineProfile),
7026
7034
  verbose: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.verbose))
7027
7035
  {
7028
7036
  let typeArg = RubyCommand.Argument(name: "type", value: type, type: nil)
@@ -7082,6 +7090,7 @@ public func match(type: String = matchfile.type,
7082
7090
  let outputPathArg = outputPath.asRubyArgument(name: "output_path", type: nil)
7083
7091
  let skipSetPartitionListArg = skipSetPartitionList.asRubyArgument(name: "skip_set_partition_list", type: nil)
7084
7092
  let forceLegacyEncryptionArg = forceLegacyEncryption.asRubyArgument(name: "force_legacy_encryption", type: nil)
7093
+ let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
7085
7094
  let verboseArg = verbose.asRubyArgument(name: "verbose", type: nil)
7086
7095
  let array: [RubyCommand.Argument?] = [typeArg,
7087
7096
  additionalCertTypesArg,
@@ -7140,6 +7149,7 @@ public func match(type: String = matchfile.type,
7140
7149
  outputPathArg,
7141
7150
  skipSetPartitionListArg,
7142
7151
  forceLegacyEncryptionArg,
7152
+ offlineProfileArg,
7143
7153
  verboseArg]
7144
7154
  let args: [RubyCommand.Argument] = array
7145
7155
  .filter { $0?.value != nil }
@@ -7170,8 +7180,8 @@ public func match(type: String = matchfile.type,
7170
7180
  - gitUserEmail: git user email to commit
7171
7181
  - shallowClone: Make a shallow clone of the repository (truncate the history to 1 revision)
7172
7182
  - cloneBranchDirectly: Clone just the branch specified, instead of the whole repo. This requires that the branch already exists. Otherwise the command will fail
7173
- - gitBasicAuthorization: Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64
7174
- - gitBearerAuthorization: Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64
7183
+ - gitBasicAuthorization: Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64. Needs git 2.31 or later
7184
+ - gitBearerAuthorization: Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64. Needs git 2.31 or later
7175
7185
  - gitPrivateKey: Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof
7176
7186
  - googleCloudBucketName: Name of the Google Cloud Storage bucket to use
7177
7187
  - googleCloudKeysFile: Path to the gc_keys.json file
@@ -7209,6 +7219,7 @@ public func match(type: String = matchfile.type,
7209
7219
  - outputPath: Path in which to export certificates, key and profile
7210
7220
  - skipSetPartitionList: Skips setting the partition list (which can sometimes take a long time). Setting the partition list is usually needed to prevent Xcode from prompting to allow a cert to be used for signing
7211
7221
  - forceLegacyEncryption: Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
7222
+ - offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
7212
7223
  - verbose: Print out extra information and all commands
7213
7224
 
7214
7225
  Use the match_nuke action to revoke your certificates and provisioning profiles.
@@ -7274,6 +7285,7 @@ public func matchNuke(type: String = "development",
7274
7285
  outputPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
7275
7286
  skipSetPartitionList: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7276
7287
  forceLegacyEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7288
+ offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7277
7289
  verbose: OptionalConfigValue<Bool> = .fastlaneDefault(false))
7278
7290
  {
7279
7291
  let typeArg = RubyCommand.Argument(name: "type", value: type, type: nil)
@@ -7333,6 +7345,7 @@ public func matchNuke(type: String = "development",
7333
7345
  let outputPathArg = outputPath.asRubyArgument(name: "output_path", type: nil)
7334
7346
  let skipSetPartitionListArg = skipSetPartitionList.asRubyArgument(name: "skip_set_partition_list", type: nil)
7335
7347
  let forceLegacyEncryptionArg = forceLegacyEncryption.asRubyArgument(name: "force_legacy_encryption", type: nil)
7348
+ let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
7336
7349
  let verboseArg = verbose.asRubyArgument(name: "verbose", type: nil)
7337
7350
  let array: [RubyCommand.Argument?] = [typeArg,
7338
7351
  additionalCertTypesArg,
@@ -7391,6 +7404,7 @@ public func matchNuke(type: String = "development",
7391
7404
  outputPathArg,
7392
7405
  skipSetPartitionListArg,
7393
7406
  forceLegacyEncryptionArg,
7407
+ offlineProfileArg,
7394
7408
  verboseArg]
7395
7409
  let args: [RubyCommand.Argument] = array
7396
7410
  .filter { $0?.value != nil }
@@ -7581,8 +7595,8 @@ public func notarize(package: String,
7581
7595
  - message: The message to display in the notification
7582
7596
  - sound: The name of a sound to play when the notification appears (names are listed in Sound Preferences)
7583
7597
  - activate: Bundle identifier of application to be opened when the notification is clicked
7584
- - appIcon: The URL of an image to display instead of the application icon (Mavericks+ only)
7585
- - contentImage: The URL of an image to display attached to the notification (Mavericks+ only)
7598
+ - appIcon: **DEPRECATED!** The URL of an image to display instead of the application icon
7599
+ - contentImage: The local path of an image to display attached to the notification (Mavericks+)
7586
7600
  - open: URL of the resource to be opened when the notification is clicked
7587
7601
  - execute: Shell command to run when the notification is clicked
7588
7602
  */
@@ -9002,6 +9016,7 @@ public func rubyVersion() {
9002
9016
  - codeCoverage: Should code coverage be generated? (Xcode 7 and up)
9003
9017
  - addressSanitizer: Should the address sanitizer be turned on?
9004
9018
  - threadSanitizer: Should the thread sanitizer be turned on?
9019
+ - collectTestDiagnostics: Whether verbose and long-running diagnostics (like sysdiagnoses or log archives) are collected when testing. Valid values are: on-failure or never. If not specified, the value in the test plan is used. Equivalent to -collect-test-diagnostics (Xcode 14 and up)
9005
9020
  - openReport: Should the HTML report be opened when tests are completed?
9006
9021
  - outputDirectory: The directory in which all reports will be stored
9007
9022
  - outputStyle: Define how the output should look like. Valid values are: standard, basic, rspec, or raw (disables xcpretty during xcodebuild)
@@ -9090,6 +9105,7 @@ public func rubyVersion() {
9090
9105
  codeCoverage: OptionalConfigValue<Bool?> = .fastlaneDefault(nil),
9091
9106
  addressSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(nil),
9092
9107
  threadSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(nil),
9108
+ collectTestDiagnostics: OptionalConfigValue<String?> = .fastlaneDefault(nil),
9093
9109
  openReport: OptionalConfigValue<Bool> = .fastlaneDefault(false),
9094
9110
  outputDirectory: String = "./test_output",
9095
9111
  outputStyle: OptionalConfigValue<String?> = .fastlaneDefault(nil),
@@ -9174,6 +9190,7 @@ public func rubyVersion() {
9174
9190
  let codeCoverageArg = codeCoverage.asRubyArgument(name: "code_coverage", type: nil)
9175
9191
  let addressSanitizerArg = addressSanitizer.asRubyArgument(name: "address_sanitizer", type: nil)
9176
9192
  let threadSanitizerArg = threadSanitizer.asRubyArgument(name: "thread_sanitizer", type: nil)
9193
+ let collectTestDiagnosticsArg = collectTestDiagnostics.asRubyArgument(name: "collect_test_diagnostics", type: nil)
9177
9194
  let openReportArg = openReport.asRubyArgument(name: "open_report", type: nil)
9178
9195
  let outputDirectoryArg = RubyCommand.Argument(name: "output_directory", value: outputDirectory, type: nil)
9179
9196
  let outputStyleArg = outputStyle.asRubyArgument(name: "output_style", type: nil)
@@ -9257,6 +9274,7 @@ public func rubyVersion() {
9257
9274
  codeCoverageArg,
9258
9275
  addressSanitizerArg,
9259
9276
  threadSanitizerArg,
9277
+ collectTestDiagnosticsArg,
9260
9278
  openReportArg,
9261
9279
  outputDirectoryArg,
9262
9280
  outputStyleArg,
@@ -9453,6 +9471,7 @@ public func say(text: [String],
9453
9471
  - codeCoverage: Should code coverage be generated? (Xcode 7 and up)
9454
9472
  - addressSanitizer: Should the address sanitizer be turned on?
9455
9473
  - threadSanitizer: Should the thread sanitizer be turned on?
9474
+ - collectTestDiagnostics: Whether verbose and long-running diagnostics (like sysdiagnoses or log archives) are collected when testing. Valid values are: on-failure or never. If not specified, the value in the test plan is used. Equivalent to -collect-test-diagnostics (Xcode 14 and up)
9456
9475
  - openReport: Should the HTML report be opened when tests are completed?
9457
9476
  - outputDirectory: The directory in which all reports will be stored
9458
9477
  - outputStyle: Define how the output should look like. Valid values are: standard, basic, rspec, or raw (disables xcpretty during xcodebuild)
@@ -9541,6 +9560,7 @@ public func say(text: [String],
9541
9560
  codeCoverage: OptionalConfigValue<Bool?> = .fastlaneDefault(scanfile.codeCoverage),
9542
9561
  addressSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(scanfile.addressSanitizer),
9543
9562
  threadSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(scanfile.threadSanitizer),
9563
+ collectTestDiagnostics: OptionalConfigValue<String?> = .fastlaneDefault(scanfile.collectTestDiagnostics),
9544
9564
  openReport: OptionalConfigValue<Bool> = .fastlaneDefault(scanfile.openReport),
9545
9565
  outputDirectory: String = scanfile.outputDirectory,
9546
9566
  outputStyle: OptionalConfigValue<String?> = .fastlaneDefault(scanfile.outputStyle),
@@ -9625,6 +9645,7 @@ public func say(text: [String],
9625
9645
  let codeCoverageArg = codeCoverage.asRubyArgument(name: "code_coverage", type: nil)
9626
9646
  let addressSanitizerArg = addressSanitizer.asRubyArgument(name: "address_sanitizer", type: nil)
9627
9647
  let threadSanitizerArg = threadSanitizer.asRubyArgument(name: "thread_sanitizer", type: nil)
9648
+ let collectTestDiagnosticsArg = collectTestDiagnostics.asRubyArgument(name: "collect_test_diagnostics", type: nil)
9628
9649
  let openReportArg = openReport.asRubyArgument(name: "open_report", type: nil)
9629
9650
  let outputDirectoryArg = RubyCommand.Argument(name: "output_directory", value: outputDirectory, type: nil)
9630
9651
  let outputStyleArg = outputStyle.asRubyArgument(name: "output_style", type: nil)
@@ -9708,6 +9729,7 @@ public func say(text: [String],
9708
9729
  codeCoverageArg,
9709
9730
  addressSanitizerArg,
9710
9731
  threadSanitizerArg,
9732
+ collectTestDiagnosticsArg,
9711
9733
  openReportArg,
9712
9734
  outputDirectoryArg,
9713
9735
  outputStyleArg,
@@ -10311,6 +10333,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
10311
10333
  - force: Renew provisioning profiles regardless of its state - to automatically add all devices for ad hoc profiles
10312
10334
  - includeMacInProfiles: Include Apple Silicon Mac devices in provisioning profiles for iOS/iPadOS apps
10313
10335
  - appIdentifier: The bundle identifier of your app
10336
+ - offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
10314
10337
  - apiKeyPath: Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
10315
10338
  - apiKey: Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
10316
10339
  - username: Your Apple ID Username
@@ -10345,6 +10368,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
10345
10368
  force: OptionalConfigValue<Bool> = .fastlaneDefault(false),
10346
10369
  includeMacInProfiles: OptionalConfigValue<Bool> = .fastlaneDefault(false),
10347
10370
  appIdentifier: String,
10371
+ offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
10348
10372
  apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
10349
10373
  apiKey: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
10350
10374
  username: OptionalConfigValue<String?> = .fastlaneDefault(nil),
@@ -10375,6 +10399,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
10375
10399
  let forceArg = force.asRubyArgument(name: "force", type: nil)
10376
10400
  let includeMacInProfilesArg = includeMacInProfiles.asRubyArgument(name: "include_mac_in_profiles", type: nil)
10377
10401
  let appIdentifierArg = RubyCommand.Argument(name: "app_identifier", value: appIdentifier, type: nil)
10402
+ let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
10378
10403
  let apiKeyPathArg = apiKeyPath.asRubyArgument(name: "api_key_path", type: nil)
10379
10404
  let apiKeyArg = apiKey.asRubyArgument(name: "api_key", type: nil)
10380
10405
  let usernameArg = username.asRubyArgument(name: "username", type: nil)
@@ -10404,6 +10429,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
10404
10429
  forceArg,
10405
10430
  includeMacInProfilesArg,
10406
10431
  appIdentifierArg,
10432
+ offlineProfileArg,
10407
10433
  apiKeyPathArg,
10408
10434
  apiKeyArg,
10409
10435
  usernameArg,
@@ -11536,8 +11562,8 @@ public func swiftlint(mode: String = "lint",
11536
11562
  - gitUserEmail: git user email to commit
11537
11563
  - shallowClone: Make a shallow clone of the repository (truncate the history to 1 revision)
11538
11564
  - cloneBranchDirectly: Clone just the branch specified, instead of the whole repo. This requires that the branch already exists. Otherwise the command will fail
11539
- - gitBasicAuthorization: Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64
11540
- - gitBearerAuthorization: Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64
11565
+ - gitBasicAuthorization: Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64. Needs git 2.31 or later
11566
+ - gitBearerAuthorization: Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64. Needs git 2.31 or later
11541
11567
  - gitPrivateKey: Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof
11542
11568
  - googleCloudBucketName: Name of the Google Cloud Storage bucket to use
11543
11569
  - googleCloudKeysFile: Path to the gc_keys.json file
@@ -11575,6 +11601,7 @@ public func swiftlint(mode: String = "lint",
11575
11601
  - outputPath: Path in which to export certificates, key and profile
11576
11602
  - skipSetPartitionList: Skips setting the partition list (which can sometimes take a long time). Setting the partition list is usually needed to prevent Xcode from prompting to allow a cert to be used for signing
11577
11603
  - forceLegacyEncryption: Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
11604
+ - offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
11578
11605
  - verbose: Print out extra information and all commands
11579
11606
 
11580
11607
  More information: https://docs.fastlane.tools/actions/match/
@@ -11636,6 +11663,7 @@ public func syncCodeSigning(type: String = "development",
11636
11663
  outputPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
11637
11664
  skipSetPartitionList: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11638
11665
  forceLegacyEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11666
+ offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11639
11667
  verbose: OptionalConfigValue<Bool> = .fastlaneDefault(false))
11640
11668
  {
11641
11669
  let typeArg = RubyCommand.Argument(name: "type", value: type, type: nil)
@@ -11695,6 +11723,7 @@ public func syncCodeSigning(type: String = "development",
11695
11723
  let outputPathArg = outputPath.asRubyArgument(name: "output_path", type: nil)
11696
11724
  let skipSetPartitionListArg = skipSetPartitionList.asRubyArgument(name: "skip_set_partition_list", type: nil)
11697
11725
  let forceLegacyEncryptionArg = forceLegacyEncryption.asRubyArgument(name: "force_legacy_encryption", type: nil)
11726
+ let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
11698
11727
  let verboseArg = verbose.asRubyArgument(name: "verbose", type: nil)
11699
11728
  let array: [RubyCommand.Argument?] = [typeArg,
11700
11729
  additionalCertTypesArg,
@@ -11753,6 +11782,7 @@ public func syncCodeSigning(type: String = "development",
11753
11782
  outputPathArg,
11754
11783
  skipSetPartitionListArg,
11755
11784
  forceLegacyEncryptionArg,
11785
+ offlineProfileArg,
11756
11786
  verboseArg]
11757
11787
  let args: [RubyCommand.Argument] = array
11758
11788
  .filter { $0?.value != nil }
@@ -14215,4 +14245,4 @@ public let snapshotfile: Snapshotfile = .init()
14215
14245
 
14216
14246
  // Please don't remove the lines below
14217
14247
  // They are used to detect outdated files
14218
- // FastlaneRunnerAPIVersion [0.9.208]
14248
+ // FastlaneRunnerAPIVersion [0.9.210]
@@ -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.240.1
20
+ // Generated with fastlane 2.241.1
@@ -399,4 +399,4 @@ public extension GymfileProtocol {
399
399
 
400
400
  // Please don't remove the lines below
401
401
  // They are used to detect outdated files
402
- // FastlaneRunnerAPIVersion [0.9.158]
402
+ // FastlaneRunnerAPIVersion [0.9.160]
@@ -9,9 +9,6 @@
9
9
  //
10
10
 
11
11
  import Foundation
12
- #if canImport(SwiftShell)
13
- import SwiftShell
14
- #endif
15
12
 
16
13
  let argumentProcessor = ArgumentProcessor(args: CommandLine.arguments)
17
14
  let timeout = argumentProcessor.commandTimeout
@@ -20,9 +17,7 @@ class MainProcess {
20
17
  var doneRunningLane = false
21
18
  var thread: Thread!
22
19
  #if SWIFT_PACKAGE
23
- var lastPrintDate = Date.distantFuture
24
- var timeBetweenPrints = Int.min
25
- var rubySocketCommand: AsyncCommand!
20
+ var rubySocketCommand: Process!
26
21
  #endif
27
22
 
28
23
  @objc func connectToFastlaneAndRunLane(_ fastfile: LaneFile?) {
@@ -44,24 +39,199 @@ class MainProcess {
44
39
  #endif
45
40
  thread.name = "worker thread"
46
41
  #if SWIFT_PACKAGE
47
- let PATH = run("/bin/bash", "-c", "-l", "eval $(/usr/libexec/path_helper -s) ; echo $PATH").stdout
48
- main.env["PATH"] = PATH
49
- let path = main.run(bash: "which fastlane").stdout
50
- let pids = main.run("lsof", "-t", "-i", ":\(argumentProcessor.port)").stdout.split(separator: "\n")
51
- pids.forEach { main.run("kill", "-9", $0) }
52
- rubySocketCommand = main.runAsync(path, "socket_server", "-c", argumentProcessor.commandTimeout, "-p", argumentProcessor.port)
53
- lastPrintDate = Date()
54
- rubySocketCommand.stderror.onStringOutput { print($0) }
55
- rubySocketCommand.stdout.onStringOutput { stdout in
56
- print(stdout)
57
- self.timeBetweenPrints = Int(self.lastPrintDate.timeIntervalSinceNow)
58
- }
42
+ killExistingSocketServerProcesses(port: argumentProcessor.port)
43
+ abortIfPortIsInUse(argumentProcessor.port)
44
+
45
+ rubySocketCommand = Process()
46
+ rubySocketCommand.launchPath = "/usr/bin/env"
47
+ rubySocketCommand.arguments = fastlaneLaunchArguments() + ["socket_server", "-c", String(timeout), "-p", String(argumentProcessor.port)]
48
+ rubySocketCommand.launch()
59
49
 
60
- // swiftformat:disable:next redundantSelf
61
- _ = Runner.waitWithPolling(self.timeBetweenPrints, toEventually: { $0 > 5 }, timeout: 10)
50
+ waitUntilSocketServerIsListening(port: argumentProcessor.port, serverProcess: rubySocketCommand)
62
51
  thread.start()
63
52
  #endif
64
53
  }
54
+
55
+ #if SWIFT_PACKAGE
56
+ /// Resolves how to invoke fastlane, replacing the previous login-shell
57
+ /// `eval $(path_helper)` + `which fastlane` lookup that broke under
58
+ /// rbenv / bundler / system-ruby mixes (#29238). First match wins:
59
+ /// 1. FASTLANE_SPM_BIN environment variable (explicit override)
60
+ /// 2. bundler binstub bin/fastlane next to the Gemfile
61
+ /// 3. Gemfile (BUNDLE_GEMFILE, or found from the working directory up, as Bundler does) -> bundle exec fastlane
62
+ /// 4. fastlane on PATH
63
+ func fastlaneLaunchArguments() -> [String] {
64
+ if let bin = ProcessInfo.processInfo.environment["FASTLANE_SPM_BIN"],
65
+ !bin.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
66
+ {
67
+ // The shell splits the value, so quoted paths with spaces work; our arguments
68
+ // pass through "$@" untouched, and exec keeps the launched process ID.
69
+ return ["/bin/sh", "-c", "exec \(bin) \"$@\"", "sh"]
70
+ }
71
+ guard let bundleRoot = bundleRootDirectory() else {
72
+ return ["fastlane"]
73
+ }
74
+ let binstub = bundleRoot + "/bin/fastlane"
75
+ if FileManager.default.isExecutableFile(atPath: binstub) {
76
+ return [binstub]
77
+ }
78
+ return ["bundle", "exec", "fastlane"]
79
+ }
80
+
81
+ /// The directory of the Gemfile Bundler would use: BUNDLE_GEMFILE, else the
82
+ /// nearest Gemfile or gems.rb from the working directory up.
83
+ func bundleRootDirectory() -> String? {
84
+ let workingDirectory = FileManager.default.currentDirectoryPath
85
+ if let gemfile = ProcessInfo.processInfo.environment["BUNDLE_GEMFILE"], !gemfile.isEmpty {
86
+ let path = gemfile.hasPrefix("/") ? gemfile : workingDirectory + "/" + gemfile
87
+ return (path as NSString).deletingLastPathComponent
88
+ }
89
+ var directory = workingDirectory
90
+ while true {
91
+ for name in ["Gemfile", "gems.rb"] where FileManager.default.fileExists(atPath: directory + "/" + name) {
92
+ return directory
93
+ }
94
+ let parent = (directory as NSString).deletingLastPathComponent
95
+ if parent == directory || parent.isEmpty {
96
+ return nil
97
+ }
98
+ directory = parent
99
+ }
100
+ }
101
+
102
+ /// The ruby socket server performs a single `accept` (see
103
+ /// fastlane/server/socket_server.rb), so probing readiness with a TCP
104
+ /// connection would consume that accept and shut the server down.
105
+ /// Poll the LISTEN state read-only via lsof instead of the previous
106
+ /// "stdout quiet for 5 seconds" heuristic.
107
+ private func waitUntilSocketServerIsListening(port: UInt32, serverProcess: Process) {
108
+ let deadline = Date(timeIntervalSinceNow: 30)
109
+ while Date() < deadline {
110
+ if !serverProcess.isRunning {
111
+ log(message: "fastlane socket_server exited with status \(serverProcess.terminationStatus) before listening. Check that the resolved fastlane installation works (e.g. `bundle exec fastlane --version`).")
112
+ exit(1)
113
+ }
114
+ if isPortListening(port, by: serverProcess.processIdentifier) {
115
+ return
116
+ }
117
+ Thread.sleep(forTimeInterval: 0.2)
118
+ }
119
+ // Don't leak the socket server: it's still running (just not
120
+ // listening yet) on this timeout path, so terminate it before exit.
121
+ terminate(serverProcess: serverProcess)
122
+ log(message: "fastlane socket_server did not start listening on port \(port) within 30 seconds")
123
+ exit(1)
124
+ }
125
+
126
+ /// Terminate the socket server, escalating SIGTERM to SIGKILL if it
127
+ /// doesn't exit promptly, so the timeout path never leaves an orphan.
128
+ private func terminate(serverProcess: Process) {
129
+ serverProcess.terminate()
130
+ let killDeadline = Date(timeIntervalSinceNow: 2)
131
+ while serverProcess.isRunning, Date() < killDeadline {
132
+ Thread.sleep(forTimeInterval: 0.1)
133
+ }
134
+ if serverProcess.isRunning {
135
+ _ = outputOfProcess(arguments: ["/bin/kill", "-9", String(serverProcess.processIdentifier)])
136
+ serverProcess.waitUntilExit()
137
+ }
138
+ }
139
+
140
+ /// Clears a stale socket server left by a previously crashed run on this
141
+ /// port. Scoped to LISTENing ruby processes (`-sTCP:LISTEN -a -c ruby`)
142
+ /// so it never kills an unrelated service or a connected client that
143
+ /// happens to share the port.
144
+ private func killExistingSocketServerProcesses(port: UInt32) {
145
+ let pids = outputOfProcess(arguments: [lsofPath, "-t", "-nP", "-iTCP:\(port)", "-sTCP:LISTEN", "-a", "-c", "ruby"])
146
+ .split(separator: "\n")
147
+ pids.forEach { _ = outputOfProcess(arguments: ["/bin/kill", "-9", String($0)]) }
148
+ }
149
+
150
+ /// socket_server listens on whichever of 127.0.0.1 and ::1 is free, while the runner connects to `localhost`,
151
+ /// so a process holding the port on either address would receive the runner's commands.
152
+ private func abortIfPortIsInUse(_ port: UInt32) {
153
+ guard isAddressInUse(family: AF_INET, port: port) || isAddressInUse(family: AF_INET6, port: port) else {
154
+ return
155
+ }
156
+ // lsof only lists this user's processes unless run as root
157
+ let holders = outputOfProcess(arguments: [lsofPath, "-nP", "-iTCP:\(port)", "-sTCP:LISTEN"])
158
+ let holder = holders.isEmpty ? " by a process of another user" : ":\n\(holders)"
159
+ log(message: "Port \(port) is already in use on localhost\(holder)\nStop it, or choose another port for the runner with `swiftServerPort`.")
160
+ exit(1)
161
+ }
162
+
163
+ /// Binding fails with EADDRINUSE when another socket listens on that address and port, whoever owns it.
164
+ func isAddressInUse(family: Int32, port: UInt32) -> Bool {
165
+ let socketDescriptor = socket(family, SOCK_STREAM, 0)
166
+ guard socketDescriptor >= 0 else {
167
+ return false
168
+ }
169
+ defer { close(socketDescriptor) }
170
+ // Ignore connections left in TIME_WAIT by an earlier run, as the Ruby server does
171
+ var reuse: Int32 = 1
172
+ setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &reuse, socklen_t(MemoryLayout<Int32>.size))
173
+
174
+ let result: Int32
175
+ if family == AF_INET {
176
+ var address = sockaddr_in()
177
+ address.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
178
+ address.sin_family = sa_family_t(AF_INET)
179
+ address.sin_port = in_port_t(UInt16(port).bigEndian)
180
+ address.sin_addr.s_addr = inet_addr("127.0.0.1")
181
+ result = withUnsafePointer(to: &address) {
182
+ $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { bind(socketDescriptor, $0, socklen_t(MemoryLayout<sockaddr_in>.size)) }
183
+ }
184
+ } else {
185
+ var address = sockaddr_in6()
186
+ address.sin6_len = UInt8(MemoryLayout<sockaddr_in6>.size)
187
+ address.sin6_family = sa_family_t(AF_INET6)
188
+ address.sin6_port = in_port_t(UInt16(port).bigEndian)
189
+ address.sin6_addr = in6addr_loopback
190
+ result = withUnsafePointer(to: &address) {
191
+ $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { bind(socketDescriptor, $0, socklen_t(MemoryLayout<sockaddr_in6>.size)) }
192
+ }
193
+ }
194
+ return result != 0 && errno == EADDRINUSE
195
+ }
196
+
197
+ /// Only the process we launched counts: another process listening on the port is not our server
198
+ private func isPortListening(_ port: UInt32, by processIdentifier: Int32) -> Bool {
199
+ let result = runProcess(arguments: [lsofPath, "-t", "-nP", "-iTCP:\(port)", "-sTCP:LISTEN"])
200
+ // `env` exits 127 when lsof can't be found. Without this guard the
201
+ // probe would silently return false on every poll, then kill the
202
+ // freshly launched server after the 30s timeout with a misleading
203
+ // "did not start listening" message. Fail fast with the real cause.
204
+ if result.status == 127 {
205
+ log(message: "Could not run lsof (\(lsofPath)) to check socket server readiness. lsof ships at /usr/sbin/lsof on macOS; ensure it is installed and reachable.")
206
+ exit(1)
207
+ }
208
+ return result.output.split(separator: "\n").contains { $0 == Substring(String(processIdentifier)) }
209
+ }
210
+
211
+ /// Prefer the absolute macOS path so port checks don't depend on PATH;
212
+ /// fall back to a PATH lookup if lsof lives somewhere non-standard.
213
+ private var lsofPath: String {
214
+ let standardPath = "/usr/sbin/lsof"
215
+ return FileManager.default.isExecutableFile(atPath: standardPath) ? standardPath : "lsof"
216
+ }
217
+
218
+ private func outputOfProcess(arguments: [String]) -> String {
219
+ return runProcess(arguments: arguments).output
220
+ }
221
+
222
+ private func runProcess(arguments: [String]) -> (output: String, status: Int32) {
223
+ let process = Process()
224
+ let pipe = Pipe()
225
+ process.launchPath = "/usr/bin/env"
226
+ process.arguments = arguments
227
+ process.standardOutput = pipe
228
+ process.standardError = FileHandle.nullDevice
229
+ process.launch()
230
+ process.waitUntilExit()
231
+ let data = pipe.fileHandleForReading.readDataToEndOfFile()
232
+ return (String(data: data, encoding: .utf8) ?? "", process.terminationStatus)
233
+ }
234
+ #endif
65
235
  }
66
236
 
67
237
  public class Main {
@@ -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.240.1
20
+ // Generated with fastlane 2.241.1
@@ -56,10 +56,10 @@ public protocol MatchfileProtocol: AnyObject {
56
56
  /// Clone just the branch specified, instead of the whole repo. This requires that the branch already exists. Otherwise the command will fail
57
57
  var cloneBranchDirectly: Bool { get }
58
58
 
59
- /// Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64
59
+ /// Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64. Needs git 2.31 or later
60
60
  var gitBasicAuthorization: String? { get }
61
61
 
62
- /// Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64
62
+ /// Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64. Needs git 2.31 or later
63
63
  var gitBearerAuthorization: String? { get }
64
64
 
65
65
  /// Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof
@@ -173,6 +173,9 @@ public protocol MatchfileProtocol: AnyObject {
173
173
  /// Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
174
174
  var forceLegacyEncryption: Bool { get }
175
175
 
176
+ /// Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
177
+ var offlineProfile: Bool { get }
178
+
176
179
  /// Print out extra information and all commands
177
180
  var verbose: Bool { get }
178
181
  }
@@ -406,6 +409,10 @@ public extension MatchfileProtocol {
406
409
  return false
407
410
  }
408
411
 
412
+ var offlineProfile: Bool {
413
+ return false
414
+ }
415
+
409
416
  var verbose: Bool {
410
417
  return false
411
418
  }
@@ -413,4 +420,4 @@ public extension MatchfileProtocol {
413
420
 
414
421
  // Please don't remove the lines below
415
422
  // They are used to detect outdated files
416
- // FastlaneRunnerAPIVersion [0.9.152]
423
+ // FastlaneRunnerAPIVersion [0.9.154]
@@ -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.240.1
20
+ // Generated with fastlane 2.241.1
@@ -84,4 +84,4 @@ public extension PrecheckfileProtocol {
84
84
 
85
85
  // Please don't remove the lines below
86
86
  // They are used to detect outdated files
87
- // FastlaneRunnerAPIVersion [0.9.151]
87
+ // FastlaneRunnerAPIVersion [0.9.153]
@@ -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.240.1
20
+ // Generated with fastlane 2.241.1
@@ -77,6 +77,9 @@ public protocol ScanfileProtocol: AnyObject {
77
77
  /// Should the thread sanitizer be turned on?
78
78
  var threadSanitizer: Bool? { get }
79
79
 
80
+ /// Whether verbose and long-running diagnostics (like sysdiagnoses or log archives) are collected when testing. Valid values are: on-failure or never. If not specified, the value in the test plan is used. Equivalent to -collect-test-diagnostics (Xcode 14 and up)
81
+ var collectTestDiagnostics: String? { get }
82
+
80
83
  /// Should the HTML report be opened when tests are completed?
81
84
  var openReport: Bool { get }
82
85
 
@@ -353,6 +356,10 @@ public extension ScanfileProtocol {
353
356
  return nil
354
357
  }
355
358
 
359
+ var collectTestDiagnostics: String? {
360
+ return nil
361
+ }
362
+
356
363
  var openReport: Bool {
357
364
  return false
358
365
  }
@@ -588,4 +595,4 @@ public extension ScanfileProtocol {
588
595
 
589
596
  // Please don't remove the lines below
590
597
  // They are used to detect outdated files
591
- // FastlaneRunnerAPIVersion [0.9.163]
598
+ // FastlaneRunnerAPIVersion [0.9.165]
@@ -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.240.1
20
+ // Generated with fastlane 2.241.1
@@ -161,4 +161,4 @@ public extension ScreengrabfileProtocol {
161
161
 
162
162
  // Please don't remove the lines below
163
163
  // They are used to detect outdated files
164
- // FastlaneRunnerAPIVersion [0.9.153]
164
+ // FastlaneRunnerAPIVersion [0.9.155]