fastlane 2.202.0 → 2.212.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +98 -98
- data/cert/lib/cert/runner.rb +15 -7
- data/deliver/lib/deliver/app_screenshot.rb +18 -0
- data/deliver/lib/deliver/options.rb +6 -2
- data/deliver/lib/deliver/runner.rb +76 -29
- data/deliver/lib/deliver/upload_price_tier.rb +3 -1
- data/deliver/lib/deliver/upload_screenshots.rb +1 -1
- data/fastlane/lib/assets/AppfileTemplate +1 -1
- data/fastlane/lib/assets/AppfileTemplate.swift +1 -1
- data/fastlane/lib/fastlane/actions/badge.rb +1 -1
- data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +1 -1
- data/fastlane/lib/fastlane/actions/danger.rb +14 -0
- data/fastlane/lib/fastlane/actions/docs/build_app.md +5 -5
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +19 -2
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/run_tests.md +1 -1
- data/fastlane/lib/fastlane/actions/get_version_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/git_commit.rb +4 -6
- data/fastlane/lib/fastlane/actions/import_certificate.rb +1 -1
- data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +1 -1
- data/fastlane/lib/fastlane/actions/pod_push.rb +19 -1
- data/fastlane/lib/fastlane/actions/read_podspec.rb +1 -1
- data/fastlane/lib/fastlane/actions/run_tests.rb +11 -9
- data/fastlane/lib/fastlane/actions/setup_ci.rb +13 -4
- data/fastlane/lib/fastlane/actions/trainer.rb +2 -2
- data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +14 -4
- data/fastlane/lib/fastlane/actions/update_info_plist.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +10 -1
- data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +1 -1
- data/fastlane/lib/fastlane/actions/verify_build.rb +1 -1
- data/fastlane/lib/fastlane/actions/xcode_install.rb +5 -1
- data/fastlane/lib/fastlane/actions/xcode_select.rb +1 -1
- data/fastlane/lib/fastlane/actions/xcodebuild.rb +8 -2
- data/fastlane/lib/fastlane/actions/xcodes.rb +152 -0
- data/fastlane/lib/fastlane/actions/xcversion.rb +10 -15
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +5 -0
- data/fastlane/lib/fastlane/commands_generator.rb +2 -1
- data/fastlane/lib/fastlane/fast_file.rb +18 -5
- data/fastlane/lib/fastlane/features.rb +3 -0
- data/fastlane/lib/fastlane/helper/xcodes_helper.rb +28 -0
- data/fastlane/lib/fastlane/helper/xcversion_helper.rb +0 -9
- data/fastlane/lib/fastlane/lane_manager.rb +1 -1
- data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +5 -1
- data/fastlane/lib/fastlane/setup/setup_ios.rb +1 -1
- data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +1 -1
- data/fastlane/lib/fastlane/swift_lane_manager.rb +11 -3
- data/fastlane/lib/fastlane/swift_runner_upgrader.rb +54 -1
- data/fastlane/lib/fastlane/tools.rb +16 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Actions.swift +1 -1
- data/fastlane/swift/Appfile.swift +2 -2
- data/fastlane/swift/ArgumentProcessor.swift +1 -1
- data/fastlane/swift/Atomic.swift +150 -0
- data/fastlane/swift/ControlCommand.swift +1 -1
- data/fastlane/swift/Deliverfile.swift +2 -2
- data/fastlane/swift/DeliverfileProtocol.swift +8 -4
- data/fastlane/swift/Fastlane.swift +363 -184
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +30 -20
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme +1 -1
- data/fastlane/swift/Gymfile.swift +2 -2
- data/fastlane/swift/GymfileProtocol.swift +7 -3
- data/fastlane/swift/LaneFileProtocol.swift +2 -2
- data/fastlane/swift/MainProcess.swift +3 -3
- data/fastlane/swift/Matchfile.swift +2 -2
- data/fastlane/swift/MatchfileProtocol.swift +21 -5
- 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 +3 -3
- data/fastlane/swift/RubyCommand.swift +1 -1
- data/fastlane/swift/RubyCommandable.swift +1 -1
- data/fastlane/swift/Runner.swift +10 -2
- data/fastlane/swift/RunnerArgument.swift +1 -1
- data/fastlane/swift/Scanfile.swift +2 -2
- data/fastlane/swift/ScanfileProtocol.swift +11 -3
- data/fastlane/swift/Screengrabfile.swift +2 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +3 -3
- data/fastlane/swift/Snapshotfile.swift +2 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +4 -4
- data/fastlane/swift/SocketClient.swift +9 -5
- data/fastlane/swift/SocketClientDelegateProtocol.swift +2 -2
- data/fastlane/swift/SocketResponse.swift +1 -1
- data/fastlane/swift/formatting/Brewfile.lock.json +42 -24
- data/fastlane/swift/main.swift +1 -1
- data/fastlane/swift/upgrade_manifest.json +1 -1
- data/fastlane_core/README.md +1 -0
- data/fastlane_core/lib/fastlane_core/cert_checker.rb +79 -17
- data/fastlane_core/lib/fastlane_core/device_manager.rb +5 -1
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +335 -20
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -0
- data/fastlane_core/lib/fastlane_core/project.rb +19 -2
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +4 -2
- data/frameit/lib/frameit/device.rb +1 -1
- data/frameit/lib/frameit/device_types.rb +9 -0
- data/frameit/lib/frameit/frame_downloader.rb +1 -1
- data/gym/lib/gym/generators/build_command_generator.rb +1 -0
- data/gym/lib/gym/options.rb +7 -0
- data/match/lib/match/change_password.rb +2 -0
- data/match/lib/match/commands_generator.rb +2 -1
- data/match/lib/match/encryption/openssl.rb +1 -1
- data/match/lib/match/encryption.rb +3 -0
- data/match/lib/match/generator.rb +1 -0
- data/match/lib/match/importer.rb +10 -1
- data/match/lib/match/migrate.rb +4 -3
- data/match/lib/match/module.rb +54 -2
- data/match/lib/match/nuke.rb +36 -47
- data/match/lib/match/options.rb +22 -1
- data/match/lib/match/runner.rb +25 -6
- data/match/lib/match/setup.rb +1 -1
- data/match/lib/match/spaceship_ensure.rb +4 -2
- data/match/lib/match/storage/gitlab/client.rb +102 -0
- data/match/lib/match/storage/gitlab/secure_file.rb +65 -0
- data/match/lib/match/storage/gitlab_secure_files.rb +182 -0
- data/match/lib/match/storage/google_cloud_storage.rb +7 -6
- data/match/lib/match/storage/s3_storage.rb +3 -3
- data/match/lib/match/storage.rb +4 -0
- data/match/lib/match/table_printer.rb +2 -1
- data/match/lib/match/utils.rb +15 -2
- data/pem/lib/pem/manager.rb +1 -1
- data/pilot/lib/pilot/build_manager.rb +33 -13
- data/pilot/lib/pilot/options.rb +6 -1
- data/scan/lib/scan/detect_values.rb +6 -0
- data/scan/lib/scan/options.rb +16 -1
- data/scan/lib/scan/runner.rb +33 -14
- data/scan/lib/scan/test_command_generator.rb +7 -1
- data/sigh/lib/sigh/download_all.rb +14 -2
- data/sigh/lib/sigh/module.rb +3 -1
- data/sigh/lib/sigh/options.rb +5 -0
- data/sigh/lib/sigh/runner.rb +12 -2
- data/snapshot/lib/assets/SnapshotHelper.swift +3 -3
- data/snapshot/lib/snapshot/options.rb +1 -1
- data/snapshot/lib/snapshot/reports_generator.rb +1 -0
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +9 -2
- data/spaceship/lib/spaceship/client.rb +36 -25
- data/spaceship/lib/spaceship/connect_api/api_client.rb +10 -5
- data/spaceship/lib/spaceship/connect_api/models/actor.rb +26 -0
- data/spaceship/lib/spaceship/connect_api/models/app.rb +7 -5
- data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +27 -10
- data/spaceship/lib/spaceship/connect_api/models/build_bundle.rb +9 -0
- data/spaceship/lib/spaceship/connect_api/models/build_bundle_file_sizes.rb +34 -0
- data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +2 -1
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +1 -0
- data/spaceship/lib/spaceship/connect_api/models/device.rb +47 -4
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +4 -0
- data/spaceship/lib/spaceship/connect_api/models/resolution_center_message.rb +29 -0
- data/spaceship/lib/spaceship/connect_api/models/resolution_center_thread.rb +67 -0
- data/spaceship/lib/spaceship/connect_api/models/review_rejection.rb +19 -0
- data/spaceship/lib/spaceship/connect_api/models/review_submission.rb +13 -0
- data/spaceship/lib/spaceship/connect_api/models/user.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +19 -0
- data/spaceship/lib/spaceship/connect_api/response.rb +10 -6
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +33 -2
- data/spaceship/lib/spaceship/connect_api/token.rb +5 -2
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +41 -8
- data/spaceship/lib/spaceship/connect_api.rb +6 -0
- data/spaceship/lib/spaceship/errors.rb +34 -0
- data/spaceship/lib/spaceship/hashcash.rb +52 -0
- data/spaceship/lib/spaceship/portal/certificate.rb +4 -3
- data/spaceship/lib/spaceship/tunes/app_ratings.rb +6 -6
- data/spaceship/lib/spaceship/tunes/iap_families.rb +1 -1
- data/spaceship/lib/spaceship/tunes/tunes.rb +0 -1
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +79 -21
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +11 -3
- data/spaceship/lib/spaceship.rb +1 -0
- data/supply/lib/supply/client.rb +2 -7
- data/trainer/lib/assets/junit.xml.erb +9 -1
- data/trainer/lib/trainer/junit_generator.rb +2 -2
- data/trainer/lib/trainer/options.rb +1 -1
- data/trainer/lib/trainer/test_parser.rb +25 -3
- metadata +36 -33
- data/deliver/lib/deliver/.runner.rb.swp +0 -0
- data/deliver/lib/deliver/.submit_for_review.rb.swp +0 -0
- data/fastlane/lib/.DS_Store +0 -0
- data/fastlane/lib/fastlane/.DS_Store +0 -0
- data/fastlane/lib/fastlane/actions/.DS_Store +0 -0
- data/spaceship/lib/spaceship/connect_api/models/.app.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/testflight/.testflight.rb.swp +0 -0
- data/spaceship/lib/spaceship/tunes/user_detail.rb +0 -15
- data/trainer/lib/.DS_Store +0 -0
@@ -28,10 +28,29 @@ module FastlaneCore
|
|
28
28
|
OUTPUT_REGEX = />\s+(.+)/
|
29
29
|
RETURN_VALUE_REGEX = />\sDBG-X:\sReturning\s+(\d+)/
|
30
30
|
|
31
|
+
# Matches a line in the iTMSTransporter provider table: "12 Initech Systems Inc LG89CQY559"
|
32
|
+
ITMS_PROVIDER_REGEX = /^\d+\s{2,}.+\s{2,}[^\s]+$/
|
33
|
+
|
31
34
|
SKIP_ERRORS = ["ERROR: An exception has occurred: Scheduling automatic restart in 1 minute"]
|
32
35
|
|
33
36
|
private_constant :ERROR_REGEX, :WARNING_REGEX, :OUTPUT_REGEX, :RETURN_VALUE_REGEX, :SKIP_ERRORS
|
34
37
|
|
38
|
+
def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
|
39
|
+
not_implemented(__method__)
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
|
43
|
+
not_implemented(__method__)
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
47
|
+
not_implemented(__method__)
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_verify_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
|
51
|
+
not_implemented(__method__)
|
52
|
+
end
|
53
|
+
|
35
54
|
def execute(command, hide_output)
|
36
55
|
if Helper.test?
|
37
56
|
yield(nil) if block_given?
|
@@ -100,8 +119,18 @@ module FastlaneCore
|
|
100
119
|
@errors.map { |error| "[Transporter Error Output]: #{error}" }.join("\n").gsub!(/"/, "")
|
101
120
|
end
|
102
121
|
|
122
|
+
def parse_provider_info(lines)
|
123
|
+
lines.map { |line| itms_provider_pair(line) }.compact.to_h
|
124
|
+
end
|
125
|
+
|
103
126
|
private
|
104
127
|
|
128
|
+
def itms_provider_pair(line)
|
129
|
+
line = line.strip
|
130
|
+
return nil unless line =~ ITMS_PROVIDER_REGEX
|
131
|
+
line.split(/\s{2,}/).drop(1)
|
132
|
+
end
|
133
|
+
|
105
134
|
def parse_line(line, hide_output)
|
106
135
|
# Taken from https://github.com/sshaw/itunes_store_transporter/blob/master/lib/itunes/store/transporter/output_parser.rb
|
107
136
|
|
@@ -180,9 +209,166 @@ module FastlaneCore
|
|
180
209
|
end
|
181
210
|
end
|
182
211
|
|
212
|
+
# Generates commands and executes the altool.
|
213
|
+
class AltoolTransporterExecutor < TransporterExecutor
|
214
|
+
ERROR_REGEX = /\*\*\* Error:\s+(.+)/
|
215
|
+
|
216
|
+
private_constant :ERROR_REGEX
|
217
|
+
|
218
|
+
def execute(command, hide_output)
|
219
|
+
if Helper.test?
|
220
|
+
yield(nil) if block_given?
|
221
|
+
return command
|
222
|
+
end
|
223
|
+
|
224
|
+
@errors = []
|
225
|
+
@all_lines = []
|
226
|
+
|
227
|
+
if hide_output
|
228
|
+
# Show a one time message instead
|
229
|
+
UI.success("Waiting for App Store Connect transporter to be finished.")
|
230
|
+
UI.success("Application Loader progress... this might take a few minutes...")
|
231
|
+
end
|
232
|
+
|
233
|
+
begin
|
234
|
+
exit_status = FastlaneCore::FastlanePty.spawn(command) do |command_stdout, command_stdin, pid|
|
235
|
+
command_stdout.each do |line|
|
236
|
+
@all_lines << line
|
237
|
+
parse_line(line, hide_output) # this is where the parsing happens
|
238
|
+
end
|
239
|
+
end
|
240
|
+
rescue => ex
|
241
|
+
# FastlanePty adds exit_status on to StandardError so every error will have a status code
|
242
|
+
exit_status = ex.exit_status
|
243
|
+
@errors << ex.to_s
|
244
|
+
end
|
245
|
+
|
246
|
+
@errors << "The call to the altool completed with a non-zero exit status: #{exit_status}. This indicates a failure." unless exit_status.zero?
|
247
|
+
|
248
|
+
unless @errors.empty? || @all_lines.empty?
|
249
|
+
# Print the last lines that appear after the last error from the logs
|
250
|
+
# If error text is not detected, it will be 20 lines
|
251
|
+
# This is key for non-verbose mode
|
252
|
+
|
253
|
+
# The format of altool's result with error is like below
|
254
|
+
# > *** Error: Error uploading '...'.
|
255
|
+
# > *** Error: ...
|
256
|
+
# > {
|
257
|
+
# > NSLocalizedDescription = "...",
|
258
|
+
# > ...
|
259
|
+
# > }
|
260
|
+
# So this line tries to find the line which has "*** Error:" prefix from bottom of log
|
261
|
+
error_line_index = @all_lines.rindex { |line| ERROR_REGEX.match?(line) }
|
262
|
+
|
263
|
+
@all_lines[(error_line_index || -20)..-1].each do |line|
|
264
|
+
UI.important("[altool] #{line}")
|
265
|
+
end
|
266
|
+
UI.message("Application Loader output above ^")
|
267
|
+
@errors.each { |error| UI.error(error) }
|
268
|
+
end
|
269
|
+
|
270
|
+
yield(@all_lines) if block_given?
|
271
|
+
exit_status.zero?
|
272
|
+
end
|
273
|
+
|
274
|
+
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
275
|
+
use_api_key = !api_key.nil?
|
276
|
+
[
|
277
|
+
("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
|
278
|
+
"xcrun altool",
|
279
|
+
"--upload-app",
|
280
|
+
("-u #{username.shellescape}" unless use_api_key),
|
281
|
+
("-p #{password.shellescape}" unless use_api_key),
|
282
|
+
("--apiKey #{api_key[:key_id]}" if use_api_key),
|
283
|
+
("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
|
284
|
+
("--asc-provider #{provider_short_name}" unless use_api_key || provider_short_name.to_s.empty?),
|
285
|
+
platform_option(platform),
|
286
|
+
file_upload_option(source),
|
287
|
+
additional_upload_parameters,
|
288
|
+
"-k 100000"
|
289
|
+
].compact.join(' ')
|
290
|
+
end
|
291
|
+
|
292
|
+
def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
|
293
|
+
use_api_key = !api_key.nil?
|
294
|
+
[
|
295
|
+
("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
|
296
|
+
"xcrun altool",
|
297
|
+
"--list-providers",
|
298
|
+
("-u #{username.shellescape}" unless use_api_key),
|
299
|
+
("-p #{password.shellescape}" unless use_api_key),
|
300
|
+
("--apiKey #{api_key[:key_id]}" if use_api_key),
|
301
|
+
("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
|
302
|
+
"--output-format json"
|
303
|
+
].compact.join(' ')
|
304
|
+
end
|
305
|
+
|
306
|
+
def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
|
307
|
+
raise "This feature has not been implemented yet with altool for Xcode 14"
|
308
|
+
end
|
309
|
+
|
310
|
+
def build_verify_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
|
311
|
+
raise "This feature has not been implemented yet with altool for Xcode 14"
|
312
|
+
end
|
313
|
+
|
314
|
+
def additional_upload_parameters
|
315
|
+
env_deliver_additional_params = ENV["DELIVER_ALTOOL_ADDITIONAL_UPLOAD_PARAMETERS"]
|
316
|
+
return nil if env_deliver_additional_params.to_s.strip.empty?
|
317
|
+
|
318
|
+
env_deliver_additional_params.to_s.strip
|
319
|
+
end
|
320
|
+
|
321
|
+
def handle_error(password)
|
322
|
+
UI.error("Could not download/upload from App Store Connect!")
|
323
|
+
end
|
324
|
+
|
325
|
+
def displayable_errors
|
326
|
+
@errors.map { |error| "[Application Loader Error Output]: #{error}" }.join("\n")
|
327
|
+
end
|
328
|
+
|
329
|
+
def parse_provider_info(lines)
|
330
|
+
# This tries parsing the provider id from altool output to detect provider list
|
331
|
+
provider_info = {}
|
332
|
+
json_body = lines[-2] # altool outputs result in second line from last
|
333
|
+
return provider_info if json_body.nil?
|
334
|
+
providers = JSON.parse(json_body)["providers"]
|
335
|
+
return provider_info if providers.nil?
|
336
|
+
providers.each do |provider|
|
337
|
+
provider_info[provider["ProviderName"]] = provider["ProviderShortname"]
|
338
|
+
end
|
339
|
+
provider_info
|
340
|
+
end
|
341
|
+
|
342
|
+
private
|
343
|
+
|
344
|
+
def file_upload_option(source)
|
345
|
+
"-f #{source.shellescape}"
|
346
|
+
end
|
347
|
+
|
348
|
+
def platform_option(platform)
|
349
|
+
"-t #{platform == 'osx' ? 'macos' : platform}"
|
350
|
+
end
|
351
|
+
|
352
|
+
def parse_line(line, hide_output)
|
353
|
+
output_done = false
|
354
|
+
|
355
|
+
if line =~ ERROR_REGEX
|
356
|
+
@errors << $1
|
357
|
+
output_done = true
|
358
|
+
end
|
359
|
+
|
360
|
+
unless hide_output
|
361
|
+
# General logging for debug purposes
|
362
|
+
unless output_done
|
363
|
+
UI.verbose("[altool]: #{line}")
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
183
369
|
# Generates commands and executes the iTMSTransporter through the shell script it provides by the same name
|
184
370
|
class ShellScriptTransporterExecutor < TransporterExecutor
|
185
|
-
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
|
371
|
+
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
186
372
|
use_jwt = !jwt.to_s.empty?
|
187
373
|
[
|
188
374
|
'"' + Helper.transporter_path + '"',
|
@@ -212,7 +398,7 @@ module FastlaneCore
|
|
212
398
|
].compact.join(' ')
|
213
399
|
end
|
214
400
|
|
215
|
-
def build_provider_ids_command(username, password, jwt = nil)
|
401
|
+
def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
|
216
402
|
use_jwt = !jwt.to_s.empty?
|
217
403
|
[
|
218
404
|
'"' + Helper.transporter_path + '"',
|
@@ -223,6 +409,20 @@ module FastlaneCore
|
|
223
409
|
].compact.join(' ')
|
224
410
|
end
|
225
411
|
|
412
|
+
def build_verify_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
|
413
|
+
use_jwt = !jwt.to_s.empty?
|
414
|
+
[
|
415
|
+
'"' + Helper.transporter_path + '"',
|
416
|
+
'-m verify',
|
417
|
+
("-u #{username.shellescape}" unless use_jwt),
|
418
|
+
("-p #{shell_escaped_password(password)}" unless use_jwt),
|
419
|
+
("-jwt #{jwt}" if use_jwt),
|
420
|
+
"-f #{source.shellescape}",
|
421
|
+
("-WONoPause true" if Helper.windows?), # Windows only: process instantly returns instead of waiting for key press
|
422
|
+
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?)
|
423
|
+
].compact.join(' ')
|
424
|
+
end
|
425
|
+
|
226
426
|
def handle_error(password)
|
227
427
|
# rubocop:disable Style/CaseEquality
|
228
428
|
# rubocop:disable Style/YodaCondition
|
@@ -264,7 +464,7 @@ module FastlaneCore
|
|
264
464
|
# Generates commands and executes the iTMSTransporter by invoking its Java app directly, to avoid the crazy parameter
|
265
465
|
# escaping problems in its accompanying shell script.
|
266
466
|
class JavaTransporterExecutor < TransporterExecutor
|
267
|
-
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
|
467
|
+
def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
|
268
468
|
use_jwt = !jwt.to_s.empty?
|
269
469
|
if !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
|
270
470
|
[
|
@@ -304,6 +504,42 @@ module FastlaneCore
|
|
304
504
|
end
|
305
505
|
end
|
306
506
|
|
507
|
+
def build_verify_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
|
508
|
+
use_jwt = !jwt.to_s.empty?
|
509
|
+
if !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
|
510
|
+
[
|
511
|
+
("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" unless use_jwt),
|
512
|
+
'xcrun iTMSTransporter',
|
513
|
+
'-m verify',
|
514
|
+
("-u #{username.shellescape}" unless use_jwt),
|
515
|
+
("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
|
516
|
+
("-jwt #{jwt}" if use_jwt),
|
517
|
+
"-f #{source.shellescape}",
|
518
|
+
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
|
519
|
+
'2>&1' # cause stderr to be written to stdout
|
520
|
+
].compact.join(' ') # compact gets rid of the possibly nil ENV value
|
521
|
+
else
|
522
|
+
[
|
523
|
+
Helper.transporter_java_executable_path.shellescape,
|
524
|
+
"-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
|
525
|
+
'-XX:NewSize=2m',
|
526
|
+
'-Xms32m',
|
527
|
+
'-Xmx1024m',
|
528
|
+
'-Xms1024m',
|
529
|
+
'-Djava.awt.headless=true',
|
530
|
+
'-Dsun.net.http.retryPost=false',
|
531
|
+
java_code_option,
|
532
|
+
'-m verify',
|
533
|
+
("-u #{username.shellescape}" unless use_jwt),
|
534
|
+
("-p #{password.shellescape}" unless use_jwt),
|
535
|
+
("-jwt #{jwt}" if use_jwt),
|
536
|
+
"-f #{source.shellescape}",
|
537
|
+
("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
|
538
|
+
'2>&1' # cause stderr to be written to stdout
|
539
|
+
].compact.join(' ') # compact gets rid of the possibly nil ENV value
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
307
543
|
def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
|
308
544
|
use_jwt = !jwt.to_s.empty?
|
309
545
|
if !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
|
@@ -342,7 +578,7 @@ module FastlaneCore
|
|
342
578
|
end
|
343
579
|
end
|
344
580
|
|
345
|
-
def build_provider_ids_command(username, password, jwt = nil)
|
581
|
+
def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
|
346
582
|
use_jwt = !jwt.to_s.empty?
|
347
583
|
if !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
|
348
584
|
[
|
@@ -401,8 +637,6 @@ module FastlaneCore
|
|
401
637
|
end
|
402
638
|
|
403
639
|
class ItunesTransporter
|
404
|
-
# Matches a line in the provider table: "12 Initech Systems Inc LG89CQY559"
|
405
|
-
PROVIDER_REGEX = /^\d+\s{2,}.+\s{2,}[^\s]+$/
|
406
640
|
TWO_STEP_HOST_PREFIX = "deliver.appspecific"
|
407
641
|
|
408
642
|
# This will be called from the Deliverfile, and disables the logging of the transporter output
|
@@ -426,7 +660,7 @@ module FastlaneCore
|
|
426
660
|
# see: https://github.com/fastlane/fastlane/issues/1524#issuecomment-196370628
|
427
661
|
# for more information about how to use the iTMSTransporter to list your provider
|
428
662
|
# short names
|
429
|
-
def initialize(user = nil, password = nil, use_shell_script = false, provider_short_name = nil, jwt = nil)
|
663
|
+
def initialize(user = nil, password = nil, use_shell_script = false, provider_short_name = nil, jwt = nil, upload: false, api_key: nil)
|
430
664
|
# Xcode 6.x doesn't have the same iTMSTransporter Java setup as later Xcode versions, so
|
431
665
|
# we can't default to using the newer direct Java invocation strategy for those versions.
|
432
666
|
use_shell_script ||= Helper.is_mac? && Helper.xcode_version.start_with?('6.')
|
@@ -439,8 +673,16 @@ module FastlaneCore
|
|
439
673
|
end
|
440
674
|
|
441
675
|
@jwt = jwt
|
676
|
+
@api_key = api_key
|
677
|
+
|
678
|
+
if should_use_altool?(upload, use_shell_script)
|
679
|
+
UI.verbose("Using altool as transporter.")
|
680
|
+
@transporter_executor = AltoolTransporterExecutor.new
|
681
|
+
else
|
682
|
+
UI.verbose("Using iTMSTransporter as transporter.")
|
683
|
+
@transporter_executor = use_shell_script ? ShellScriptTransporterExecutor.new : JavaTransporterExecutor.new
|
684
|
+
end
|
442
685
|
|
443
|
-
@transporter_executor = use_shell_script ? ShellScriptTransporterExecutor.new : JavaTransporterExecutor.new
|
444
686
|
@provider_short_name = provider_short_name
|
445
687
|
end
|
446
688
|
|
@@ -489,7 +731,7 @@ module FastlaneCore
|
|
489
731
|
# @return (Bool) True if everything worked fine
|
490
732
|
# @raise [Deliver::TransporterTransferError] when something went wrong
|
491
733
|
# when transferring
|
492
|
-
def upload(app_id = nil, dir = nil, package_path: nil, asset_path: nil)
|
734
|
+
def upload(app_id = nil, dir = nil, package_path: nil, asset_path: nil, platform: nil)
|
493
735
|
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?
|
494
736
|
|
495
737
|
# Transport can upload .ipa, .dmg, and .pkg files directly with -assetFile
|
@@ -519,14 +761,25 @@ module FastlaneCore
|
|
519
761
|
password_placeholder = @jwt.nil? ? 'YourPassword' : nil
|
520
762
|
jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
|
521
763
|
|
522
|
-
|
523
|
-
|
764
|
+
# Handle AppStore Connect API
|
765
|
+
use_api_key = !@api_key.nil?
|
766
|
+
api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
|
767
|
+
|
768
|
+
api_key = nil
|
769
|
+
api_key = api_key_with_p8_file_path(@api_key) if use_api_key
|
770
|
+
|
771
|
+
command = @transporter_executor.build_upload_command(@user, @password, actual_dir, @provider_short_name, @jwt, platform, api_key)
|
772
|
+
UI.verbose(@transporter_executor.build_upload_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt_placeholder, platform, api_key_placeholder))
|
524
773
|
|
525
774
|
begin
|
526
775
|
result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
|
527
776
|
rescue TransporterRequiresApplicationSpecificPasswordError => ex
|
528
777
|
handle_two_step_failure(ex)
|
529
778
|
return upload(app_id, dir, package_path: package_path, asset_path: asset_path)
|
779
|
+
ensure
|
780
|
+
if use_api_key
|
781
|
+
FileUtils.rm_rf(api_key[:key_dir]) unless api_key.nil?
|
782
|
+
end
|
530
783
|
end
|
531
784
|
|
532
785
|
if result
|
@@ -540,6 +793,46 @@ module FastlaneCore
|
|
540
793
|
return result
|
541
794
|
end
|
542
795
|
|
796
|
+
# Verifies the given binary with App Store Connect
|
797
|
+
# @param app_id [Integer] The unique App ID
|
798
|
+
# @param dir [String] the path in which the package file is located
|
799
|
+
# @param package_path [String] the path to the package file (used instead of app_id and dir)
|
800
|
+
# @return (Bool) True if everything worked fine
|
801
|
+
# @raise [Deliver::TransporterTransferError] when something went wrong
|
802
|
+
# when transferring
|
803
|
+
def verify(app_id = nil, dir = nil, package_path: nil)
|
804
|
+
raise "Either a combination of app id and directory or a package_path are required" if (app_id.nil? || dir.nil?) && package_path.nil?
|
805
|
+
|
806
|
+
actual_dir = if package_path
|
807
|
+
package_path
|
808
|
+
else
|
809
|
+
File.join(dir, "#{app_id}.itmsp")
|
810
|
+
end
|
811
|
+
|
812
|
+
password_placeholder = @jwt.nil? ? 'YourPassword' : nil
|
813
|
+
jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
|
814
|
+
|
815
|
+
command = @transporter_executor.build_verify_command(@user, @password, actual_dir, @provider_short_name, @jwt)
|
816
|
+
UI.verbose(@transporter_executor.build_verify_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt_placeholder))
|
817
|
+
|
818
|
+
begin
|
819
|
+
result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
|
820
|
+
rescue TransporterRequiresApplicationSpecificPasswordError => ex
|
821
|
+
handle_two_step_failure(ex)
|
822
|
+
return verify(app_id, dir, package_path: package_path)
|
823
|
+
end
|
824
|
+
|
825
|
+
if result
|
826
|
+
UI.header("Successfully verified package on App Store Connect")
|
827
|
+
|
828
|
+
FileUtils.rm_rf(actual_dir) unless Helper.test? # we don't need the package any more, since the upload was successful
|
829
|
+
else
|
830
|
+
handle_error(@password)
|
831
|
+
end
|
832
|
+
|
833
|
+
return result
|
834
|
+
end
|
835
|
+
|
543
836
|
def displayable_errors
|
544
837
|
@transporter_executor.displayable_errors
|
545
838
|
end
|
@@ -548,8 +841,15 @@ module FastlaneCore
|
|
548
841
|
password_placeholder = @jwt.nil? ? 'YourPassword' : nil
|
549
842
|
jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
|
550
843
|
|
551
|
-
|
552
|
-
|
844
|
+
# Handle AppStore Connect API
|
845
|
+
use_api_key = !@api_key.nil?
|
846
|
+
api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
|
847
|
+
|
848
|
+
api_key = nil
|
849
|
+
api_key = api_key_with_p8_file_path(@api_key) if use_api_key
|
850
|
+
|
851
|
+
command = @transporter_executor.build_provider_ids_command(@user, @password, @jwt, api_key)
|
852
|
+
UI.verbose(@transporter_executor.build_provider_ids_command(@user, password_placeholder, jwt_placeholder, api_key_placeholder))
|
553
853
|
|
554
854
|
lines = []
|
555
855
|
begin
|
@@ -558,15 +858,36 @@ module FastlaneCore
|
|
558
858
|
rescue TransporterRequiresApplicationSpecificPasswordError => ex
|
559
859
|
handle_two_step_failure(ex)
|
560
860
|
return provider_ids
|
861
|
+
ensure
|
862
|
+
if use_api_key
|
863
|
+
FileUtils.rm_rf(api_key[:key_dir]) unless api_key.nil?
|
864
|
+
end
|
561
865
|
end
|
562
866
|
|
563
|
-
|
867
|
+
@transporter_executor.parse_provider_info(lines)
|
564
868
|
end
|
565
869
|
|
566
870
|
private
|
567
871
|
|
568
872
|
TWO_FACTOR_ENV_VARIABLE = "FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"
|
569
873
|
|
874
|
+
# Create .p8 file from api_key and provide api key info which contains .p8 file path
|
875
|
+
def api_key_with_p8_file_path(original_api_key)
|
876
|
+
api_key = original_api_key.dup
|
877
|
+
api_key[:key_dir] = Dir.mktmpdir("deliver-")
|
878
|
+
# Specified p8 needs to be generated to call altool
|
879
|
+
File.open(File.join(api_key[:key_dir], "AuthKey_#{api_key[:key_id]}.p8"), "wb") do |p8|
|
880
|
+
p8.write(api_key[:key])
|
881
|
+
end
|
882
|
+
api_key
|
883
|
+
end
|
884
|
+
|
885
|
+
# Returns whether altool should be used or ItunesTransporter should be used
|
886
|
+
def should_use_altool?(upload, use_shell_script)
|
887
|
+
# Xcode 14 no longer supports iTMSTransporter. Use altool instead
|
888
|
+
!use_shell_script && upload && !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(14)
|
889
|
+
end
|
890
|
+
|
570
891
|
# Returns the password to be used with the transporter
|
571
892
|
def load_password_for_transporter
|
572
893
|
# 3 different sources for the password
|
@@ -624,11 +945,5 @@ module FastlaneCore
|
|
624
945
|
def handle_error(password)
|
625
946
|
@transporter_executor.handle_error(password)
|
626
947
|
end
|
627
|
-
|
628
|
-
def provider_pair(line)
|
629
|
-
line = line.strip
|
630
|
-
return nil unless line =~ PROVIDER_REGEX
|
631
|
-
line.split(/\s{2,}/).drop(1)
|
632
|
-
end
|
633
948
|
end
|
634
949
|
end
|
@@ -14,6 +14,7 @@ module FastlaneCore
|
|
14
14
|
command << " -T /usr/bin/codesign" # to not be asked for permission when running a tool like `gym` (before Sierra)
|
15
15
|
command << " -T /usr/bin/security"
|
16
16
|
command << " -T /usr/bin/productbuild" # to not be asked for permission when using an installer cert for macOS
|
17
|
+
command << " -T /usr/bin/productsign" # to not be asked for permission when using an installer cert for macOS
|
17
18
|
command << " 1> /dev/null" unless output
|
18
19
|
|
19
20
|
sensitive_command = command.gsub(password_part, " -P ********")
|
@@ -356,7 +356,7 @@ module FastlaneCore
|
|
356
356
|
# This xcodebuild bug is fixed in Xcode 8.3 so 'clean' it's not necessary anymore
|
357
357
|
# See: https://github.com/fastlane/fastlane/pull/5626
|
358
358
|
if FastlaneCore::Helper.xcode_at_least?('8.3')
|
359
|
-
command = "xcodebuild -showBuildSettings #{xcodebuild_parameters.join(' ')}"
|
359
|
+
command = "xcodebuild -showBuildSettings #{xcodebuild_parameters.join(' ')}#{xcodebuild_destination_parameter}"
|
360
360
|
else
|
361
361
|
command = "xcodebuild clean -showBuildSettings #{xcodebuild_parameters.join(' ')}"
|
362
362
|
end
|
@@ -365,10 +365,27 @@ module FastlaneCore
|
|
365
365
|
|
366
366
|
def build_xcodebuild_resolvepackagedependencies_command
|
367
367
|
return nil if options[:skip_package_dependencies_resolution]
|
368
|
-
command = "xcodebuild -resolvePackageDependencies #{xcodebuild_parameters.join(' ')}"
|
368
|
+
command = "xcodebuild -resolvePackageDependencies #{xcodebuild_parameters.join(' ')}#{xcodebuild_destination_parameter}"
|
369
369
|
command
|
370
370
|
end
|
371
371
|
|
372
|
+
def xcodebuild_destination_parameter
|
373
|
+
# Xcode13+ xcodebuild command 'without destination parameter' generates annoying warnings
|
374
|
+
# See: https://github.com/fastlane/fastlane/issues/19579
|
375
|
+
destination_parameter = ""
|
376
|
+
xcode_at_least_13 = FastlaneCore::Helper.xcode_at_least?("13")
|
377
|
+
if xcode_at_least_13 && options[:destination]
|
378
|
+
begin
|
379
|
+
destination_parameter = " " + "-destination #{options[:destination].shellescape}"
|
380
|
+
rescue => ex
|
381
|
+
# xcodebuild command can continue without destination parameter, so
|
382
|
+
# we really don't care about this exception if something goes wrong with shellescape
|
383
|
+
UI.important("Failed to set destination parameter for xcodebuild command: #{ex}")
|
384
|
+
end
|
385
|
+
end
|
386
|
+
destination_parameter
|
387
|
+
end
|
388
|
+
|
372
389
|
# Get the build settings for our project
|
373
390
|
# e.g. to properly get the DerivedData folder
|
374
391
|
# @param [String] The key of which we want the value for (e.g. "PRODUCT_NAME")
|
@@ -86,11 +86,13 @@ module FastlaneCore
|
|
86
86
|
|
87
87
|
def header(message)
|
88
88
|
format = format_string
|
89
|
-
|
89
|
+
# clamp to zero to prevent negative argument error below
|
90
|
+
available_width = [0, TTY::Screen.width - format.length].max
|
91
|
+
if message.length + 8 < available_width
|
90
92
|
message = "--- #{message} ---"
|
91
93
|
i = message.length
|
92
94
|
else
|
93
|
-
i =
|
95
|
+
i = available_width
|
94
96
|
end
|
95
97
|
success("-" * i)
|
96
98
|
success(message)
|
@@ -51,7 +51,7 @@ module Frameit
|
|
51
51
|
found_device = nil
|
52
52
|
filename_device = nil
|
53
53
|
filename = Pathname.new(path).basename.to_s
|
54
|
-
Devices.constants.
|
54
|
+
Devices.constants.sort_by(&:length).reverse_each do |c|
|
55
55
|
device = Devices.const_get(c)
|
56
56
|
next unless device.resolutions.include?(size)
|
57
57
|
# assign to filename_device if the filename contains the formatted name / id and its priority is higher than the current filename_device
|
@@ -47,6 +47,10 @@ module Frameit
|
|
47
47
|
PURPLE ||= "Purple"
|
48
48
|
GRAPHITE ||= "Graphite"
|
49
49
|
PACIFIC_BLUE ||= "Pacific Blue"
|
50
|
+
MIDNIGHT ||= "Midnight"
|
51
|
+
STARLIGHT ||= "Starlight"
|
52
|
+
SIERRA ||= "Sierra"
|
53
|
+
SORTA_SAGE ||= "Sorta Sage"
|
50
54
|
|
51
55
|
def self.all_colors
|
52
56
|
Color.constants.map { |c| Color.const_get(c).upcase.gsub(' ', '_') }
|
@@ -82,6 +86,7 @@ module Frameit
|
|
82
86
|
# Google Pixel 4's priority should be higher than Samsung Galaxy S10+ (priority 8):
|
83
87
|
GOOGLE_PIXEL_4 ||= Frameit::Device.new("google-pixel-4", "Google Pixel 4", 9, [[1080, 2280], [2280, 1080]], 444, Color::JUST_BLACK, Platform::ANDROID)
|
84
88
|
GOOGLE_PIXEL_4_XL ||= Frameit::Device.new("google-pixel-4-xl", "Google Pixel 4 XL", 9, [[1440, 3040], [3040, 1440]], 537, Color::JUST_BLACK, Platform::ANDROID)
|
89
|
+
GOOGLE_PIXEL_5 ||= Frameit::Device.new("google-pixel-5", "Google Pixel 5", 10, [[1080, 2340], [2340, 1080]], 432, Color::JUST_BLACK, Platform::ANDROID)
|
85
90
|
HTC_ONE_A9 ||= Frameit::Device.new("htc-one-a9", "HTC One A9", 6, [[1080, 1920], [1920, 1080]], 441, Color::BLACK, Platform::ANDROID)
|
86
91
|
HTC_ONE_M8 ||= Frameit::Device.new("htc-one-m8", "HTC One M8", 3, [[1080, 1920], [1920, 1080]], 441, Color::BLACK, Platform::ANDROID)
|
87
92
|
HUAWEI_P8 ||= Frameit::Device.new("huawei-p8", "Huawei P8", 5, [[1080, 1920], [1920, 1080]], 424, Color::BLACK, Platform::ANDROID)
|
@@ -124,6 +129,10 @@ module Frameit
|
|
124
129
|
IPHONE_12_PRO ||= Frameit::Device.new("iphone-12-pro", "Apple iPhone 12 Pro", 10, [[1170, 2532], [2532, 1170]], 460, Color::SPACE_GRAY, Platform::IOS)
|
125
130
|
IPHONE_12_PRO_MAX ||= Frameit::Device.new("iphone12-pro-max", "Apple iPhone 12 Pro Max", 10, [[1284, 2778], [2778, 1284]], 458, Color::GRAPHITE, Platform::IOS)
|
126
131
|
IPHONE_12_MINI ||= Frameit::Device.new("iphone-12-mini", "Apple iPhone 12 Mini", 10, [[1125, 2436], [2436, 1125]], 476, Color::BLACK, Platform::IOS)
|
132
|
+
IPHONE_13 ||= Frameit::Device.new("iphone-13", "Apple iPhone 13", 11, [[1170, 2532], [2532, 1170]], 460, Color::MIDNIGHT, Platform::IOS)
|
133
|
+
IPHONE_13_PRO ||= Frameit::Device.new("iphone-13-pro", "Apple iPhone 13 Pro", 11, [[1170, 2532], [2532, 1170]], 460, Color::GRAPHITE, Platform::IOS)
|
134
|
+
IPHONE_13_PRO_MAX ||= Frameit::Device.new("iphone13-pro-max", "Apple iPhone 13 Pro Max", 11, [[1284, 2778], [2778, 1284]], 458, Color::GRAPHITE, Platform::IOS)
|
135
|
+
IPHONE_13_MINI ||= Frameit::Device.new("iphone-13-mini", "Apple iPhone 13 Mini", 11, [[1080, 2340], [2340, 1080]], 476, Color::MIDNIGHT, Platform::IOS)
|
127
136
|
IPAD_10_2 ||= Frameit::Device.new("ipad-10-2", "Apple iPad 10.2", 1, [[1620, 2160], [2160, 1620]], 264, Color::SPACE_GRAY, Platform::IOS)
|
128
137
|
IPAD_AIR_2 ||= Frameit::Device.new("ipad-air-2", "Apple iPad Air 2", 1, [[1536, 2048], [2048, 1536]], 264, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_IPAD)
|
129
138
|
IPAD_AIR_2019 ||= Frameit::Device.new("ipad-air-2019", "Apple iPad Air (2019)", 2, [[1668, 2224], [2224, 1668]], 265, Color::SPACE_GRAY, Platform::IOS)
|
@@ -53,7 +53,7 @@ module Frameit
|
|
53
53
|
|
54
54
|
def print_disclaimer
|
55
55
|
UI.header("Device frames disclaimer")
|
56
|
-
UI.important("All used device frames are available via Facebook Design:
|
56
|
+
UI.important("All used device frames are available via Facebook Design: https://design.facebook.com/toolsandresources/devices/")
|
57
57
|
UI.message("----------------------------------------")
|
58
58
|
UI.message("While Facebook has redrawn and shares these assets for the benefit")
|
59
59
|
UI.message("of the design community, Facebook does not own any of the underlying")
|
@@ -39,6 +39,7 @@ module Gym
|
|
39
39
|
options << "-destination '#{config[:destination]}'" if config[:destination]
|
40
40
|
options << "-archivePath #{archive_path.shellescape}" unless config[:skip_archive]
|
41
41
|
options << "-resultBundlePath '#{result_bundle_path}'" if config[:result_bundle]
|
42
|
+
options << "-showBuildTimingSummary" if config[:build_timing_summary]
|
42
43
|
if config[:use_system_scm] && !options.include?("-scmProvider system")
|
43
44
|
options << "-scmProvider system"
|
44
45
|
end
|
data/gym/lib/gym/options.rb
CHANGED
@@ -239,6 +239,13 @@ module Gym
|
|
239
239
|
default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
|
240
240
|
default_value_dynamic: true),
|
241
241
|
|
242
|
+
FastlaneCore::ConfigItem.new(key: :build_timing_summary,
|
243
|
+
env_name: "GYM_BUILD_TIMING_SUMMARY",
|
244
|
+
description: "Create a build timing summary",
|
245
|
+
type: Boolean,
|
246
|
+
default_value: false,
|
247
|
+
optional: true),
|
248
|
+
|
242
249
|
# xcpretty
|
243
250
|
FastlaneCore::ConfigItem.new(key: :disable_xcpretty,
|
244
251
|
env_name: "DISABLE_XCPRETTY",
|
@@ -42,6 +42,8 @@ module Match
|
|
42
42
|
message = "[fastlane] Changed passphrase"
|
43
43
|
files_to_commit = encryption.encrypt_files(password: new_password)
|
44
44
|
storage.save_changes!(files_to_commit: files_to_commit, custom_message: message)
|
45
|
+
ensure
|
46
|
+
storage.clear_changes if storage
|
45
47
|
end
|
46
48
|
|
47
49
|
def self.ensure_ui_interactive
|
@@ -155,7 +155,8 @@ module Match
|
|
155
155
|
FastlaneCore::CommanderGenerator.new.generate(Match::Options.available_options, command: c)
|
156
156
|
|
157
157
|
c.action do |args, options|
|
158
|
-
Match::
|
158
|
+
params = FastlaneCore::Configuration.create(Match::Options.available_options, options.__hash__)
|
159
|
+
Match::Migrate.new.migrate(params)
|
159
160
|
end
|
160
161
|
end
|
161
162
|
|
@@ -135,7 +135,7 @@ module Match
|
|
135
135
|
UI.crash!("Error encrypting '#{path}'")
|
136
136
|
end
|
137
137
|
|
138
|
-
# The encryption parameters in this implementations reflect the old
|
138
|
+
# The encryption parameters in this implementations reflect the old behavior which depended on the users' local OpenSSL version
|
139
139
|
# 1.0.x OpenSSL and earlier versions use MD5, 1.1.0c and newer uses SHA256, we try both before giving an error
|
140
140
|
def decrypt_specific_file(path: nil, password: nil, hash_algorithm: "MD5")
|
141
141
|
stored_data = Base64.decode64(File.read(path))
|