fastlane 2.240.0 → 2.241.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.
- checksums.yaml +4 -4
- data/README.md +57 -177
- data/bin/fastlane +4 -2
- data/credentials_manager/README.md +1 -1
- data/credentials_manager/lib/credentials_manager/account_manager.rb +6 -2
- data/deliver/lib/deliver/app_screenshot.rb +0 -4
- data/deliver/lib/deliver/commands_generator.rb +1 -1
- data/deliver/lib/deliver/detect_values.rb +3 -1
- data/deliver/lib/deliver/download_screenshots.rb +8 -1
- data/deliver/lib/deliver/sync_screenshots.rb +27 -28
- data/deliver/lib/deliver/upload_app_clip_default_experience_header_images.rb +3 -3
- data/deliver/lib/deliver/upload_metadata.rb +12 -16
- data/deliver/lib/deliver/upload_screenshots.rb +12 -14
- data/docs/README.md +25 -0
- data/fastlane/lib/assets/TeamTable.md.erb +28 -0
- data/fastlane/lib/fastlane/actions/appaloosa.rb +2 -1
- data/fastlane/lib/fastlane/actions/appium.rb +1 -1
- data/fastlane/lib/fastlane/actions/apteligent.rb +8 -1
- data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +1 -1
- data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +3 -0
- data/fastlane/lib/fastlane/actions/danger.rb +5 -5
- data/fastlane/lib/fastlane/actions/docs/build_app.md +1 -2
- data/fastlane/lib/fastlane/actions/docs/create_app_online.md +1 -2
- data/fastlane/lib/fastlane/actions/docs/get_certificates.md +0 -2
- data/fastlane/lib/fastlane/actions/docs/get_push_certificate.md +1 -3
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +13 -3
- data/fastlane/lib/fastlane/actions/ensure_no_debug_code.rb +2 -2
- data/fastlane/lib/fastlane/actions/get_managed_play_store_publishing_rights.rb +1 -0
- data/fastlane/lib/fastlane/actions/github_api.rb +1 -2
- data/fastlane/lib/fastlane/actions/hg_commit_version_bump.rb +1 -1
- data/fastlane/lib/fastlane/actions/increment_build_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/increment_version_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/install_xcode_plugin.rb +16 -6
- data/fastlane/lib/fastlane/actions/lcov.rb +9 -2
- data/fastlane/lib/fastlane/actions/nexus_upload.rb +16 -4
- data/fastlane/lib/fastlane/actions/notification.rb +3 -2
- data/fastlane/lib/fastlane/actions/oclint.rb +8 -8
- data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -4
- data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
- data/fastlane/lib/fastlane/actions/say.rb +2 -4
- data/fastlane/lib/fastlane/actions/set_pod_key.rb +3 -3
- data/fastlane/lib/fastlane/actions/sonar.rb +16 -16
- data/fastlane/lib/fastlane/actions/sourcedocs.rb +8 -8
- data/fastlane/lib/fastlane/actions/splunkmint.rb +8 -1
- data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +1 -1
- data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +5 -2
- data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +5 -2
- data/fastlane/lib/fastlane/actions/verify_build.rb +1 -4
- data/fastlane/lib/fastlane/actions/verify_pod_keys.rb +3 -1
- data/fastlane/lib/fastlane/actions/xcode_server_get_assets.rb +20 -19
- data/fastlane/lib/fastlane/actions/xcodebuild.rb +5 -6
- data/fastlane/lib/fastlane/actions/zip.rb +2 -1
- data/fastlane/lib/fastlane/auto_complete.rb +1 -1
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +14 -0
- data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +23 -0
- data/fastlane/lib/fastlane/environment_printer.rb +12 -25
- data/fastlane/lib/fastlane/fast_file.rb +2 -1
- data/fastlane/lib/fastlane/fastlane_require.rb +5 -1
- data/fastlane/lib/fastlane/helper/sh_helper.rb +16 -6
- data/fastlane/lib/fastlane/new_action.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +36 -4
- data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
- data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +1 -1
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +3 -7
- data/fastlane/lib/fastlane/swift_lane_manager.rb +22 -4
- data/fastlane/lib/fastlane/version.rb +3 -2
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +1 -1
- data/fastlane/swift/Fastlane.swift +55 -9
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +1 -1
- data/fastlane/swift/MainProcess.swift +190 -20
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +10 -3
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +8 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
- data/fastlane/swift/formatting/Rakefile +1 -0
- data/fastlane/swift/main.swift +4 -1
- data/fastlane_core/README.md +1 -1
- data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +1 -17
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +23 -8
- data/fastlane_core/lib/fastlane_core/device_manager.rb +2 -2
- data/fastlane_core/lib/fastlane_core/helper.rb +34 -5
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +0 -14
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +31 -28
- data/fastlane_core/lib/fastlane_core/languages.rb +0 -1
- data/fastlane_core/lib/fastlane_core/print_table.rb +5 -2
- data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +10 -19
- data/fastlane_core/lib/fastlane_core/secrets.rb +77 -0
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +3 -3
- data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +1 -1
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +2 -1
- data/fastlane_core/lib/fastlane_core.rb +1 -0
- data/frameit/lib/frameit/device.rb +1 -1
- data/frameit/lib/frameit/frame_downloader.rb +2 -0
- data/frameit/lib/frameit/runner.rb +3 -2
- data/frameit/lib/frameit/screenshot.rb +0 -1
- data/gym/lib/gym/generators/build_command_generator.rb +4 -4
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +3 -3
- data/gym/lib/gym/runner.rb +1 -1
- data/internal/README.md +1 -1
- data/match/lib/match/encryption/openssl.rb +6 -2
- data/match/lib/match/generator.rb +1 -0
- data/match/lib/match/options.rb +13 -5
- data/match/lib/match/runner.rb +30 -3
- data/match/lib/match/storage/git_storage.rb +43 -7
- data/match/lib/match/storage/gitlab/secure_file.rb +2 -1
- data/match/lib/match/storage/interface.rb +8 -5
- data/pem/lib/pem/module.rb +0 -4
- data/precheck/lib/precheck/rule_processor.rb +1 -0
- data/produce/lib/produce/developer_center.rb +49 -2
- data/produce/lib/produce/itunes_connect.rb +1 -1
- data/produce/lib/produce/module.rb +21 -0
- data/produce/lib/produce/options.rb +17 -0
- data/produce/lib/produce/service.rb +3 -5
- data/produce/lib/produce.rb +0 -1
- data/scan/lib/scan/options.rb +7 -0
- data/scan/lib/scan/runner.rb +1 -1
- data/scan/lib/scan/test_command_generator.rb +12 -9
- data/scan/lib/scan/test_result_parser.rb +1 -0
- data/scan/lib/scan/xcpretty_reporter_options_generator.rb +2 -2
- data/screengrab/lib/screengrab/page.html.erb +12 -7
- data/screengrab/lib/screengrab/reports_generator.rb +1 -1
- data/sigh/lib/assets/resign.sh +17 -0
- data/sigh/lib/sigh/local_manage.rb +1 -1
- data/sigh/lib/sigh/options.rb +5 -0
- data/sigh/lib/sigh/resign.rb +3 -3
- data/sigh/lib/sigh/runner.rb +6 -1
- data/snapshot/lib/snapshot/page.html.erb +17 -12
- data/snapshot/lib/snapshot/reports_generator.rb +1 -1
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +1 -1
- data/snapshot/lib/snapshot.rb +0 -2
- data/spaceship/README.md +2 -3
- data/spaceship/lib/spaceship/base.rb +3 -1
- data/spaceship/lib/spaceship/client.rb +65 -47
- data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +13 -2
- data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +6 -0
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +7 -5
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +25 -0
- data/spaceship/lib/spaceship/du/upload_file.rb +1 -1
- data/spaceship/lib/spaceship/errors.rb +7 -1
- data/spaceship/lib/spaceship/globals.rb +2 -2
- data/spaceship/lib/spaceship/portal/merchant.rb +127 -2
- data/spaceship/lib/spaceship/portal/portal_client.rb +58 -0
- data/spaceship/lib/spaceship/portal/ui/select_team.rb +0 -2
- data/spaceship/lib/spaceship/portal/website_push.rb +8 -2
- data/spaceship/lib/spaceship/test_flight/client.rb +0 -22
- data/spaceship/lib/spaceship/test_flight.rb +0 -1
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +11 -0
- data/supply/lib/supply/options.rb +1 -0
- data/supply/lib/supply.rb +0 -1
- metadata +75 -43
- data/produce/lib/produce/available_default_languages.rb +0 -62
- data/snapshot/lib/snapshot/screenshot_flatten.rb +0 -20
- data/snapshot/lib/snapshot/screenshot_rotate.rb +0 -36
- data/spaceship/lib/spaceship/test_flight/app_test_info.rb +0 -40
- data/supply/lib/supply/apk_listing.rb +0 -14
- /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)) {
|
|
@@ -3435,6 +3437,8 @@ public func createAppOnManagedPlayStore(jsonKey: OptionalConfigValue<String?> =
|
|
|
3435
3437
|
|
|
3436
3438
|
- parameters:
|
|
3437
3439
|
- username: Your Apple ID Username
|
|
3440
|
+
- 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)
|
|
3441
|
+
- apiKey: Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
|
3438
3442
|
- appIdentifier: App Identifier (Bundle ID, e.g. com.krausefx.app)
|
|
3439
3443
|
- bundleIdentifierSuffix: App Identifier Suffix (Ignored if App Identifier does not end with .*)
|
|
3440
3444
|
- appName: App Name
|
|
@@ -3459,6 +3463,8 @@ public func createAppOnManagedPlayStore(jsonKey: OptionalConfigValue<String?> =
|
|
|
3459
3463
|
For more information about _produce_, visit its documentation page: [https://docs.fastlane.tools/actions/produce/](https://docs.fastlane.tools/actions/produce/).
|
|
3460
3464
|
*/
|
|
3461
3465
|
public func createAppOnline(username: String,
|
|
3466
|
+
apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
3467
|
+
apiKey: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
|
|
3462
3468
|
appIdentifier: String,
|
|
3463
3469
|
bundleIdentifierSuffix: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
3464
3470
|
appName: String,
|
|
@@ -3479,6 +3485,8 @@ public func createAppOnline(username: String,
|
|
|
3479
3485
|
itcTeamName: OptionalConfigValue<String?> = .fastlaneDefault(nil))
|
|
3480
3486
|
{
|
|
3481
3487
|
let usernameArg = RubyCommand.Argument(name: "username", value: username, type: nil)
|
|
3488
|
+
let apiKeyPathArg = apiKeyPath.asRubyArgument(name: "api_key_path", type: nil)
|
|
3489
|
+
let apiKeyArg = apiKey.asRubyArgument(name: "api_key", type: nil)
|
|
3482
3490
|
let appIdentifierArg = RubyCommand.Argument(name: "app_identifier", value: appIdentifier, type: nil)
|
|
3483
3491
|
let bundleIdentifierSuffixArg = bundleIdentifierSuffix.asRubyArgument(name: "bundle_identifier_suffix", type: nil)
|
|
3484
3492
|
let appNameArg = RubyCommand.Argument(name: "app_name", value: appName, type: nil)
|
|
@@ -3498,6 +3506,8 @@ public func createAppOnline(username: String,
|
|
|
3498
3506
|
let itcTeamIdArg = RubyCommand.Argument(name: "itc_team_id", value: itcTeamId, type: nil)
|
|
3499
3507
|
let itcTeamNameArg = itcTeamName.asRubyArgument(name: "itc_team_name", type: nil)
|
|
3500
3508
|
let array: [RubyCommand.Argument?] = [usernameArg,
|
|
3509
|
+
apiKeyPathArg,
|
|
3510
|
+
apiKeyArg,
|
|
3501
3511
|
appIdentifierArg,
|
|
3502
3512
|
bundleIdentifierSuffixArg,
|
|
3503
3513
|
appNameArg,
|
|
@@ -5214,6 +5224,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
|
|
|
5214
5224
|
- force: Renew provisioning profiles regardless of its state - to automatically add all devices for ad hoc profiles
|
|
5215
5225
|
- includeMacInProfiles: Include Apple Silicon Mac devices in provisioning profiles for iOS/iPadOS apps
|
|
5216
5226
|
- appIdentifier: The bundle identifier of your app
|
|
5227
|
+
- offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
|
|
5217
5228
|
- 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
5229
|
- apiKey: Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
|
5219
5230
|
- username: Your Apple ID Username
|
|
@@ -5248,6 +5259,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
|
|
|
5248
5259
|
force: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
5249
5260
|
includeMacInProfiles: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
5250
5261
|
appIdentifier: String,
|
|
5262
|
+
offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
5251
5263
|
apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
5252
5264
|
apiKey: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
|
|
5253
5265
|
username: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
@@ -5278,6 +5290,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
|
|
|
5278
5290
|
let forceArg = force.asRubyArgument(name: "force", type: nil)
|
|
5279
5291
|
let includeMacInProfilesArg = includeMacInProfiles.asRubyArgument(name: "include_mac_in_profiles", type: nil)
|
|
5280
5292
|
let appIdentifierArg = RubyCommand.Argument(name: "app_identifier", value: appIdentifier, type: nil)
|
|
5293
|
+
let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
|
|
5281
5294
|
let apiKeyPathArg = apiKeyPath.asRubyArgument(name: "api_key_path", type: nil)
|
|
5282
5295
|
let apiKeyArg = apiKey.asRubyArgument(name: "api_key", type: nil)
|
|
5283
5296
|
let usernameArg = username.asRubyArgument(name: "username", type: nil)
|
|
@@ -5307,6 +5320,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
|
|
|
5307
5320
|
forceArg,
|
|
5308
5321
|
includeMacInProfilesArg,
|
|
5309
5322
|
appIdentifierArg,
|
|
5323
|
+
offlineProfileArg,
|
|
5310
5324
|
apiKeyPathArg,
|
|
5311
5325
|
apiKeyArg,
|
|
5312
5326
|
usernameArg,
|
|
@@ -6923,8 +6937,8 @@ public func makeChangelogFromJenkins(fallbackChangelog: String = "",
|
|
|
6923
6937
|
- gitUserEmail: git user email to commit
|
|
6924
6938
|
- shallowClone: Make a shallow clone of the repository (truncate the history to 1 revision)
|
|
6925
6939
|
- 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
|
|
6940
|
+
- 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
|
|
6941
|
+
- 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
6942
|
- 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
6943
|
- googleCloudBucketName: Name of the Google Cloud Storage bucket to use
|
|
6930
6944
|
- googleCloudKeysFile: Path to the gc_keys.json file
|
|
@@ -6962,6 +6976,7 @@ public func makeChangelogFromJenkins(fallbackChangelog: String = "",
|
|
|
6962
6976
|
- outputPath: Path in which to export certificates, key and profile
|
|
6963
6977
|
- 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
6978
|
- forceLegacyEncryption: Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
|
|
6979
|
+
- offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
|
|
6965
6980
|
- verbose: Print out extra information and all commands
|
|
6966
6981
|
|
|
6967
6982
|
More information: https://docs.fastlane.tools/actions/match/
|
|
@@ -7023,6 +7038,7 @@ public func match(type: String = matchfile.type,
|
|
|
7023
7038
|
outputPath: OptionalConfigValue<String?> = .fastlaneDefault(matchfile.outputPath),
|
|
7024
7039
|
skipSetPartitionList: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.skipSetPartitionList),
|
|
7025
7040
|
forceLegacyEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.forceLegacyEncryption),
|
|
7041
|
+
offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.offlineProfile),
|
|
7026
7042
|
verbose: OptionalConfigValue<Bool> = .fastlaneDefault(matchfile.verbose))
|
|
7027
7043
|
{
|
|
7028
7044
|
let typeArg = RubyCommand.Argument(name: "type", value: type, type: nil)
|
|
@@ -7082,6 +7098,7 @@ public func match(type: String = matchfile.type,
|
|
|
7082
7098
|
let outputPathArg = outputPath.asRubyArgument(name: "output_path", type: nil)
|
|
7083
7099
|
let skipSetPartitionListArg = skipSetPartitionList.asRubyArgument(name: "skip_set_partition_list", type: nil)
|
|
7084
7100
|
let forceLegacyEncryptionArg = forceLegacyEncryption.asRubyArgument(name: "force_legacy_encryption", type: nil)
|
|
7101
|
+
let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
|
|
7085
7102
|
let verboseArg = verbose.asRubyArgument(name: "verbose", type: nil)
|
|
7086
7103
|
let array: [RubyCommand.Argument?] = [typeArg,
|
|
7087
7104
|
additionalCertTypesArg,
|
|
@@ -7140,6 +7157,7 @@ public func match(type: String = matchfile.type,
|
|
|
7140
7157
|
outputPathArg,
|
|
7141
7158
|
skipSetPartitionListArg,
|
|
7142
7159
|
forceLegacyEncryptionArg,
|
|
7160
|
+
offlineProfileArg,
|
|
7143
7161
|
verboseArg]
|
|
7144
7162
|
let args: [RubyCommand.Argument] = array
|
|
7145
7163
|
.filter { $0?.value != nil }
|
|
@@ -7170,8 +7188,8 @@ public func match(type: String = matchfile.type,
|
|
|
7170
7188
|
- gitUserEmail: git user email to commit
|
|
7171
7189
|
- shallowClone: Make a shallow clone of the repository (truncate the history to 1 revision)
|
|
7172
7190
|
- 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
|
|
7191
|
+
- 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
|
|
7192
|
+
- 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
7193
|
- 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
7194
|
- googleCloudBucketName: Name of the Google Cloud Storage bucket to use
|
|
7177
7195
|
- googleCloudKeysFile: Path to the gc_keys.json file
|
|
@@ -7209,6 +7227,7 @@ public func match(type: String = matchfile.type,
|
|
|
7209
7227
|
- outputPath: Path in which to export certificates, key and profile
|
|
7210
7228
|
- 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
7229
|
- forceLegacyEncryption: Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
|
|
7230
|
+
- offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
|
|
7212
7231
|
- verbose: Print out extra information and all commands
|
|
7213
7232
|
|
|
7214
7233
|
Use the match_nuke action to revoke your certificates and provisioning profiles.
|
|
@@ -7274,6 +7293,7 @@ public func matchNuke(type: String = "development",
|
|
|
7274
7293
|
outputPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
7275
7294
|
skipSetPartitionList: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
7276
7295
|
forceLegacyEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
7296
|
+
offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
7277
7297
|
verbose: OptionalConfigValue<Bool> = .fastlaneDefault(false))
|
|
7278
7298
|
{
|
|
7279
7299
|
let typeArg = RubyCommand.Argument(name: "type", value: type, type: nil)
|
|
@@ -7333,6 +7353,7 @@ public func matchNuke(type: String = "development",
|
|
|
7333
7353
|
let outputPathArg = outputPath.asRubyArgument(name: "output_path", type: nil)
|
|
7334
7354
|
let skipSetPartitionListArg = skipSetPartitionList.asRubyArgument(name: "skip_set_partition_list", type: nil)
|
|
7335
7355
|
let forceLegacyEncryptionArg = forceLegacyEncryption.asRubyArgument(name: "force_legacy_encryption", type: nil)
|
|
7356
|
+
let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
|
|
7336
7357
|
let verboseArg = verbose.asRubyArgument(name: "verbose", type: nil)
|
|
7337
7358
|
let array: [RubyCommand.Argument?] = [typeArg,
|
|
7338
7359
|
additionalCertTypesArg,
|
|
@@ -7391,6 +7412,7 @@ public func matchNuke(type: String = "development",
|
|
|
7391
7412
|
outputPathArg,
|
|
7392
7413
|
skipSetPartitionListArg,
|
|
7393
7414
|
forceLegacyEncryptionArg,
|
|
7415
|
+
offlineProfileArg,
|
|
7394
7416
|
verboseArg]
|
|
7395
7417
|
let args: [RubyCommand.Argument] = array
|
|
7396
7418
|
.filter { $0?.value != nil }
|
|
@@ -7581,8 +7603,8 @@ public func notarize(package: String,
|
|
|
7581
7603
|
- message: The message to display in the notification
|
|
7582
7604
|
- sound: The name of a sound to play when the notification appears (names are listed in Sound Preferences)
|
|
7583
7605
|
- 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
|
|
7585
|
-
- contentImage: The
|
|
7606
|
+
- appIcon: **DEPRECATED!** The URL of an image to display instead of the application icon
|
|
7607
|
+
- contentImage: The local path of an image to display attached to the notification (Mavericks+)
|
|
7586
7608
|
- open: URL of the resource to be opened when the notification is clicked
|
|
7587
7609
|
- execute: Shell command to run when the notification is clicked
|
|
7588
7610
|
*/
|
|
@@ -8415,6 +8437,8 @@ public func println(message: OptionalConfigValue<String?> = .fastlaneDefault(nil
|
|
|
8415
8437
|
|
|
8416
8438
|
- parameters:
|
|
8417
8439
|
- username: Your Apple ID Username
|
|
8440
|
+
- 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)
|
|
8441
|
+
- apiKey: Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
|
8418
8442
|
- appIdentifier: App Identifier (Bundle ID, e.g. com.krausefx.app)
|
|
8419
8443
|
- bundleIdentifierSuffix: App Identifier Suffix (Ignored if App Identifier does not end with .*)
|
|
8420
8444
|
- appName: App Name
|
|
@@ -8439,6 +8463,8 @@ public func println(message: OptionalConfigValue<String?> = .fastlaneDefault(nil
|
|
|
8439
8463
|
For more information about _produce_, visit its documentation page: [https://docs.fastlane.tools/actions/produce/](https://docs.fastlane.tools/actions/produce/).
|
|
8440
8464
|
*/
|
|
8441
8465
|
public func produce(username: String,
|
|
8466
|
+
apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
8467
|
+
apiKey: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
|
|
8442
8468
|
appIdentifier: String,
|
|
8443
8469
|
bundleIdentifierSuffix: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
8444
8470
|
appName: String,
|
|
@@ -8459,6 +8485,8 @@ public func produce(username: String,
|
|
|
8459
8485
|
itcTeamName: OptionalConfigValue<String?> = .fastlaneDefault(nil))
|
|
8460
8486
|
{
|
|
8461
8487
|
let usernameArg = RubyCommand.Argument(name: "username", value: username, type: nil)
|
|
8488
|
+
let apiKeyPathArg = apiKeyPath.asRubyArgument(name: "api_key_path", type: nil)
|
|
8489
|
+
let apiKeyArg = apiKey.asRubyArgument(name: "api_key", type: nil)
|
|
8462
8490
|
let appIdentifierArg = RubyCommand.Argument(name: "app_identifier", value: appIdentifier, type: nil)
|
|
8463
8491
|
let bundleIdentifierSuffixArg = bundleIdentifierSuffix.asRubyArgument(name: "bundle_identifier_suffix", type: nil)
|
|
8464
8492
|
let appNameArg = RubyCommand.Argument(name: "app_name", value: appName, type: nil)
|
|
@@ -8478,6 +8506,8 @@ public func produce(username: String,
|
|
|
8478
8506
|
let itcTeamIdArg = RubyCommand.Argument(name: "itc_team_id", value: itcTeamId, type: nil)
|
|
8479
8507
|
let itcTeamNameArg = itcTeamName.asRubyArgument(name: "itc_team_name", type: nil)
|
|
8480
8508
|
let array: [RubyCommand.Argument?] = [usernameArg,
|
|
8509
|
+
apiKeyPathArg,
|
|
8510
|
+
apiKeyArg,
|
|
8481
8511
|
appIdentifierArg,
|
|
8482
8512
|
bundleIdentifierSuffixArg,
|
|
8483
8513
|
appNameArg,
|
|
@@ -9002,6 +9032,7 @@ public func rubyVersion() {
|
|
|
9002
9032
|
- codeCoverage: Should code coverage be generated? (Xcode 7 and up)
|
|
9003
9033
|
- addressSanitizer: Should the address sanitizer be turned on?
|
|
9004
9034
|
- threadSanitizer: Should the thread sanitizer be turned on?
|
|
9035
|
+
- 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
9036
|
- openReport: Should the HTML report be opened when tests are completed?
|
|
9006
9037
|
- outputDirectory: The directory in which all reports will be stored
|
|
9007
9038
|
- outputStyle: Define how the output should look like. Valid values are: standard, basic, rspec, or raw (disables xcpretty during xcodebuild)
|
|
@@ -9090,6 +9121,7 @@ public func rubyVersion() {
|
|
|
9090
9121
|
codeCoverage: OptionalConfigValue<Bool?> = .fastlaneDefault(nil),
|
|
9091
9122
|
addressSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(nil),
|
|
9092
9123
|
threadSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(nil),
|
|
9124
|
+
collectTestDiagnostics: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
9093
9125
|
openReport: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
9094
9126
|
outputDirectory: String = "./test_output",
|
|
9095
9127
|
outputStyle: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
@@ -9174,6 +9206,7 @@ public func rubyVersion() {
|
|
|
9174
9206
|
let codeCoverageArg = codeCoverage.asRubyArgument(name: "code_coverage", type: nil)
|
|
9175
9207
|
let addressSanitizerArg = addressSanitizer.asRubyArgument(name: "address_sanitizer", type: nil)
|
|
9176
9208
|
let threadSanitizerArg = threadSanitizer.asRubyArgument(name: "thread_sanitizer", type: nil)
|
|
9209
|
+
let collectTestDiagnosticsArg = collectTestDiagnostics.asRubyArgument(name: "collect_test_diagnostics", type: nil)
|
|
9177
9210
|
let openReportArg = openReport.asRubyArgument(name: "open_report", type: nil)
|
|
9178
9211
|
let outputDirectoryArg = RubyCommand.Argument(name: "output_directory", value: outputDirectory, type: nil)
|
|
9179
9212
|
let outputStyleArg = outputStyle.asRubyArgument(name: "output_style", type: nil)
|
|
@@ -9257,6 +9290,7 @@ public func rubyVersion() {
|
|
|
9257
9290
|
codeCoverageArg,
|
|
9258
9291
|
addressSanitizerArg,
|
|
9259
9292
|
threadSanitizerArg,
|
|
9293
|
+
collectTestDiagnosticsArg,
|
|
9260
9294
|
openReportArg,
|
|
9261
9295
|
outputDirectoryArg,
|
|
9262
9296
|
outputStyleArg,
|
|
@@ -9453,6 +9487,7 @@ public func say(text: [String],
|
|
|
9453
9487
|
- codeCoverage: Should code coverage be generated? (Xcode 7 and up)
|
|
9454
9488
|
- addressSanitizer: Should the address sanitizer be turned on?
|
|
9455
9489
|
- threadSanitizer: Should the thread sanitizer be turned on?
|
|
9490
|
+
- 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
9491
|
- openReport: Should the HTML report be opened when tests are completed?
|
|
9457
9492
|
- outputDirectory: The directory in which all reports will be stored
|
|
9458
9493
|
- outputStyle: Define how the output should look like. Valid values are: standard, basic, rspec, or raw (disables xcpretty during xcodebuild)
|
|
@@ -9541,6 +9576,7 @@ public func say(text: [String],
|
|
|
9541
9576
|
codeCoverage: OptionalConfigValue<Bool?> = .fastlaneDefault(scanfile.codeCoverage),
|
|
9542
9577
|
addressSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(scanfile.addressSanitizer),
|
|
9543
9578
|
threadSanitizer: OptionalConfigValue<Bool?> = .fastlaneDefault(scanfile.threadSanitizer),
|
|
9579
|
+
collectTestDiagnostics: OptionalConfigValue<String?> = .fastlaneDefault(scanfile.collectTestDiagnostics),
|
|
9544
9580
|
openReport: OptionalConfigValue<Bool> = .fastlaneDefault(scanfile.openReport),
|
|
9545
9581
|
outputDirectory: String = scanfile.outputDirectory,
|
|
9546
9582
|
outputStyle: OptionalConfigValue<String?> = .fastlaneDefault(scanfile.outputStyle),
|
|
@@ -9625,6 +9661,7 @@ public func say(text: [String],
|
|
|
9625
9661
|
let codeCoverageArg = codeCoverage.asRubyArgument(name: "code_coverage", type: nil)
|
|
9626
9662
|
let addressSanitizerArg = addressSanitizer.asRubyArgument(name: "address_sanitizer", type: nil)
|
|
9627
9663
|
let threadSanitizerArg = threadSanitizer.asRubyArgument(name: "thread_sanitizer", type: nil)
|
|
9664
|
+
let collectTestDiagnosticsArg = collectTestDiagnostics.asRubyArgument(name: "collect_test_diagnostics", type: nil)
|
|
9628
9665
|
let openReportArg = openReport.asRubyArgument(name: "open_report", type: nil)
|
|
9629
9666
|
let outputDirectoryArg = RubyCommand.Argument(name: "output_directory", value: outputDirectory, type: nil)
|
|
9630
9667
|
let outputStyleArg = outputStyle.asRubyArgument(name: "output_style", type: nil)
|
|
@@ -9708,6 +9745,7 @@ public func say(text: [String],
|
|
|
9708
9745
|
codeCoverageArg,
|
|
9709
9746
|
addressSanitizerArg,
|
|
9710
9747
|
threadSanitizerArg,
|
|
9748
|
+
collectTestDiagnosticsArg,
|
|
9711
9749
|
openReportArg,
|
|
9712
9750
|
outputDirectoryArg,
|
|
9713
9751
|
outputStyleArg,
|
|
@@ -10311,6 +10349,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
|
|
|
10311
10349
|
- force: Renew provisioning profiles regardless of its state - to automatically add all devices for ad hoc profiles
|
|
10312
10350
|
- includeMacInProfiles: Include Apple Silicon Mac devices in provisioning profiles for iOS/iPadOS apps
|
|
10313
10351
|
- appIdentifier: The bundle identifier of your app
|
|
10352
|
+
- offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
|
|
10314
10353
|
- 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
10354
|
- apiKey: Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
|
10316
10355
|
- username: Your Apple ID Username
|
|
@@ -10345,6 +10384,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
|
|
|
10345
10384
|
force: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
10346
10385
|
includeMacInProfiles: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
10347
10386
|
appIdentifier: String,
|
|
10387
|
+
offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
10348
10388
|
apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
10349
10389
|
apiKey: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
|
|
10350
10390
|
username: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
@@ -10375,6 +10415,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
|
|
|
10375
10415
|
let forceArg = force.asRubyArgument(name: "force", type: nil)
|
|
10376
10416
|
let includeMacInProfilesArg = includeMacInProfiles.asRubyArgument(name: "include_mac_in_profiles", type: nil)
|
|
10377
10417
|
let appIdentifierArg = RubyCommand.Argument(name: "app_identifier", value: appIdentifier, type: nil)
|
|
10418
|
+
let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
|
|
10378
10419
|
let apiKeyPathArg = apiKeyPath.asRubyArgument(name: "api_key_path", type: nil)
|
|
10379
10420
|
let apiKeyArg = apiKey.asRubyArgument(name: "api_key", type: nil)
|
|
10380
10421
|
let usernameArg = username.asRubyArgument(name: "username", type: nil)
|
|
@@ -10404,6 +10445,7 @@ public func setupTravis(force: OptionalConfigValue<Bool> = .fastlaneDefault(fals
|
|
|
10404
10445
|
forceArg,
|
|
10405
10446
|
includeMacInProfilesArg,
|
|
10406
10447
|
appIdentifierArg,
|
|
10448
|
+
offlineProfileArg,
|
|
10407
10449
|
apiKeyPathArg,
|
|
10408
10450
|
apiKeyArg,
|
|
10409
10451
|
usernameArg,
|
|
@@ -11536,8 +11578,8 @@ public func swiftlint(mode: String = "lint",
|
|
|
11536
11578
|
- gitUserEmail: git user email to commit
|
|
11537
11579
|
- shallowClone: Make a shallow clone of the repository (truncate the history to 1 revision)
|
|
11538
11580
|
- 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
|
|
11581
|
+
- 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
|
|
11582
|
+
- 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
11583
|
- 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
11584
|
- googleCloudBucketName: Name of the Google Cloud Storage bucket to use
|
|
11543
11585
|
- googleCloudKeysFile: Path to the gc_keys.json file
|
|
@@ -11575,6 +11617,7 @@ public func swiftlint(mode: String = "lint",
|
|
|
11575
11617
|
- outputPath: Path in which to export certificates, key and profile
|
|
11576
11618
|
- 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
11619
|
- forceLegacyEncryption: Force encryption to use legacy cbc algorithm for backwards compatibility with older match versions
|
|
11620
|
+
- offlineProfile: Enable profile with 'Offline Support' (7 day validity). Requires Apple ID login, not supported with App Store Connect API key authentication
|
|
11578
11621
|
- verbose: Print out extra information and all commands
|
|
11579
11622
|
|
|
11580
11623
|
More information: https://docs.fastlane.tools/actions/match/
|
|
@@ -11636,6 +11679,7 @@ public func syncCodeSigning(type: String = "development",
|
|
|
11636
11679
|
outputPath: OptionalConfigValue<String?> = .fastlaneDefault(nil),
|
|
11637
11680
|
skipSetPartitionList: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
11638
11681
|
forceLegacyEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
11682
|
+
offlineProfile: OptionalConfigValue<Bool> = .fastlaneDefault(false),
|
|
11639
11683
|
verbose: OptionalConfigValue<Bool> = .fastlaneDefault(false))
|
|
11640
11684
|
{
|
|
11641
11685
|
let typeArg = RubyCommand.Argument(name: "type", value: type, type: nil)
|
|
@@ -11695,6 +11739,7 @@ public func syncCodeSigning(type: String = "development",
|
|
|
11695
11739
|
let outputPathArg = outputPath.asRubyArgument(name: "output_path", type: nil)
|
|
11696
11740
|
let skipSetPartitionListArg = skipSetPartitionList.asRubyArgument(name: "skip_set_partition_list", type: nil)
|
|
11697
11741
|
let forceLegacyEncryptionArg = forceLegacyEncryption.asRubyArgument(name: "force_legacy_encryption", type: nil)
|
|
11742
|
+
let offlineProfileArg = offlineProfile.asRubyArgument(name: "offline_profile", type: nil)
|
|
11698
11743
|
let verboseArg = verbose.asRubyArgument(name: "verbose", type: nil)
|
|
11699
11744
|
let array: [RubyCommand.Argument?] = [typeArg,
|
|
11700
11745
|
additionalCertTypesArg,
|
|
@@ -11753,6 +11798,7 @@ public func syncCodeSigning(type: String = "development",
|
|
|
11753
11798
|
outputPathArg,
|
|
11754
11799
|
skipSetPartitionListArg,
|
|
11755
11800
|
forceLegacyEncryptionArg,
|
|
11801
|
+
offlineProfileArg,
|
|
11756
11802
|
verboseArg]
|
|
11757
11803
|
let args: [RubyCommand.Argument] = array
|
|
11758
11804
|
.filter { $0?.value != nil }
|
|
@@ -14215,4 +14261,4 @@ public let snapshotfile: Snapshotfile = .init()
|
|
|
14215
14261
|
|
|
14216
14262
|
// Please don't remove the lines below
|
|
14217
14263
|
// They are used to detect outdated files
|
|
14218
|
-
// FastlaneRunnerAPIVersion [0.9.
|
|
14264
|
+
// FastlaneRunnerAPIVersion [0.9.209]
|
|
@@ -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
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
rubySocketCommand =
|
|
53
|
-
|
|
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
|
-
|
|
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 {
|