fastlane 2.227.0 → 2.232.2
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 +102 -96
- data/bin/fastlane +2 -2
- data/deliver/lib/assets/summary.html.erb +3 -3
- data/deliver/lib/deliver/app_screenshot.rb +215 -347
- data/deliver/lib/deliver/app_screenshot_iterator.rb +4 -1
- data/deliver/lib/deliver/app_screenshot_validator.rb +5 -21
- data/deliver/lib/deliver/loader.rb +2 -9
- data/deliver/lib/deliver/runner.rb +1 -1
- data/deliver/lib/deliver/upload_metadata.rb +5 -0
- data/deliver/lib/deliver/upload_screenshots.rb +4 -2
- data/fastlane/lib/assets/completions/completion.bash +1 -1
- data/fastlane/lib/assets/completions/completion.sh +2 -2
- data/fastlane/lib/fastlane/actions/app_store_build_number.rb +19 -14
- data/fastlane/lib/fastlane/actions/appium.rb +1 -1
- data/fastlane/lib/fastlane/actions/docs/create_app_online.md +6 -3
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +11 -7
- data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +56 -17
- data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +13 -1
- data/fastlane/lib/fastlane/actions/get_version_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/import_certificate.rb +9 -1
- data/fastlane/lib/fastlane/actions/increment_build_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/install_xcode_plugin.rb +3 -2
- data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/modify_services.rb +1 -0
- data/fastlane/lib/fastlane/actions/notarize.rb +1 -1
- data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -1
- data/fastlane/lib/fastlane/actions/xcov.rb +1 -7
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +19 -1
- data/fastlane/lib/fastlane/console.rb +2 -2
- data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +4 -4
- data/fastlane/lib/fastlane/erb_template_helper.rb +1 -7
- data/fastlane/lib/fastlane/helper/s3_client_helper.rb +4 -0
- data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
- data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +20 -20
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -1
- data/fastlane/lib/fastlane/version.rb +2 -1
- data/fastlane/swift/Actions.swift +1 -1
- data/fastlane/swift/Appfile.swift +13 -5
- data/fastlane/swift/ArgumentProcessor.swift +1 -1
- data/fastlane/swift/Atomic.swift +1 -1
- data/fastlane/swift/ControlCommand.swift +5 -4
- data/fastlane/swift/Deliverfile.swift +2 -2
- data/fastlane/swift/DeliverfileProtocol.swift +265 -68
- data/fastlane/swift/Fastlane.swift +150 -157
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +3 -1
- data/fastlane/swift/Gymfile.swift +2 -2
- data/fastlane/swift/GymfileProtocol.swift +227 -54
- data/fastlane/swift/LaneFileProtocol.swift +4 -2
- data/fastlane/swift/MainProcess.swift +1 -1
- data/fastlane/swift/Matchfile.swift +2 -2
- data/fastlane/swift/MatchfileProtocol.swift +226 -59
- data/fastlane/swift/OptionalConfigValue.swift +1 -1
- data/fastlane/swift/Plugins.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +2 -2
- data/fastlane/swift/PrecheckfileProtocol.swift +45 -13
- data/fastlane/swift/RubyCommand.swift +6 -7
- data/fastlane/swift/RubyCommandable.swift +1 -1
- data/fastlane/swift/Runner.swift +3 -3
- data/fastlane/swift/RunnerArgument.swift +1 -1
- data/fastlane/swift/Scanfile.swift +2 -2
- data/fastlane/swift/ScanfileProtocol.swift +334 -84
- data/fastlane/swift/Screengrabfile.swift +2 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +89 -24
- data/fastlane/swift/Snapshotfile.swift +2 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +216 -53
- data/fastlane/swift/SocketClient.swift +7 -7
- data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
- data/fastlane/swift/SocketResponse.swift +1 -1
- data/fastlane/swift/formatting/Rakefile +1 -2
- data/fastlane/swift/main.swift +1 -1
- data/fastlane_core/lib/assets/XMLTemplate.xml.erb +5 -1
- data/fastlane_core/lib/fastlane_core/cert_checker.rb +10 -0
- data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -1
- data/fastlane_core/lib/fastlane_core/fastlane_pty.rb +5 -1
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +4 -14
- data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +19 -2
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +143 -106
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +3 -1
- data/fastlane_core/lib/fastlane_core/project.rb +8 -0
- data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +7 -1
- data/frameit/lib/frameit/device.rb +2 -2
- data/frameit/lib/frameit/device_types.rb +108 -70
- data/frameit/lib/frameit/template_finder.rb +1 -1
- data/gym/lib/assets/wrap_xcodebuild/xcbuild-safe.sh +1 -0
- data/gym/lib/gym/module.rb +9 -4
- data/gym/lib/gym/options.rb +20 -2
- data/gym/lib/gym/runner.rb +38 -3
- data/match/lib/match/options.rb +1 -0
- data/match/lib/match/storage/s3_storage.rb +4 -7
- data/pilot/lib/pilot/build_manager.rb +7 -1
- data/produce/lib/produce/commands_generator.rb +2 -0
- data/produce/lib/produce/developer_center.rb +1 -0
- data/produce/lib/produce/service.rb +6 -1
- data/scan/lib/scan/error_handler.rb +5 -0
- data/scan/lib/scan/options.rb +13 -3
- data/scan/lib/scan/test_command_generator.rb +10 -2
- data/sigh/lib/assets/resign.sh +6 -3
- data/sigh/lib/sigh/local_manage.rb +6 -4
- data/sigh/lib/sigh/options.rb +1 -0
- data/sigh/lib/sigh/runner.rb +23 -3
- data/snapshot/lib/snapshot/detect_values.rb +1 -1
- data/snapshot/lib/snapshot/options.rb +13 -1
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +4 -2
- data/spaceship/lib/spaceship/client.rb +32 -2
- data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +65 -9
- data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +4 -4
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +7 -1
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +16 -16
- data/spaceship/lib/spaceship/connect_api/models/build_upload.rb +42 -0
- data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +2 -0
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +32 -2
- data/spaceship/lib/spaceship/connect_api/models/device.rb +1 -2
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +2 -3
- data/spaceship/lib/spaceship/connect_api/models/webhook.rb +62 -0
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +0 -6
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +9 -0
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +38 -0
- data/spaceship/lib/spaceship/connect_api.rb +2 -0
- data/spaceship/lib/spaceship/errors.rb +8 -6
- data/spaceship/lib/spaceship/portal/key.rb +22 -3
- data/spaceship/lib/spaceship/portal/portal_client.rb +29 -2
- data/spaceship/lib/spaceship/spaceauth_runner.rb +5 -15
- data/supply/lib/supply/client.rb +18 -1
- data/trainer/lib/trainer/legacy_xcresult.rb +1 -1
- data/trainer/lib/trainer/test_parser.rb +1 -1
- data/trainer/lib/trainer/xcresult/helper.rb +11 -1
- metadata +153 -37
- data/fastlane/lib/fastlane/actions/hipchat.rb +0 -200
- data/fastlane/lib/fastlane/core_ext/bundler_monkey_patch.rb +0 -14
- data/fastlane/lib/fastlane/plugins/template/.circleci/config.yml +0 -43
- data/fastlane/lib/fastlane/plugins/template/.travis.yml +0 -4
|
@@ -51,6 +51,45 @@ module FastlaneCore
|
|
|
51
51
|
not_implemented(__method__)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# Builds a string array of credentials parameters based on the provided authentication details.
|
|
55
|
+
#
|
|
56
|
+
# @param username [String, nil] The username for authentication (optional).
|
|
57
|
+
# @param password [String, nil] The password for authentication (optional).
|
|
58
|
+
# @param jwt [String, nil] A JSON Web Token for token-based authentication (optional).
|
|
59
|
+
# @param api_key [Hash, nil] An API key for authentication (optional).
|
|
60
|
+
#
|
|
61
|
+
# @return [String] A string containing the appropriate credentials for authentication.
|
|
62
|
+
def build_credential_params(username = nil, password = nil, jwt = nil, api_key = nil)
|
|
63
|
+
not_implemented(__method__)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Runs preparations before executing any command from the executor.
|
|
67
|
+
#
|
|
68
|
+
# @param original_api_key [Hash] api key containing the issuer id and private key
|
|
69
|
+
# @return [Hash] copy of `api_key` which includes an extra `key_dir` with the location of the .p8 file on disk
|
|
70
|
+
def prepare(original_api_key:)
|
|
71
|
+
return if original_api_key.nil?
|
|
72
|
+
# Create .p8 file from api_key and provide api key info which contains .p8 file path
|
|
73
|
+
api_key = original_api_key.dup
|
|
74
|
+
if self.kind_of?(ShellScriptTransporterExecutor)
|
|
75
|
+
# as of Transporter v3.3.0, the app is unable to detect the private keys under the 'private_keys' folder in current directory
|
|
76
|
+
# so we must rely on the other search paths in the Home dir:
|
|
77
|
+
# https://help.apple.com/itc/transporteruserguide/en.lproj/static.html#itc803b7be80
|
|
78
|
+
private_keys_dir = File.join(Dir.home, ".appstoreconnect/private_keys")
|
|
79
|
+
unless Dir.exist?(private_keys_dir)
|
|
80
|
+
FileUtils.mkdir_p(private_keys_dir)
|
|
81
|
+
end
|
|
82
|
+
api_key[:key_dir] = private_keys_dir
|
|
83
|
+
else
|
|
84
|
+
api_key[:key_dir] = Dir.mktmpdir("deliver-")
|
|
85
|
+
end
|
|
86
|
+
# Specified p8 needs to be generated to call altool or iTMSTransporter
|
|
87
|
+
File.open(File.join(api_key[:key_dir], "AuthKey_#{api_key[:key_id]}.p8"), "wb") do |p8|
|
|
88
|
+
p8.write(api_key[:key])
|
|
89
|
+
end
|
|
90
|
+
api_key
|
|
91
|
+
end
|
|
92
|
+
|
|
54
93
|
def execute(command, hide_output)
|
|
55
94
|
if Helper.test?
|
|
56
95
|
yield(nil) if block_given?
|
|
@@ -180,8 +219,8 @@ module FastlaneCore
|
|
|
180
219
|
end
|
|
181
220
|
|
|
182
221
|
def file_upload_option(source)
|
|
183
|
-
|
|
184
|
-
is_asset_file_type = !File.directory?(source) &&
|
|
222
|
+
file_ext = File.extname(source).downcase
|
|
223
|
+
is_asset_file_type = !File.directory?(source) && allowed_package_extensions.map { |ext| ".#{ext}" }.include?(file_ext)
|
|
185
224
|
|
|
186
225
|
if is_asset_file_type
|
|
187
226
|
return "-assetFile #{source.shellescape}"
|
|
@@ -207,11 +246,16 @@ module FastlaneCore
|
|
|
207
246
|
end
|
|
208
247
|
return deliver_additional_params
|
|
209
248
|
end
|
|
249
|
+
|
|
250
|
+
def allowed_package_extensions
|
|
251
|
+
["ipa", "pkg", "dmg", "zip"]
|
|
252
|
+
end
|
|
210
253
|
end
|
|
211
254
|
|
|
212
255
|
# Generates commands and executes the altool.
|
|
213
256
|
class AltoolTransporterExecutor < TransporterExecutor
|
|
214
|
-
|
|
257
|
+
# Xcode 26 uses ERROR, while previous versions used *** Error
|
|
258
|
+
ERROR_REGEX = /(?:\*\*\*\s*)?ERROR:\s+(.+)/i
|
|
215
259
|
|
|
216
260
|
private_constant :ERROR_REGEX
|
|
217
261
|
|
|
@@ -249,21 +293,7 @@ module FastlaneCore
|
|
|
249
293
|
@errors << "-1 indicates altool exited abnormally; try retrying (see https://github.com/fastlane/fastlane/issues/21535)" if exit_status == -1
|
|
250
294
|
|
|
251
295
|
unless @errors.empty? || @all_lines.empty?
|
|
252
|
-
|
|
253
|
-
# If error text is not detected, it will be 20 lines
|
|
254
|
-
# This is key for non-verbose mode
|
|
255
|
-
|
|
256
|
-
# The format of altool's result with error is like below
|
|
257
|
-
# > *** Error: Error uploading '...'.
|
|
258
|
-
# > *** Error: ...
|
|
259
|
-
# > {
|
|
260
|
-
# > NSLocalizedDescription = "...",
|
|
261
|
-
# > ...
|
|
262
|
-
# > }
|
|
263
|
-
# So this line tries to find the line which has "*** Error:" prefix from bottom of log
|
|
264
|
-
error_line_index = @all_lines.rindex { |line| ERROR_REGEX.match?(line) }
|
|
265
|
-
|
|
266
|
-
@all_lines[(error_line_index || -20)..-1].each do |line|
|
|
296
|
+
@all_lines.each do |line|
|
|
267
297
|
UI.important("[altool] #{line}")
|
|
268
298
|
end
|
|
269
299
|
UI.message("Application Loader output above ^")
|
|
@@ -271,7 +301,15 @@ module FastlaneCore
|
|
|
271
301
|
end
|
|
272
302
|
|
|
273
303
|
yield(@all_lines) if block_given?
|
|
274
|
-
|
|
304
|
+
@errors.empty?
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def build_credential_params(username = nil, password = nil, jwt = nil, api_key = nil)
|
|
308
|
+
if !username.nil? && !password.nil? && api_key.nil?
|
|
309
|
+
"-u #{username.shellescape} -p #{password.shellescape}"
|
|
310
|
+
elsif !api_key.nil?
|
|
311
|
+
"--apiKey #{api_key[:key_id]} --apiIssuer #{api_key[:issuer_id]}"
|
|
312
|
+
end
|
|
275
313
|
end
|
|
276
314
|
|
|
277
315
|
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
|
@@ -280,10 +318,7 @@ module FastlaneCore
|
|
|
280
318
|
("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
|
|
281
319
|
"xcrun altool",
|
|
282
320
|
"--upload-app",
|
|
283
|
-
(
|
|
284
|
-
("-p #{password.shellescape}" unless use_api_key),
|
|
285
|
-
("--apiKey #{api_key[:key_id]}" if use_api_key),
|
|
286
|
-
("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
|
|
321
|
+
build_credential_params(username, password, jwt, api_key),
|
|
287
322
|
("--asc-provider #{provider_short_name}" unless use_api_key || provider_short_name.to_s.empty?),
|
|
288
323
|
platform_option(platform),
|
|
289
324
|
file_upload_option(source),
|
|
@@ -298,10 +333,7 @@ module FastlaneCore
|
|
|
298
333
|
("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
|
|
299
334
|
"xcrun altool",
|
|
300
335
|
"--list-providers",
|
|
301
|
-
(
|
|
302
|
-
("-p #{password.shellescape}" unless use_api_key),
|
|
303
|
-
("--apiKey #{api_key[:key_id]}" if use_api_key),
|
|
304
|
-
("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
|
|
336
|
+
build_credential_params(username, password, jwt, api_key),
|
|
305
337
|
"--output-format json"
|
|
306
338
|
].compact.join(' ')
|
|
307
339
|
end
|
|
@@ -318,10 +350,7 @@ module FastlaneCore
|
|
|
318
350
|
("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
|
|
319
351
|
"xcrun altool",
|
|
320
352
|
"--validate-app",
|
|
321
|
-
(
|
|
322
|
-
("-p #{password.shellescape}" unless use_api_key),
|
|
323
|
-
("--apiKey #{api_key[:key_id]}" if use_api_key),
|
|
324
|
-
("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
|
|
353
|
+
build_credential_params(username, password, nil, api_key),
|
|
325
354
|
("--asc-provider #{provider_short_name}" unless use_api_key || provider_short_name.to_s.empty?),
|
|
326
355
|
platform_option(platform),
|
|
327
356
|
file_upload_option(source)
|
|
@@ -385,14 +414,21 @@ module FastlaneCore
|
|
|
385
414
|
|
|
386
415
|
# Generates commands and executes the iTMSTransporter through the shell script it provides by the same name
|
|
387
416
|
class ShellScriptTransporterExecutor < TransporterExecutor
|
|
417
|
+
def build_credential_params(username = nil, password = nil, jwt = nil, api_key = nil)
|
|
418
|
+
if !(username.nil? || password.nil?) && (jwt.nil? && api_key.nil?)
|
|
419
|
+
"-u #{username.shellescape} -p #{shell_escaped_password(password)}"
|
|
420
|
+
elsif !jwt.nil? && api_key.nil?
|
|
421
|
+
"-jwt #{jwt}"
|
|
422
|
+
elsif !api_key.nil?
|
|
423
|
+
"-apiIssuer #{api_key[:issuer_id]} -apiKey #{api_key[:key_id]}"
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
|
|
388
427
|
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
|
389
|
-
use_jwt = !jwt.to_s.empty?
|
|
390
428
|
[
|
|
391
429
|
'"' + Helper.transporter_path + '"',
|
|
392
430
|
"-m upload",
|
|
393
|
-
(
|
|
394
|
-
("-p #{shell_escaped_password(password)}" unless use_jwt),
|
|
395
|
-
("-jwt #{jwt}" if use_jwt),
|
|
431
|
+
build_credential_params(username, password, jwt, api_key),
|
|
396
432
|
file_upload_option(source),
|
|
397
433
|
additional_upload_parameters, # that's here, because the user might overwrite the -t option
|
|
398
434
|
"-k 100000",
|
|
@@ -402,13 +438,10 @@ module FastlaneCore
|
|
|
402
438
|
end
|
|
403
439
|
|
|
404
440
|
def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
|
|
405
|
-
use_jwt = !jwt.to_s.empty?
|
|
406
441
|
[
|
|
407
442
|
'"' + Helper.transporter_path + '"',
|
|
408
443
|
"-m lookupMetadata",
|
|
409
|
-
(
|
|
410
|
-
("-p #{shell_escaped_password(password)}" unless use_jwt),
|
|
411
|
-
("-jwt #{jwt}" if use_jwt),
|
|
444
|
+
build_credential_params(username, password, jwt),
|
|
412
445
|
"-apple_id #{apple_id}",
|
|
413
446
|
"-destination '#{destination}'",
|
|
414
447
|
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?)
|
|
@@ -416,25 +449,19 @@ module FastlaneCore
|
|
|
416
449
|
end
|
|
417
450
|
|
|
418
451
|
def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
|
|
419
|
-
use_jwt = !jwt.to_s.empty?
|
|
420
452
|
[
|
|
421
453
|
'"' + Helper.transporter_path + '"',
|
|
422
454
|
'-m provider',
|
|
423
|
-
(
|
|
424
|
-
("-p #{shell_escaped_password(password)}" unless use_jwt),
|
|
425
|
-
("-jwt #{jwt}" if use_jwt)
|
|
455
|
+
build_credential_params(username, password, jwt, api_key)
|
|
426
456
|
].compact.join(' ')
|
|
427
457
|
end
|
|
428
458
|
|
|
429
459
|
def build_verify_command(username, password, source = "/tmp", provider_short_name = "", **kwargs)
|
|
430
460
|
jwt = kwargs[:jwt]
|
|
431
|
-
use_jwt = !jwt.to_s.empty?
|
|
432
461
|
[
|
|
433
462
|
'"' + Helper.transporter_path + '"',
|
|
434
463
|
'-m verify',
|
|
435
|
-
(
|
|
436
|
-
("-p #{shell_escaped_password(password)}" unless use_jwt),
|
|
437
|
-
("-jwt #{jwt}" if use_jwt),
|
|
464
|
+
build_credential_params(username, password, jwt),
|
|
438
465
|
"-f #{source.shellescape}",
|
|
439
466
|
("-WONoPause true" if Helper.windows?), # Windows only: process instantly returns instead of waiting for key press
|
|
440
467
|
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?)
|
|
@@ -456,6 +483,31 @@ module FastlaneCore
|
|
|
456
483
|
UI.error("Could not download/upload from App Store Connect! It's probably related to your password or your internet connection.")
|
|
457
484
|
end
|
|
458
485
|
|
|
486
|
+
def file_upload_option(source)
|
|
487
|
+
# uploading packages on non-macOS platforms requires AppStoreInfo.plist starting with Transporter >= 4.1
|
|
488
|
+
if !Helper.is_mac? && File.directory?(source)
|
|
489
|
+
asset_file = Dir.glob(File.join(source, "*.{#{allowed_package_extensions.join(',')}}")).first
|
|
490
|
+
unless asset_file
|
|
491
|
+
UI.user_error!("No package file (#{allowed_package_extensions.join(',')}) found in #{source}")
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
appstore_info_path = File.join(source, "AppStoreInfo.plist")
|
|
495
|
+
unless File.file?(appstore_info_path)
|
|
496
|
+
UI.error("AppStoreInfo.plist is required for uploading #{File.extname(asset_file)} files on non-macOS platforms.")
|
|
497
|
+
UI.error("Expected AppStoreInfo.plist in the same directory as the #{File.extname(asset_file)} file.")
|
|
498
|
+
UI.error("Generate it by running either 'fastlane gym [...] --generate_appstore_info'")
|
|
499
|
+
UI.error("Or add '<key>generateAppStoreInformation</key><true/>' in an options.plist then run 'fastlane gym [...] --export_options options.plist'.")
|
|
500
|
+
UI.user_error!("Missing required AppStoreInfo.plist file for iTMSTransporter upload")
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
UI.verbose("Using AppStoreInfo.plist for iTMSTransporter upload: #{appstore_info_path}")
|
|
504
|
+
return "-assetFile #{asset_file.shellescape} -assetDescription #{appstore_info_path.shellescape}"
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
# use standard behavior for other file types or macOS platform
|
|
508
|
+
super(source)
|
|
509
|
+
end
|
|
510
|
+
|
|
459
511
|
private
|
|
460
512
|
|
|
461
513
|
def shell_escaped_password(password)
|
|
@@ -482,16 +534,26 @@ module FastlaneCore
|
|
|
482
534
|
# Generates commands and executes the iTMSTransporter by invoking its Java app directly, to avoid the crazy parameter
|
|
483
535
|
# escaping problems in its accompanying shell script.
|
|
484
536
|
class JavaTransporterExecutor < TransporterExecutor
|
|
537
|
+
def build_credential_params(username = nil, password = nil, jwt = nil, api_key = nil, is_password_from_env = false)
|
|
538
|
+
if !username.nil? && jwt.to_s.empty?
|
|
539
|
+
if is_password_from_env
|
|
540
|
+
"-u #{username.shellescape} -p @env:ITMS_TRANSPORTER_PASSWORD"
|
|
541
|
+
elsif !password.nil?
|
|
542
|
+
"-u #{username.shellescape} -p #{password.shellescape}"
|
|
543
|
+
end
|
|
544
|
+
elsif !jwt.to_s.empty?
|
|
545
|
+
"-jwt #{jwt}"
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
485
549
|
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
|
486
|
-
|
|
487
|
-
if
|
|
550
|
+
credential_params = build_credential_params(username, password, jwt, api_key, is_default_itms_on_xcode_11?)
|
|
551
|
+
if is_default_itms_on_xcode_11?
|
|
488
552
|
[
|
|
489
|
-
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}"
|
|
553
|
+
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" if jwt.to_s.empty?),
|
|
490
554
|
'xcrun iTMSTransporter',
|
|
491
555
|
'-m upload',
|
|
492
|
-
|
|
493
|
-
("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
|
|
494
|
-
("-jwt #{jwt}" if use_jwt),
|
|
556
|
+
credential_params,
|
|
495
557
|
file_upload_option(source),
|
|
496
558
|
additional_upload_parameters, # that's here, because the user might overwrite the -t option
|
|
497
559
|
'-k 100000',
|
|
@@ -510,9 +572,7 @@ module FastlaneCore
|
|
|
510
572
|
'-Dsun.net.http.retryPost=false',
|
|
511
573
|
java_code_option,
|
|
512
574
|
'-m upload',
|
|
513
|
-
|
|
514
|
-
("-p #{password.shellescape}" unless use_jwt),
|
|
515
|
-
("-jwt #{jwt}" if use_jwt),
|
|
575
|
+
credential_params,
|
|
516
576
|
file_upload_option(source),
|
|
517
577
|
additional_upload_parameters, # that's here, because the user might overwrite the -t option
|
|
518
578
|
'-k 100000',
|
|
@@ -524,15 +584,13 @@ module FastlaneCore
|
|
|
524
584
|
|
|
525
585
|
def build_verify_command(username, password, source = "/tmp", provider_short_name = "", **kwargs)
|
|
526
586
|
jwt = kwargs[:jwt]
|
|
527
|
-
|
|
528
|
-
if
|
|
587
|
+
credential_params = build_credential_params(username, password, jwt, nil, is_default_itms_on_xcode_11?)
|
|
588
|
+
if is_default_itms_on_xcode_11?
|
|
529
589
|
[
|
|
530
|
-
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}"
|
|
590
|
+
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" if jwt.to_s.empty?),
|
|
531
591
|
'xcrun iTMSTransporter',
|
|
532
592
|
'-m verify',
|
|
533
|
-
|
|
534
|
-
("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
|
|
535
|
-
("-jwt #{jwt}" if use_jwt),
|
|
593
|
+
credential_params,
|
|
536
594
|
"-f #{source.shellescape}",
|
|
537
595
|
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
|
|
538
596
|
'2>&1' # cause stderr to be written to stdout
|
|
@@ -549,9 +607,7 @@ module FastlaneCore
|
|
|
549
607
|
'-Dsun.net.http.retryPost=false',
|
|
550
608
|
java_code_option,
|
|
551
609
|
'-m verify',
|
|
552
|
-
|
|
553
|
-
("-p #{password.shellescape}" unless use_jwt),
|
|
554
|
-
("-jwt #{jwt}" if use_jwt),
|
|
610
|
+
credential_params,
|
|
555
611
|
"-f #{source.shellescape}",
|
|
556
612
|
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
|
|
557
613
|
'2>&1' # cause stderr to be written to stdout
|
|
@@ -560,15 +616,13 @@ module FastlaneCore
|
|
|
560
616
|
end
|
|
561
617
|
|
|
562
618
|
def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
|
|
563
|
-
|
|
564
|
-
if
|
|
619
|
+
credential_params = build_credential_params(username, password, jwt, nil, is_default_itms_on_xcode_11?)
|
|
620
|
+
if is_default_itms_on_xcode_11?
|
|
565
621
|
[
|
|
566
|
-
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}"
|
|
622
|
+
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" if jwt.to_s.empty?),
|
|
567
623
|
'xcrun iTMSTransporter',
|
|
568
624
|
'-m lookupMetadata',
|
|
569
|
-
|
|
570
|
-
("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
|
|
571
|
-
("-jwt #{jwt}" if use_jwt),
|
|
625
|
+
credential_params,
|
|
572
626
|
"-apple_id #{apple_id.shellescape}",
|
|
573
627
|
"-destination #{destination.shellescape}",
|
|
574
628
|
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
|
|
@@ -586,9 +640,7 @@ module FastlaneCore
|
|
|
586
640
|
'-Dsun.net.http.retryPost=false',
|
|
587
641
|
java_code_option,
|
|
588
642
|
'-m lookupMetadata',
|
|
589
|
-
|
|
590
|
-
("-p #{password.shellescape}" unless use_jwt),
|
|
591
|
-
("-jwt #{jwt}" if use_jwt),
|
|
643
|
+
credential_params,
|
|
592
644
|
"-apple_id #{apple_id.shellescape}",
|
|
593
645
|
"-destination #{destination.shellescape}",
|
|
594
646
|
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
|
|
@@ -598,15 +650,13 @@ module FastlaneCore
|
|
|
598
650
|
end
|
|
599
651
|
|
|
600
652
|
def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
|
|
601
|
-
|
|
602
|
-
if
|
|
653
|
+
credential_params = build_credential_params(username, password, jwt, api_key, is_default_itms_on_xcode_11?)
|
|
654
|
+
if is_default_itms_on_xcode_11?
|
|
603
655
|
[
|
|
604
|
-
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}"
|
|
656
|
+
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" if jwt.to_s.empty?),
|
|
605
657
|
'xcrun iTMSTransporter',
|
|
606
658
|
'-m provider',
|
|
607
|
-
|
|
608
|
-
("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
|
|
609
|
-
("-jwt #{jwt}" if use_jwt),
|
|
659
|
+
credential_params,
|
|
610
660
|
'2>&1' # cause stderr to be written to stdout
|
|
611
661
|
].compact.join(' ')
|
|
612
662
|
else
|
|
@@ -621,14 +671,16 @@ module FastlaneCore
|
|
|
621
671
|
'-Dsun.net.http.retryPost=false',
|
|
622
672
|
java_code_option,
|
|
623
673
|
'-m provider',
|
|
624
|
-
|
|
625
|
-
("-p #{password.shellescape}" unless use_jwt),
|
|
626
|
-
("-jwt #{jwt}" if use_jwt),
|
|
674
|
+
credential_params,
|
|
627
675
|
'2>&1' # cause stderr to be written to stdout
|
|
628
676
|
].compact.join(' ')
|
|
629
677
|
end
|
|
630
678
|
end
|
|
631
679
|
|
|
680
|
+
def is_default_itms_on_xcode_11?
|
|
681
|
+
!Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
|
|
682
|
+
end
|
|
683
|
+
|
|
632
684
|
def java_code_option
|
|
633
685
|
if Helper.mac? && Helper.xcode_at_least?(9)
|
|
634
686
|
return "-jar #{Helper.transporter_java_jar_path.shellescape}"
|
|
@@ -686,7 +738,7 @@ module FastlaneCore
|
|
|
686
738
|
use_shell_script ||= Helper.windows?
|
|
687
739
|
use_shell_script ||= Feature.enabled?('FASTLANE_ITUNES_TRANSPORTER_USE_SHELL_SCRIPT')
|
|
688
740
|
|
|
689
|
-
if jwt.to_s.empty?
|
|
741
|
+
if jwt.to_s.empty? && api_key.nil?
|
|
690
742
|
@user = user
|
|
691
743
|
@password = password || load_password_for_transporter
|
|
692
744
|
end
|
|
@@ -754,16 +806,16 @@ module FastlaneCore
|
|
|
754
806
|
raise "app_id and dir are required or package_path or asset_path is required" if (app_id.nil? || dir.nil?) && package_path.nil? && asset_path.nil?
|
|
755
807
|
|
|
756
808
|
# Transport can upload .ipa, .dmg, and .pkg files directly with -assetFile
|
|
757
|
-
# However, -assetFile requires -assetDescription if Linux or Windows
|
|
758
|
-
# This will
|
|
759
|
-
# otherwise it will use the .itmsp package
|
|
809
|
+
# However, -assetFile requires -assetDescription arguments if Linux or Windows.
|
|
810
|
+
# This will return the asset directly if asset_path exists,
|
|
811
|
+
# otherwise it will use the .itmsp package for the -f argument
|
|
760
812
|
|
|
761
813
|
force_itmsp = FastlaneCore::Env.truthy?("ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD")
|
|
762
814
|
can_use_asset_path = Helper.is_mac? && asset_path
|
|
763
815
|
|
|
764
816
|
actual_dir = if can_use_asset_path && !force_itmsp
|
|
765
817
|
# The asset gets deleted upon completion so copying to a temp directory
|
|
766
|
-
# (with randomized filename
|
|
818
|
+
# (with randomized filename. for multibyte-mixed filename it fails to upload)
|
|
767
819
|
new_file_name = "#{SecureRandom.uuid}#{File.extname(asset_path)}"
|
|
768
820
|
tmp_asset_path = File.join(Dir.tmpdir, new_file_name)
|
|
769
821
|
FileUtils.cp(asset_path, tmp_asset_path)
|
|
@@ -783,9 +835,7 @@ module FastlaneCore
|
|
|
783
835
|
# Handle AppStore Connect API
|
|
784
836
|
use_api_key = !@api_key.nil?
|
|
785
837
|
api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
|
|
786
|
-
|
|
787
|
-
api_key = nil
|
|
788
|
-
api_key = api_key_with_p8_file_path(@api_key) if use_api_key
|
|
838
|
+
api_key = @transporter_executor.prepare(original_api_key: @api_key)
|
|
789
839
|
|
|
790
840
|
command = @transporter_executor.build_upload_command(@user, @password, actual_dir, @provider_short_name, @jwt, platform, api_key)
|
|
791
841
|
UI.verbose(@transporter_executor.build_upload_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt_placeholder, platform, api_key_placeholder))
|
|
@@ -846,8 +896,7 @@ module FastlaneCore
|
|
|
846
896
|
|
|
847
897
|
# Masking credentials for verbose outputs
|
|
848
898
|
api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
|
|
849
|
-
|
|
850
|
-
api_key = api_key_with_p8_file_path(@api_key) if use_api_key
|
|
899
|
+
api_key = @transporter_executor.prepare(original_api_key: @api_key)
|
|
851
900
|
|
|
852
901
|
command = @transporter_executor.build_verify_command(@user, @password, actual_dir, @provider_short_name, jwt: @jwt, platform: platform, api_key: api_key)
|
|
853
902
|
UI.verbose(@transporter_executor.build_verify_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt: jwt_placeholder, platform: platform, api_key: api_key_placeholder))
|
|
@@ -882,8 +931,7 @@ module FastlaneCore
|
|
|
882
931
|
use_api_key = !@api_key.nil?
|
|
883
932
|
api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
|
|
884
933
|
|
|
885
|
-
api_key =
|
|
886
|
-
api_key = api_key_with_p8_file_path(@api_key) if use_api_key
|
|
934
|
+
api_key = @transporter_executor.prepare(original_api_key: @api_key)
|
|
887
935
|
|
|
888
936
|
command = @transporter_executor.build_provider_ids_command(@user, @password, @jwt, api_key)
|
|
889
937
|
UI.verbose(@transporter_executor.build_provider_ids_command(@user, password_placeholder, jwt_placeholder, api_key_placeholder))
|
|
@@ -908,17 +956,6 @@ module FastlaneCore
|
|
|
908
956
|
|
|
909
957
|
TWO_FACTOR_ENV_VARIABLE = "FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"
|
|
910
958
|
|
|
911
|
-
# Create .p8 file from api_key and provide api key info which contains .p8 file path
|
|
912
|
-
def api_key_with_p8_file_path(original_api_key)
|
|
913
|
-
api_key = original_api_key.dup
|
|
914
|
-
api_key[:key_dir] = Dir.mktmpdir("deliver-")
|
|
915
|
-
# Specified p8 needs to be generated to call altool
|
|
916
|
-
File.open(File.join(api_key[:key_dir], "AuthKey_#{api_key[:key_id]}.p8"), "wb") do |p8|
|
|
917
|
-
p8.write(api_key[:key])
|
|
918
|
-
end
|
|
919
|
-
api_key
|
|
920
|
-
end
|
|
921
|
-
|
|
922
959
|
# Returns whether altool should be used or ItunesTransporter should be used
|
|
923
960
|
def should_use_altool?(altool_compatible_command, use_shell_script)
|
|
924
961
|
# Xcode 14 no longer supports iTMSTransporter. Use altool instead
|
|
@@ -4,13 +4,15 @@ require 'security'
|
|
|
4
4
|
|
|
5
5
|
module FastlaneCore
|
|
6
6
|
class KeychainImporter
|
|
7
|
-
def self.import_file(path, keychain_path, keychain_password: nil, certificate_password: "", skip_set_partition_list: false, output: FastlaneCore::Globals.verbose?)
|
|
7
|
+
def self.import_file(path, keychain_path, keychain_password: nil, certificate_password: "", certificate_format: nil, skip_set_partition_list: false, output: FastlaneCore::Globals.verbose?)
|
|
8
8
|
UI.user_error!("Could not find file '#{path}'") unless File.exist?(path)
|
|
9
9
|
|
|
10
10
|
password_part = " -P #{certificate_password.shellescape}"
|
|
11
|
+
certificate_format_part = certificate_format.to_s.strip.empty? ? "" : " -f #{certificate_format.shellescape}"
|
|
11
12
|
|
|
12
13
|
command = "security import #{path.shellescape} -k '#{keychain_path.shellescape}'"
|
|
13
14
|
command << password_part
|
|
15
|
+
command << certificate_format_part
|
|
14
16
|
command << " -T /usr/bin/codesign" # to not be asked for permission when running a tool like `gym` (before Sierra)
|
|
15
17
|
command << " -T /usr/bin/security"
|
|
16
18
|
command << " -T /usr/bin/productbuild" # to not be asked for permission when using an installer cert for macOS
|
|
@@ -348,10 +348,18 @@ module FastlaneCore
|
|
|
348
348
|
proj << "-clonedSourcePackagesDirPath #{options[:cloned_source_packages_path].shellescape}"
|
|
349
349
|
end
|
|
350
350
|
|
|
351
|
+
if xcode_at_least_11 && options[:package_cache_path]
|
|
352
|
+
proj << "-packageCachePath #{options[:package_cache_path].shellescape}"
|
|
353
|
+
end
|
|
354
|
+
|
|
351
355
|
if xcode_at_least_11 && options[:disable_package_automatic_updates]
|
|
352
356
|
proj << "-disableAutomaticPackageResolution"
|
|
353
357
|
end
|
|
354
358
|
|
|
359
|
+
if xcode_at_least_11 && options[:skip_package_repository_fetches]
|
|
360
|
+
proj << "-skipPackageUpdates"
|
|
361
|
+
end
|
|
362
|
+
|
|
355
363
|
return proj
|
|
356
364
|
end
|
|
357
365
|
|
|
@@ -73,7 +73,13 @@ module FastlaneCore
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def profiles_path
|
|
76
|
-
path = File.expand_path("~")
|
|
76
|
+
path = File.expand_path("~")
|
|
77
|
+
# Xcode 16 has a new location for provisioning profiles.
|
|
78
|
+
if FastlaneCore::Helper.xcode_at_least?(16)
|
|
79
|
+
path = File.join(path, "Library", "Developer", "Xcode", "UserData", "Provisioning Profiles")
|
|
80
|
+
else
|
|
81
|
+
path = File.join(path, "Library", "MobileDevice", "Provisioning Profiles")
|
|
82
|
+
end
|
|
77
83
|
# If the directory doesn't exist, create it first
|
|
78
84
|
unless File.directory?(path)
|
|
79
85
|
FileUtils.mkdir_p(path)
|
|
@@ -71,9 +71,9 @@ module Frameit
|
|
|
71
71
|
return nil
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
# Previously ENV[FRAMEIT_FORCE_DEVICE_TYPE] was matched to Deliver::AppScreenshot
|
|
74
|
+
# Previously ENV[FRAMEIT_FORCE_DEVICE_TYPE] was matched to Deliver::AppScreenshot display type strings.
|
|
75
75
|
# options.rb defined a few Apple devices with unspecified IDs, this option was never read from Frameit.config.
|
|
76
|
-
# Therefore this function matches both
|
|
76
|
+
# Therefore this function matches both DisplayType constants and formatted names to maintain backward compatibility.
|
|
77
77
|
def self.find_device_by_id_or_name(id)
|
|
78
78
|
return nil if id.nil?
|
|
79
79
|
found_device = nil
|