fastlane 2.170.0 → 2.175.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +74 -74
  3. data/cert/lib/cert/options.rb +2 -2
  4. data/deliver/lib/deliver/app_screenshot.rb +5 -7
  5. data/deliver/lib/deliver/app_screenshot_validator.rb +108 -0
  6. data/deliver/lib/deliver/commands_generator.rb +1 -1
  7. data/deliver/lib/deliver/loader.rb +13 -29
  8. data/deliver/lib/deliver/options.rb +2 -2
  9. data/deliver/lib/deliver/setup.rb +8 -3
  10. data/deliver/lib/deliver/upload_metadata.rb +2 -0
  11. data/deliver/lib/deliver/upload_screenshots.rb +2 -1
  12. data/fastlane/lib/fastlane/actions/adb.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/add_git_tag.rb +12 -3
  14. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +2 -2
  15. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +1 -0
  16. data/fastlane/lib/fastlane/actions/appetize.rb +13 -1
  17. data/fastlane/lib/fastlane/actions/artifactory.rb +36 -3
  18. data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +10 -2
  19. data/fastlane/lib/fastlane/actions/build_app.rb +3 -1
  20. data/fastlane/lib/fastlane/actions/carthage.rb +22 -0
  21. data/fastlane/lib/fastlane/actions/cocoapods.rb +15 -1
  22. data/fastlane/lib/fastlane/actions/create_pull_request.rb +16 -1
  23. data/fastlane/lib/fastlane/actions/create_xcframework.rb +118 -0
  24. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +1 -1
  25. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
  26. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +8 -2
  27. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +5 -1
  28. data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +142 -0
  29. data/fastlane/lib/fastlane/actions/download_dsyms.rb +5 -16
  30. data/fastlane/lib/fastlane/actions/git_commit.rb +7 -3
  31. data/fastlane/lib/fastlane/actions/github_api.rb +14 -3
  32. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -2
  33. data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
  34. data/fastlane/lib/fastlane/actions/pod_push.rb +9 -0
  35. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -1
  36. data/fastlane/lib/fastlane/actions/register_device.rb +3 -3
  37. data/fastlane/lib/fastlane/actions/register_devices.rb +4 -3
  38. data/fastlane/lib/fastlane/actions/set_changelog.rb +2 -2
  39. data/fastlane/lib/fastlane/actions/set_github_release.rb +21 -8
  40. data/fastlane/lib/fastlane/actions/slack.rb +4 -5
  41. data/fastlane/lib/fastlane/actions/spm.rb +2 -2
  42. data/fastlane/lib/fastlane/actions/swiftlint.rb +4 -4
  43. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +1 -1
  44. data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +4 -2
  45. data/fastlane/lib/fastlane/cli_tools_distributor.rb +3 -0
  46. data/fastlane/lib/fastlane/documentation/actions_list.rb +2 -2
  47. data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
  48. data/fastlane/lib/fastlane/helper/gem_helper.rb +2 -2
  49. data/fastlane/lib/fastlane/version.rb +1 -1
  50. data/fastlane/swift/Actions.swift +1 -1
  51. data/fastlane/swift/Appfile.swift +1 -1
  52. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  53. data/fastlane/swift/ControlCommand.swift +1 -1
  54. data/fastlane/swift/Deliverfile.swift +2 -2
  55. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  56. data/fastlane/swift/Fastlane.swift +213 -38
  57. data/fastlane/swift/Gymfile.swift +2 -2
  58. data/fastlane/swift/GymfileProtocol.swift +11 -3
  59. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  60. data/fastlane/swift/MainProcess.swift +1 -1
  61. data/fastlane/swift/Matchfile.swift +2 -2
  62. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  63. data/fastlane/swift/Plugins.swift +1 -1
  64. data/fastlane/swift/Precheckfile.swift +2 -2
  65. data/fastlane/swift/PrecheckfileProtocol.swift +6 -2
  66. data/fastlane/swift/RubyCommand.swift +1 -1
  67. data/fastlane/swift/RubyCommandable.swift +1 -1
  68. data/fastlane/swift/Runner.swift +2 -2
  69. data/fastlane/swift/RunnerArgument.swift +1 -1
  70. data/fastlane/swift/Scanfile.swift +2 -2
  71. data/fastlane/swift/ScanfileProtocol.swift +14 -2
  72. data/fastlane/swift/Screengrabfile.swift +2 -2
  73. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  74. data/fastlane/swift/Snapshotfile.swift +2 -2
  75. data/fastlane/swift/SnapshotfileProtocol.swift +15 -3
  76. data/fastlane/swift/SocketClient.swift +1 -1
  77. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  78. data/fastlane/swift/SocketResponse.swift +1 -1
  79. data/fastlane/swift/formatting/Brewfile.lock.json +20 -14
  80. data/fastlane/swift/main.swift +1 -1
  81. data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -9
  82. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +1 -1
  83. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +23 -0
  84. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +9 -5
  85. data/fastlane_core/lib/fastlane_core/helper.rb +28 -7
  86. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +41 -16
  87. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -4
  88. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -1
  89. data/fastlane_core/lib/fastlane_core/project.rb +41 -14
  90. data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +2 -2
  91. data/frameit/lib/frameit/device_types.rb +7 -1
  92. data/gym/lib/gym/error_handler.rb +8 -0
  93. data/gym/lib/gym/generators/build_command_generator.rb +3 -1
  94. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +2 -2
  95. data/gym/lib/gym/options.rb +12 -2
  96. data/match/lib/match/encryption/openssl.rb +4 -2
  97. data/match/lib/match/nuke.rb +5 -0
  98. data/match/lib/match/options.rb +2 -2
  99. data/match/lib/match/storage/git_storage.rb +14 -10
  100. data/pilot/lib/pilot/options.rb +2 -2
  101. data/precheck/lib/precheck/options.rb +8 -3
  102. data/precheck/lib/precheck/rule_processor.rb +1 -1
  103. data/precheck/lib/precheck/runner.rb +1 -1
  104. data/scan/lib/scan/options.rb +15 -0
  105. data/scan/lib/scan/runner.rb +6 -1
  106. data/scan/lib/scan/slack_poster.rb +4 -1
  107. data/scan/lib/scan/test_command_generator.rb +3 -1
  108. data/screengrab/lib/screengrab/android_environment.rb +2 -2
  109. data/screengrab/lib/screengrab/runner.rb +2 -0
  110. data/sigh/lib/sigh/options.rb +2 -2
  111. data/sigh/lib/sigh/runner.rb +1 -1
  112. data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
  113. data/snapshot/lib/snapshot/options.rb +17 -2
  114. data/snapshot/lib/snapshot/update.rb +1 -1
  115. data/spaceship/README.md +2 -2
  116. data/spaceship/lib/spaceship/client.rb +14 -1
  117. data/spaceship/lib/spaceship/connect_api/api_client.rb +17 -2
  118. data/spaceship/lib/spaceship/connect_api/models/app.rb +6 -0
  119. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +7 -1
  120. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +9 -0
  121. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +24 -0
  122. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +26 -4
  123. data/spaceship/lib/spaceship/connect_api/models/device.rb +26 -0
  124. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +53 -0
  125. data/spaceship/lib/spaceship/connect_api/response.rb +3 -1
  126. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
  127. data/spaceship/lib/spaceship/connect_api/token.rb +1 -1
  128. data/spaceship/lib/spaceship/playground.rb +2 -2
  129. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  130. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +1 -0
  131. data/spaceship/lib/spaceship/upgrade_2fa_later_client.rb +91 -0
  132. metadata +51 -21
  133. data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
  134. data/spaceship/lib/spaceship/connect_api/models/.app_data_usage_data_protection.rb.swp +0 -0
@@ -67,7 +67,7 @@ module FastlaneCore
67
67
  long_switch = "--#{option.key} #{value_appendix}"
68
68
 
69
69
  description = option.description
70
- description += " (#{option.env_name})" unless option.env_name.to_s.empty?
70
+ description += " (#{option.env_names.join(', ')})" unless option.env_names.empty?
71
71
 
72
72
  # We compact this array here to remove the short_switch variable if it is nil.
73
73
  # Passing a nil value to global_option has been shown to create problems with
@@ -12,6 +12,9 @@ module FastlaneCore
12
12
  # [String] the name of the environment variable, which is only used if no other values were found
13
13
  attr_accessor :env_name
14
14
 
15
+ # [Array] the names of the environment variables, which is only used if no other values were found
16
+ attr_accessor :env_names
17
+
15
18
  # [String] A description shown to the user
16
19
  attr_accessor :description
17
20
 
@@ -71,6 +74,7 @@ module FastlaneCore
71
74
  # Creates a new option
72
75
  # @param key (Symbol) the key which is used as command parameters or key in the fastlane tools
73
76
  # @param env_name (String) the name of the environment variable, which is only used if no other values were found
77
+ # @param env_names (Array) the names of the environment variables, which is only used if no other values were found
74
78
  # @param description (String) A description shown to the user
75
79
  # @param short_option (String) A string of length 1 which is used for the command parameters (e.g. -f)
76
80
  # @param default_value the value which is used if there was no given values and no environment values
@@ -88,8 +92,10 @@ module FastlaneCore
88
92
  # @param sensitive (Boolean) Set if the variable is sensitive, such as a password or API token, to prevent echoing when prompted for the parameter
89
93
  # @param display_in_shell (Boolean) Set if the variable can be used from shell
90
94
  # rubocop:disable Metrics/ParameterLists
95
+ # rubocop:disable Metrics/PerceivedComplexity
91
96
  def initialize(key: nil,
92
97
  env_name: nil,
98
+ env_names: nil,
93
99
  description: nil,
94
100
  short_option: nil,
95
101
  default_value: nil,
@@ -109,6 +115,11 @@ module FastlaneCore
109
115
  UI.user_error!("key must be a symbol") unless key.kind_of?(Symbol)
110
116
  UI.user_error!("env_name must be a String") unless (env_name || '').kind_of?(String)
111
117
 
118
+ UI.user_error!("env_names must be an Array") unless (env_names || []).kind_of?(Array)
119
+ (env_names || []).each do |name|
120
+ UI.user_error!("env_names must only contain String") unless (name || '').kind_of?(String)
121
+ end
122
+
112
123
  if short_option
113
124
  UI.user_error!("short_option for key :#{key} must of type String") unless short_option.kind_of?(String)
114
125
  UI.user_error!("short_option for key :#{key} must be a string of length 1") unless short_option.delete('-').length == 1
@@ -138,6 +149,7 @@ module FastlaneCore
138
149
 
139
150
  @key = key
140
151
  @env_name = env_name
152
+ @env_names = [env_name].compact + (env_names || [])
141
153
  @description = description
142
154
  @short_option = short_option
143
155
  @default_value = default_value
@@ -160,6 +172,7 @@ module FastlaneCore
160
172
 
161
173
  update_code_gen_default_value_if_able!
162
174
  end
175
+ # rubocop:enable Metrics/PerceivedComplexity
163
176
  # rubocop:enable Metrics/ParameterLists
164
177
 
165
178
  # if code_gen_default_value is nil, use the default value if it isn't a `code_gen_sensitive` value
@@ -228,6 +241,16 @@ module FastlaneCore
228
241
  true
229
242
  end
230
243
 
244
+ def fetch_env_value
245
+ env_names.each do |name|
246
+ next if ENV[name].nil?
247
+ # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
248
+ return ENV[name].dup if verify!(auto_convert_value(ENV[name]))
249
+ end
250
+
251
+ return nil
252
+ end
253
+
231
254
  # rubocop:disable Metrics/PerceivedComplexity
232
255
  # Returns an updated value type (if necessary)
233
256
  def auto_convert_value(value)
@@ -209,7 +209,6 @@ module FastlaneCore
209
209
 
210
210
  # Returns the value for a certain key. fastlane_core tries to fetch the value from different sources
211
211
  # if 'ask' is true and the value is not present, the user will be prompted to provide a value
212
- # rubocop:disable Metrics/PerceivedComplexity
213
212
  def fetch(key, ask: true)
214
213
  UI.crash!("Key '#{key}' must be a symbol. Example :app_id.") unless key.kind_of?(Symbol)
215
214
 
@@ -218,9 +217,8 @@ module FastlaneCore
218
217
  # Same order as https://docs.fastlane.tools/advanced/#priorities-of-parameters-and-options
219
218
  value = if @values.key?(key) && !@values[key].nil?
220
219
  @values[key]
221
- elsif option.env_name && !ENV[option.env_name].nil?
222
- # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
223
- ENV[option.env_name].dup if option.verify!(option.auto_convert_value(ENV[option.env_name]))
220
+ elsif (env_value = option.fetch_env_value)
221
+ env_value
224
222
  elsif self.config_file_options.key?(key)
225
223
  self.config_file_options[key]
226
224
  else
@@ -243,11 +241,17 @@ module FastlaneCore
243
241
  while value.nil?
244
242
  UI.important("To not be asked about this value, you can specify it using '#{option.key}'") if ENV["FASTLANE_ONBOARDING_IN_PROCESS"].to_s.length == 0
245
243
  value = option.sensitive ? UI.password("#{option.description}: ") : UI.input("#{option.description}: ")
244
+
245
+ # ConfigItem allows to specify a type for the item but UI.password and
246
+ # UI.input return String values. Try to convert the String input to
247
+ # the option's type before passing it along.
248
+ value = option.auto_convert_value(value)
249
+
246
250
  # Also store this value to use it from now on
247
251
  begin
248
252
  set(key, value)
249
253
  rescue => ex
250
- puts(ex)
254
+ UI.error(ex)
251
255
  value = nil
252
256
  end
253
257
  end
@@ -14,7 +14,7 @@ module FastlaneCore
14
14
 
15
15
  def self.fastlane_enabled?
16
16
  # This is called from the root context on the first start
17
- @enabled ||= !FastlaneCore::FastlaneFolder.path.nil?
17
+ !FastlaneCore::FastlaneFolder.path.nil?
18
18
  end
19
19
 
20
20
  # Checks if fastlane is enabled for this project and returns the folder where the configuration lives
@@ -74,7 +74,7 @@ module FastlaneCore
74
74
  return true if self.is_circle_ci?
75
75
 
76
76
  # Check for Jenkins, Travis CI, ... environment variables
77
- ['JENKINS_HOME', 'JENKINS_URL', 'TRAVIS', 'CI', 'APPCENTER_BUILD_ID', 'TEAMCITY_VERSION', 'GO_PIPELINE_NAME', 'bamboo_buildKey', 'GITLAB_CI', 'XCS', 'TF_BUILD', 'GITHUB_ACTION', 'GITHUB_ACTIONS', 'BITRISE_IO'].each do |current|
77
+ ['JENKINS_HOME', 'JENKINS_URL', 'TRAVIS', 'CI', 'APPCENTER_BUILD_ID', 'TEAMCITY_VERSION', 'GO_PIPELINE_NAME', 'bamboo_buildKey', 'GITLAB_CI', 'XCS', 'TF_BUILD', 'GITHUB_ACTION', 'GITHUB_ACTIONS', 'BITRISE_IO', 'BUDDY'].each do |current|
78
78
  return true if ENV.key?(current)
79
79
  end
80
80
  return false
@@ -368,8 +368,29 @@ module FastlaneCore
368
368
 
369
369
  # checks if a given path is an executable file
370
370
  def self.executable?(cmd_path)
371
- # no executable files on Windows, so existing is enough there
372
- cmd_path && !File.directory?(cmd_path) && (File.executable?(cmd_path) || (self.windows? && File.exist?(cmd_path)))
371
+ if !cmd_path || File.directory?(cmd_path)
372
+ return false
373
+ end
374
+
375
+ return File.exist?(get_executable_path(cmd_path))
376
+ end
377
+
378
+ # returns the path of the executable with the correct extension on Windows
379
+ def self.get_executable_path(cmd_path)
380
+ if self.windows?
381
+ # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
382
+ # e.g. ".COM;.EXE;.BAT;.CMD"
383
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
384
+
385
+ # no executable files on Windows, so existing is enough there
386
+ # also check if command + ext is present
387
+ exts.each do |ext|
388
+ executable_path = "#{cmd_path}#{ext.downcase}"
389
+ return executable_path if File.exist?(executable_path)
390
+ end
391
+ end
392
+
393
+ return cmd_path
373
394
  end
374
395
 
375
396
  # checks if given file is a valid json file
@@ -425,20 +446,20 @@ module FastlaneCore
425
446
  UI.current.log
426
447
  end
427
448
 
428
- def self.ask_password(message: "Passphrase: ", confirm: nil)
449
+ def self.ask_password(message: "Passphrase: ", confirm: nil, confirmation_message: "Type passphrase again: ")
429
450
  raise "This code should only run in interactive mode" unless UI.interactive?
430
451
 
431
452
  loop do
432
453
  password = UI.password(message)
433
454
  if confirm
434
- password2 = UI.password("Type passphrase again: ")
455
+ password2 = UI.password(confirmation_message)
435
456
  if password == password2
436
457
  return password
437
458
  end
438
459
  else
439
460
  return password
440
461
  end
441
- UI.error("Passphrases differ. Try again")
462
+ UI.error("Your entries do not match. Please try again")
442
463
  end
443
464
  end
444
465
  end
@@ -1,3 +1,4 @@
1
+ require 'open3'
1
2
  require 'zip'
2
3
 
3
4
  require_relative 'core_ext/cfpropertylist'
@@ -37,27 +38,51 @@ module FastlaneCore
37
38
 
38
39
  def self.fetch_info_plist_file(path)
39
40
  UI.user_error!("Could not find file at path '#{path}'") unless File.exist?(path)
40
- Zip::File.open(path, "rb") do |zipfile|
41
- file = zipfile.glob('**/Payload/*.app/Info.plist').first
42
- return nil unless file
41
+ plist_data = self.fetch_info_plist_with_rubyzip(path)
42
+ if plist_data.nil?
43
+ # Xcode produces invalid zip files for IPAs larger than 4GB. RubyZip
44
+ # can't read them, but the unzip command is able to work around this.
45
+ plist_data = self.fetch_info_plist_with_unzip(path)
46
+ end
47
+ return nil if plist_data.nil?
43
48
 
44
- # Creates a temporary directory with a unique name tagged with 'fastlane'
45
- # The directory is deleted automatically at the end of the block
46
- Dir.mktmpdir("fastlane") do |tmp|
47
- # The XML file has to be properly unpacked first
48
- tmp_path = File.join(tmp, "Info.plist")
49
- File.open(tmp_path, 'wb') do |output|
50
- output.write(zipfile.read(file))
51
- end
52
- result = CFPropertyList.native_types(CFPropertyList::List.new(file: tmp_path).value)
53
-
54
- if result['CFBundleIdentifier'] || result['CFBundleVersion']
55
- return result
56
- end
49
+ # Creates a temporary directory with a unique name tagged with 'fastlane'
50
+ # The directory is deleted automatically at the end of the block
51
+ Dir.mktmpdir("fastlane") do |tmp|
52
+ # The XML file has to be properly unpacked first
53
+ tmp_path = File.join(tmp, "Info.plist")
54
+ File.open(tmp_path, 'wb') do |output|
55
+ output.write(plist_data)
56
+ end
57
+ result = CFPropertyList.native_types(CFPropertyList::List.new(file: tmp_path).value)
58
+
59
+ if result['CFBundleIdentifier'] || result['CFBundleVersion']
60
+ return result
57
61
  end
58
62
  end
59
63
 
60
64
  return nil
61
65
  end
66
+
67
+ def self.fetch_info_plist_with_rubyzip(path)
68
+ Zip::File.open(path, "rb") do |zipfile|
69
+ file = zipfile.glob('**/Payload/*.app/Info.plist').first
70
+ return nil unless file
71
+ zipfile.read(file)
72
+ end
73
+ end
74
+
75
+ def self.fetch_info_plist_with_unzip(path)
76
+ list, error, = Open3.capture3("unzip", "-Z", "-1", path)
77
+ UI.command_output(error) unless error.empty?
78
+ return nil if list.empty?
79
+ entry = list.chomp.split("\n").find do |e|
80
+ File.fnmatch("**/Payload/*.app/Info.plist", e, File::FNM_PATHNAME)
81
+ end
82
+ data, error, = Open3.capture3("unzip", "-p", path, entry)
83
+ UI.command_output(error) unless error.empty?
84
+ return nil if data.empty?
85
+ data
86
+ end
62
87
  end
63
88
  end
@@ -160,11 +160,10 @@ module FastlaneCore
160
160
  end
161
161
 
162
162
  deliver_additional_params = env_deliver_additional_params.to_s.strip
163
- if !deliver_additional_params.include?("-t ")
164
- UI.user_error!("Invalid transport parameter")
165
- else
166
- return deliver_additional_params
163
+ if deliver_additional_params.include?("-t ")
164
+ UI.important("Apple recommends you don’t specify the -t transport and instead allow Transporter to use automatic transport discovery to determine the best transport mode for your packages. For more information, please read Apple's Transporter User Guide 2.1: https://help.apple.com/itc/transporteruserguide/#/apdATD1E1288-D1E1A1303-D1E1288A1126")
167
165
  end
166
+ return deliver_additional_params
168
167
  end
169
168
  end
170
169
 
@@ -99,7 +99,7 @@ module FastlaneCore
99
99
  UI.important("Enter the password for #{keychain_path}")
100
100
  UI.important("This passphrase will be stored in your local keychain with the name #{server} and used in future runs")
101
101
  UI.important("This prompt can be avoided by specifying the 'keychain_password' option or 'MATCH_KEYCHAIN_PASSWORD' environment variable")
102
- keychain_password = FastlaneCore::Helper.ask_password(message: "Password for #{keychain_name} keychain: ", confirm: true)
102
+ keychain_password = FastlaneCore::Helper.ask_password(message: "Password for #{keychain_name} keychain: ", confirm: true, confirmation_message: "Type password for #{keychain_name} keychain again: ")
103
103
  Security::InternetPassword.add(server, "", keychain_password)
104
104
  else
105
105
  UI.important("Keychain password for #{keychain_path} was not specified and not found in your keychain. Specify the 'keychain_password' option to prevent the UI permission popup when code signing")
@@ -1,5 +1,6 @@
1
1
  require_relative 'helper'
2
2
  require 'xcodeproj'
3
+ require_relative './configuration/configuration'
3
4
  require 'fastlane_core/command_executor'
4
5
 
5
6
  module FastlaneCore
@@ -67,9 +68,6 @@ module FastlaneCore
67
68
  # Is this project a workspace?
68
69
  attr_accessor :is_workspace
69
70
 
70
- # The config object containing the scheme, configuration, etc.
71
- attr_accessor :options
72
-
73
71
  # Should the output of xcodebuild commands be silenced?
74
72
  attr_accessor :xcodebuild_list_silent
75
73
 
@@ -77,18 +75,34 @@ module FastlaneCore
77
75
  # Gets rid of annoying plugin info warnings.
78
76
  attr_accessor :xcodebuild_suppress_stderr
79
77
 
78
+ # @param options [FastlaneCore::Configuration|Hash] a set of configuration to run xcodebuild to work out build settings
79
+ # @param xcodebuild_list_silent [Boolean] a flag to silent xcodebuild command's output
80
+ # @param xcodebuild_suppress_stderr [Boolean] a flag to supress output to stderr from xcodebuild
80
81
  def initialize(options, xcodebuild_list_silent: false, xcodebuild_suppress_stderr: false)
81
- self.options = options
82
- self.path = File.expand_path(options[:workspace] || options[:project])
83
- self.is_workspace = (options[:workspace].to_s.length > 0)
84
- self.xcodebuild_list_silent = xcodebuild_list_silent
85
- self.xcodebuild_suppress_stderr = xcodebuild_suppress_stderr
82
+ @options = options
83
+ @path = File.expand_path(self.options[:workspace] || self.options[:project])
84
+ @is_workspace = (self.options[:workspace].to_s.length > 0)
85
+ @xcodebuild_list_silent = xcodebuild_list_silent
86
+ @xcodebuild_suppress_stderr = xcodebuild_suppress_stderr
86
87
 
87
88
  if !path || !File.directory?(path)
88
89
  UI.user_error!("Could not find project at path '#{path}'")
89
90
  end
90
91
  end
91
92
 
93
+ # @return [Hash] a hash object containing project, workspace, scheme, any configuration related to xcodebuild, or etc...
94
+ def options
95
+ # To keep compatibility with actions using this class from outside of `fastlane` gem; i.e. `xcov`,
96
+ # converts `options` to a plain Hash. Otherwise, it might crash when a new option's key is added
97
+ # due to `FastlaneCore::Configuration` to validate valid keys defined.
98
+ @options.kind_of?(FastlaneCore::Configuration) ? @options.values : @options
99
+ end
100
+
101
+ def options=(new_value)
102
+ UI.deprecated('Update `options` is not worth doing since it can change behavior of this object entirely. Consider re-creating FastlaneCore::Project.')
103
+ @options = new_value
104
+ end
105
+
92
106
  def workspace?
93
107
  self.is_workspace
94
108
  end
@@ -275,7 +289,7 @@ module FastlaneCore
275
289
  end
276
290
 
277
291
  def supports_mac_catalyst?
278
- build_settings(key: "SUPPORTS_MACCATALYST") == "YES"
292
+ build_settings(key: "SUPPORTS_MACCATALYST") == "YES" || build_settings(key: "SUPPORTS_UIKITFORMAC") == "YES"
279
293
  end
280
294
 
281
295
  def command_line_tool?
@@ -322,11 +336,17 @@ module FastlaneCore
322
336
  proj << "-configuration #{options[:configuration].shellescape}" if options[:configuration]
323
337
  proj << "-derivedDataPath #{options[:derived_data_path].shellescape}" if options[:derived_data_path]
324
338
  proj << "-xcconfig #{options[:xcconfig].shellescape}" if options[:xcconfig]
339
+ proj << "-scmProvider system" if options[:use_system_scm]
325
340
 
326
- if FastlaneCore::Helper.xcode_at_least?('11.0') && options[:cloned_source_packages_path]
341
+ xcode_at_least_11 = FastlaneCore::Helper.xcode_at_least?('11.0')
342
+ if xcode_at_least_11 && options[:cloned_source_packages_path]
327
343
  proj << "-clonedSourcePackagesDirPath #{options[:cloned_source_packages_path].shellescape}"
328
344
  end
329
345
 
346
+ if xcode_at_least_11 && options[:disable_package_automatic_updates]
347
+ proj << "-disableAutomaticPackageResolution"
348
+ end
349
+
330
350
  return proj
331
351
  end
332
352
 
@@ -350,6 +370,7 @@ module FastlaneCore
350
370
  end
351
371
 
352
372
  def build_xcodebuild_resolvepackagedependencies_command
373
+ return nil if options[:skip_package_dependencies_resolution]
353
374
  command = "xcodebuild -resolvePackageDependencies #{xcodebuild_parameters.join(' ')}"
354
375
  command += " 2> /dev/null" if xcodebuild_suppress_stderr
355
376
  command
@@ -369,10 +390,16 @@ module FastlaneCore
369
390
 
370
391
  # SwiftPM support
371
392
  if FastlaneCore::Helper.xcode_at_least?('11.0')
372
- UI.important("Resolving Swift Package Manager dependencies...")
373
- FastlaneCore::CommandExecutor.execute(command: build_xcodebuild_resolvepackagedependencies_command,
374
- print_all: true,
375
- print_command: !self.xcodebuild_list_silent)
393
+ if (command = build_xcodebuild_resolvepackagedependencies_command)
394
+ UI.important("Resolving Swift Package Manager dependencies...")
395
+ FastlaneCore::CommandExecutor.execute(
396
+ command: command,
397
+ print_all: true,
398
+ print_command: !self.xcodebuild_list_silent
399
+ )
400
+ else
401
+ UI.important("Skipped Swift Package Manager dependencies resolution.")
402
+ end
376
403
  end
377
404
 
378
405
  command = build_xcodebuild_showbuildsettings_command
@@ -63,7 +63,7 @@ module FastlaneCore
63
63
  if !Helper.bundler? && !Helper.contained_fastlane? && Random.rand(5) == 1
64
64
  # We want to show this message from time to time, if the user doesn't use bundler, nor bundled fastlane
65
65
  puts('#######################################################################')
66
- puts("# Run `sudo gem cleanup` from time to time to speed up fastlane")
66
+ puts("# Run `gem cleanup` from time to time to speed up fastlane")
67
67
  end
68
68
  puts('#######################################################################')
69
69
  Changelog.show_changes(gem_name, current_version, update_gem_command: UpdateChecker.update_command(gem_name: gem_name)) unless FastlaneCore::Env.truthy?("FASTLANE_HIDE_CHANGELOG")
@@ -80,7 +80,7 @@ module FastlaneCore
80
80
  elsif Helper.mac_app?
81
81
  "the Fabric app. Launch the app and navigate to the fastlane tab to get the most recent version."
82
82
  else
83
- "sudo gem install #{gem_name.downcase}"
83
+ "gem install #{gem_name.downcase}"
84
84
  end
85
85
  end
86
86
 
@@ -45,6 +45,8 @@ module Frameit
45
45
  GREEN ||= "Green"
46
46
  PINK ||= "Pink"
47
47
  PURPLE ||= "Purple"
48
+ GRAPHITE ||= "Graphite"
49
+ PACIFIC_BLUE ||= "Pacific Blue"
48
50
 
49
51
  def self.all_colors
50
52
  Color.constants.map { |c| Color.const_get(c).upcase.gsub(' ', '_') }
@@ -110,7 +112,7 @@ module Frameit
110
112
  IPHONE_7 ||= Frameit::Device.new("iphone-7", "Apple iPhone 7", 5, [[750, 1334], [1334, 750]], 326, Color::MATTE_BLACK, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_47, :use_legacy_iphone7)
111
113
  IPHONE_7_PLUS ||= Frameit::Device.new("iphone-7-plus", "Apple iPhone 7 Plus", 5, [[1242, 2208], [2208, 1242]], 401, Color::MATTE_BLACK, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_55, :use_legacy_iphone7)
112
114
  IPHONE_8 ||= Frameit::Device.new("iphone-8", "Apple iPhone 8", 6, [[750, 1334], [1334, 750]], 326, Color::SPACE_GRAY)
113
- IPHONE_8_PLUS ||= Frameit::Device.new("iphone-8-plus", "Apple iPhone 8 Plus", 6, [[1080, 1920], [1920, 1080]], 401, Color::SPACE_GRAY)
115
+ IPHONE_8_PLUS ||= Frameit::Device.new("iphone-8-plus", "Apple iPhone 8 Plus", 6, [[1242, 2208], [2208, 1242]], 401, Color::SPACE_GRAY)
114
116
  IPHONE_X ||= Frameit::Device.new("iphone-X", "Apple iPhone X", 7, [[1125, 2436], [2436, 1125]], 458, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_58, :use_legacy_iphonex)
115
117
  IPHONE_XS ||= Frameit::Device.new("iphone-XS", "Apple iPhone XS", 8, [[1125, 2436], [2436, 1125]], 458, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_58, :use_legacy_iphonexs)
116
118
  IPHONE_XR ||= Frameit::Device.new("iphone-XR", "Apple iPhone XR", 8, [[828, 1792], [1792, 828]], 326, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_61, :use_legacy_iphonexr)
@@ -118,6 +120,10 @@ module Frameit
118
120
  IPHONE_11 ||= Frameit::Device.new("iphone-11", "Apple iPhone 11", 9, [[828, 1792], [1792, 828]], 326, Color::BLACK, Platform::IOS)
119
121
  IPHONE_11_PRO ||= Frameit::Device.new("iphone-11-pro", "Apple iPhone 11 Pro", 9, [[1125, 2436], [2436, 1125]], 458, Color::SPACE_GRAY, Platform::IOS)
120
122
  IPHONE_11_PRO_MAX ||= Frameit::Device.new("iphone11-pro-max", "Apple iPhone 11 Pro Max", 9, [[1242, 2688], [2688, 1242]], 458, Color::SPACE_GRAY, Platform::IOS)
123
+ IPHONE_12 ||= Frameit::Device.new("iphone-12", "Apple iPhone 12", 10, [[1170, 2532], [2532, 1170]], 460, Color::BLACK, Platform::IOS)
124
+ 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
+ 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
+ IPHONE_12_MINI ||= Frameit::Device.new("iphone-12-mini", "Apple iPhone 12 Mini", 10, [[1125, 2436], [2436, 1125]], 476, Color::BLACK, Platform::IOS)
121
127
  IPAD_10_2 ||= Frameit::Device.new("ipad-10-2", "Apple iPad 10.2", 1, [[1620, 2160], [2160, 1620]], 264, Color::SPACE_GRAY, Platform::IOS)
122
128
  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)
123
129
  IPAD_AIR_2019 ||= Frameit::Device.new("ipad-air-2019", "Apple iPad Air (2019)", 2, [[1668, 2224], [2224, 1668]], 265, Color::SPACE_GRAY, Platform::IOS)