fastlane 2.237.0 → 2.238.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +111 -104
  3. data/deliver/lib/deliver/options.rb +1 -1
  4. data/fastlane/lib/fastlane/actions/deploygate.rb +3 -2
  5. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +4 -2
  6. data/fastlane/lib/fastlane/actions/hockey.rb +3 -2
  7. data/fastlane/lib/fastlane/actions/installr.rb +3 -2
  8. data/fastlane/lib/fastlane/actions/mailgun.rb +1 -0
  9. data/fastlane/lib/fastlane/actions/notarize.rb +3 -18
  10. data/fastlane/lib/fastlane/actions/register_devices.rb +21 -5
  11. data/fastlane/lib/fastlane/actions/setup_ci.rb +7 -2
  12. data/fastlane/lib/fastlane/actions/spm.rb +6 -0
  13. data/fastlane/lib/fastlane/actions/testfairy.rb +5 -3
  14. data/fastlane/lib/fastlane/actions/tryouts.rb +3 -2
  15. data/fastlane/lib/fastlane/actions/update_project_team.rb +17 -9
  16. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +33 -7
  17. data/fastlane/lib/fastlane/version.rb +1 -1
  18. data/fastlane/swift/Deliverfile.swift +1 -1
  19. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  20. data/fastlane/swift/Fastlane.swift +29 -19
  21. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +1 -1
  22. data/fastlane/swift/Gymfile.swift +1 -1
  23. data/fastlane/swift/GymfileProtocol.swift +1 -1
  24. data/fastlane/swift/Matchfile.swift +1 -1
  25. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  26. data/fastlane/swift/Precheckfile.swift +1 -1
  27. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  28. data/fastlane/swift/Scanfile.swift +1 -1
  29. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  30. data/fastlane/swift/Screengrabfile.swift +1 -1
  31. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  32. data/fastlane/swift/Snapshotfile.swift +1 -1
  33. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  34. data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +31 -5
  35. data/fastlane_core/lib/fastlane_core/analytics/analytics_ingester_client.rb +24 -12
  36. data/fastlane_core/lib/fastlane_core/analytics/analytics_session.rb +22 -12
  37. data/fastlane_core/lib/fastlane_core/cert_checker.rb +22 -9
  38. data/fastlane_core/lib/fastlane_core/helper.rb +4 -3
  39. data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +6 -2
  40. data/fastlane_core/lib/fastlane_core/pkg_upload_package_builder.rb +1 -1
  41. data/fastlane_core/lib/fastlane_core/print_table.rb +0 -16
  42. data/fastlane_core/lib/fastlane_core/queue_worker.rb +10 -1
  43. data/fastlane_core/lib/fastlane_core/video_utils.rb +4 -2
  44. data/gym/lib/gym/module.rb +20 -2
  45. data/pilot/lib/pilot/build_manager.rb +2 -2
  46. data/pilot/lib/pilot/options.rb +2 -2
  47. data/pilot/lib/pilot/tester_manager.rb +2 -2
  48. data/precheck/lib/precheck/rules/copyright_date_rule.rb +1 -1
  49. data/precheck/lib/precheck/rules/unreachable_urls_rule.rb +2 -2
  50. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +4 -1
  51. data/spaceship/lib/spaceship/client.rb +0 -1
  52. data/spaceship/lib/spaceship/connect_api/file_uploader.rb +1 -1
  53. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +6 -0
  54. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +5 -0
  55. data/spaceship/lib/spaceship/helper/plist_middleware.rb +37 -8
  56. metadata +71 -29
@@ -4,18 +4,20 @@ require_relative 'analytics_event_builder'
4
4
 
5
5
  module FastlaneCore
6
6
  class AnalyticsSession
7
- GA_TRACKING = "UA-121171860-1"
7
+ GA_TRACKING = "G-94HQ3VVP0X"
8
8
 
9
9
  private_constant :GA_TRACKING
10
10
  attr_accessor :session_id
11
11
  attr_accessor :client
12
12
 
13
13
  def initialize(analytics_ingester_client: AnalyticsIngesterClient.new(GA_TRACKING))
14
- require 'securerandom'
15
- @session_id = SecureRandom.uuid
14
+ # GA4 requires a numeric session ID for events to be attributed to a session
15
+ @session_id = Time.now.to_i.to_s
16
+ @session_start_time = Time.now
16
17
  @client = analytics_ingester_client
17
18
  @threads = []
18
- @launch_event_sent = false
19
+ @launch_event = nil
20
+ @launch_event_captured = false
19
21
  end
20
22
 
21
23
  def action_launched(launch_context: nil)
@@ -23,23 +25,22 @@ module FastlaneCore
23
25
  show_message
24
26
  end
25
27
 
26
- if @launch_event_sent || launch_context.p_hash.nil?
28
+ if @launch_event_captured || launch_context.p_hash.nil?
27
29
  return
28
30
  end
29
31
 
30
- @launch_event_sent = true
32
+ @launch_event_captured = true
31
33
  builder = AnalyticsEventBuilder.new(
32
34
  p_hash: launch_context.p_hash,
33
35
  session_id: session_id,
34
36
  action_name: nil,
35
- fastlane_client_language: launch_context.fastlane_client_language
37
+ fastlane_client_language: launch_context.fastlane_client_language,
38
+ build_tool_version: launch_context.build_tool_version
36
39
  )
37
40
 
38
- launch_event = builder.new_event(:launch)
39
- post_thread = client.post_event(launch_event)
40
- unless post_thread.nil?
41
- @threads << post_thread
42
- end
41
+ # The event is not posted until finalize_session, so that the
42
+ # run duration can be reported as GA4 engagement time
43
+ @launch_event = builder.new_event(:launch)
43
44
  end
44
45
 
45
46
  def action_completed(completion_context: nil)
@@ -64,6 +65,15 @@ module FastlaneCore
64
65
  end
65
66
 
66
67
  def finalize_session
68
+ unless @launch_event.nil?
69
+ @launch_event[:engagement_time_msec] = ((Time.now - @session_start_time) * 1000).round
70
+ post_thread = client.post_event(@launch_event)
71
+ unless post_thread.nil?
72
+ @threads << post_thread
73
+ end
74
+ @launch_event = nil
75
+ end
76
+
67
77
  @threads.map(&:join)
68
78
  end
69
79
  end
@@ -43,6 +43,15 @@ WWDRCA_CERTIFICATES = [
43
43
  }
44
44
  ]
45
45
 
46
+ # Common names of the certificates in `WWDRCA_CERTIFICATES`. The WWDR
47
+ # certificates (G2-G6) and the Developer ID certificates (DEV-ID-G1,
48
+ # DEV-ID-G2) use different common names, so each of them has to be queried
49
+ # separately when looking up the installed certificates
50
+ WWDRCA_CERTIFICATE_NAMES = [
51
+ 'Apple Worldwide Developer Relations',
52
+ 'Developer ID Certification Authority'
53
+ ]
54
+
46
55
  module FastlaneCore
47
56
  # This class checks if a specific certificate is installed on the current mac
48
57
  class CertChecker
@@ -123,18 +132,21 @@ module FastlaneCore
123
132
  end
124
133
 
125
134
  def self.installed_wwdr_certificates(keychain: nil)
126
- certificate_name = "Apple Worldwide Developer Relations"
127
135
  keychain ||= wwdr_keychain # backwards compatibility
128
136
 
129
- # Find all installed WWDRCA certificates
137
+ # Find all installed WWDRCA certificates. A single `security
138
+ # find-certificate` call can only match one common name, so query the
139
+ # keychain once per common name used by the certificates
130
140
  installed_certs = []
131
- Helper.backticks("security find-certificate -a -c '#{certificate_name}' -p #{keychain.shellescape}", print: false)
132
- .lines
133
- .each do |line|
134
- if line.start_with?('-----BEGIN CERTIFICATE-----')
135
- installed_certs << line
136
- else
137
- installed_certs.last << line
141
+ WWDRCA_CERTIFICATE_NAMES.each do |certificate_name|
142
+ Helper.backticks("security find-certificate -a -c '#{certificate_name}' -p #{keychain.shellescape}", print: false)
143
+ .lines
144
+ .each do |line|
145
+ if line.start_with?('-----BEGIN CERTIFICATE-----')
146
+ installed_certs << line
147
+ else
148
+ installed_certs.last << line
149
+ end
138
150
  end
139
151
  end
140
152
 
@@ -145,6 +157,7 @@ module FastlaneCore
145
157
  WWDRCA_CERTIFICATES.find { |c| c[:sha256].casecmp?(sha256) }&.fetch(:alias)
146
158
  end
147
159
  .compact
160
+ .uniq
148
161
  end
149
162
 
150
163
  def self.install_missing_wwdr_certificates(in_keychain: nil)
@@ -91,9 +91,10 @@ module FastlaneCore
91
91
  end
92
92
 
93
93
  def self.operating_system
94
- return "macOS" if RUBY_PLATFORM.downcase.include?("darwin")
95
- return "Windows" if RUBY_PLATFORM.downcase.include?("mswin")
96
- return "Linux" if RUBY_PLATFORM.downcase.include?("linux")
94
+ return "macOS" if self.mac?
95
+ return "Windows" if self.windows?
96
+ return "Linux" if self.linux?
97
+ return "Java" if RUBY_PLATFORM =~ /java/
97
98
  return "Unknown"
98
99
  end
99
100
 
@@ -14,8 +14,12 @@ module FastlaneCore
14
14
 
15
15
  def generate(app_id: nil, ipa_path: nil, package_path: nil, platform: nil, app_identifier: nil, short_version: nil, bundle_version: nil)
16
16
  unless Helper.is_mac?
17
- # .itmsp packages are not supported for ipa uploads starting Transporter 4.1, for non-macOS
18
- self.package_path = package_path
17
+ # .itmsp packages are not supported for ipa uploads starting Transporter 4.1, for non-macOS.
18
+ # Use a unique subdirectory anyway: callers pass a shared parent (deliver passes "/tmp"),
19
+ # and ItunesTransporter#upload runs FileUtils.rm_rf on whatever this returns.
20
+ self.package_path = File.join(package_path, "#{app_id}-#{SecureRandom.uuid}")
21
+ FileUtils.mkdir_p(self.package_path)
22
+
19
23
  copy_ipa(ipa_path)
20
24
 
21
25
  # copy any AppStoreInfo.plist file that's next to the ipa file
@@ -22,7 +22,7 @@ module FastlaneCore
22
22
  apple_id: app_id,
23
23
  file_size: File.size(pkg_path),
24
24
  ipa_path: File.basename(pkg_path), # this is only the base name as the ipa is inside the package
25
- md5: Digest::MD5.hexdigest(File.read(pkg_path)),
25
+ md5: Digest::MD5.file(pkg_path).hexdigest,
26
26
  archive_type: 'product-archive',
27
27
  platform: platform
28
28
  }
@@ -1,22 +1,6 @@
1
1
  require_relative 'configuration/configuration'
2
2
  require_relative 'helper'
3
3
 
4
- # Monkey patch Terminal::Table until this is merged
5
- # https://github.com/tj/terminal-table/pull/131
6
- # solves https://github.com/fastlane/fastlane/issues/21852
7
- # loads Terminal::Table first to be able to monkey patch it.
8
- require 'terminal-table'
9
- module Terminal
10
- class Table
11
- class Cell
12
- def lines
13
- # @value.to_s.split(/\n/)
14
- @value.to_s.encode("utf-8", invalid: :replace).split(/\n/)
15
- end
16
- end
17
- end
18
- end
19
-
20
4
  module FastlaneCore
21
5
  class PrintTable
22
6
  class << self
@@ -33,17 +33,26 @@ module FastlaneCore
33
33
  @queue.close
34
34
 
35
35
  threads = []
36
+ results = Queue.new
36
37
  @concurrency.times do
37
38
  threads << Thread.new do
39
+ # Exceptions are re-joined (and raised) below, so this just causes duplicate raised exceptions
40
+ Thread.current.report_on_exception = false
41
+
38
42
  job = @queue.pop
39
43
  while job
40
- @block.call(job)
44
+ results << @block.call(job)
41
45
  job = @queue.pop
42
46
  end
43
47
  end
44
48
  end
45
49
 
46
50
  threads.each(&:join)
51
+
52
+ # Convert Queue to Array
53
+ real_results = []
54
+ real_results << results.pop until results.empty?
55
+ real_results
47
56
  end
48
57
  end
49
58
  end
@@ -60,7 +60,9 @@ module FastlaneCore
60
60
  nil
61
61
  end
62
62
 
63
- # Reads the moov box and returns [w, h] if found in any trak/tkhd, else nil.
63
+ # Reads the moov box and returns [w, h] from the first trak/tkhd with non-zero dimensions, else nil.
64
+ # Non-video tracks (e.g. audio) carry a legitimate tkhd width/height of 0x0,
65
+ # so zero-sized results are skipped to keep scanning for the video track.
64
66
  # Input: io (IO) positioned at moov contents; moov_end (Integer) absolute end offset.
65
67
  # Output: [width, height] or nil.
66
68
  def self.extract_resolution_from_moov(io, moov_end)
@@ -71,7 +73,7 @@ module FastlaneCore
71
73
  if atom_type == "trak"
72
74
  trak_end = io.pos + (atom_size - 8)
73
75
  resolution = extract_resolution_from_trak(io, trak_end)
74
- return resolution if resolution
76
+ return resolution if resolution && resolution[0] > 0 && resolution[1] > 0
75
77
  io.seek(trak_end, IO::SEEK_SET)
76
78
  else
77
79
  skip(io, atom_size - 8)
@@ -56,11 +56,29 @@ module Gym
56
56
  end
57
57
 
58
58
  def building_mac_catalyst_for_ios?
59
- Gym.project.supports_mac_catalyst? && Gym.config[:catalyst_platform] == "ios"
59
+ return false unless Gym.project.supports_mac_catalyst?
60
+
61
+ # If catalyst_platform is explicitly set, use it
62
+ if Gym.config[:catalyst_platform]
63
+ return Gym.config[:catalyst_platform] == "ios"
64
+ end
65
+
66
+ # If catalyst_platform is not set, use SDK to determine
67
+ # Mac Catalyst apps with iOS SDK build for iOS (IPA), not macOS
68
+ return Gym.config[:sdk] == "iphoneos" || Gym.config[:sdk] == "iphonesimulator"
60
69
  end
61
70
 
62
71
  def building_mac_catalyst_for_mac?
63
- Gym.project.supports_mac_catalyst? && Gym.config[:catalyst_platform] == "macos"
72
+ return false unless Gym.project.supports_mac_catalyst?
73
+
74
+ # If catalyst_platform is explicitly set, use it
75
+ if Gym.config[:catalyst_platform]
76
+ return Gym.config[:catalyst_platform] == "macos"
77
+ end
78
+
79
+ # If catalyst_platform is not set, use SDK to determine
80
+ # Mac Catalyst apps with SDK macosx build for Mac (PKG), otherwise for iOS (IPA)
81
+ return Gym.config[:sdk] == "macosx"
64
82
  end
65
83
 
66
84
  def building_multiplatform_for_ios?
@@ -172,7 +172,7 @@ module Pilot
172
172
  # Verify the build has all the includes that we need
173
173
  # and fetch a new build if not
174
174
  if build && (!build.app || !build.build_beta_detail || !build.pre_release_version)
175
- UI.important("Build did include information for app, build beta detail and pre release version")
175
+ UI.important("Build did not include information for app, build beta detail and pre release version")
176
176
  UI.important("Fetching a new build with all the information needed")
177
177
  build = Spaceship::ConnectAPI::Build.get(build_id: build.id)
178
178
  end
@@ -459,7 +459,7 @@ module Pilot
459
459
  if options[:groups]
460
460
  app = uploaded_build.app
461
461
  beta_groups = app.get_beta_groups.select do |group|
462
- options[:groups].include?(group.name)
462
+ group.matches_identifiers?(options[:groups])
463
463
  end
464
464
 
465
465
  unless beta_groups.empty?
@@ -267,7 +267,7 @@ module Pilot
267
267
  FastlaneCore::ConfigItem.new(key: :groups,
268
268
  short_option: "-g",
269
269
  env_name: "PILOT_GROUPS",
270
- description: "Associate tester to one group or more by group name / group id. E.g. `-g \"Team 1\",\"Team 2\"` This is required when `distribute_external` option is set to true or when we want to add a tester to one or more external testing groups ",
270
+ description: "Associate tester to one group or more by group name / group id. E.g. `-g \"Team 1\",\"a06cf5b5-95a9-4beb-88c6-f22bd6b3f7a2\"` This is required when `distribute_external` option is set to true or when we want to add a tester to one or more external testing groups ",
271
271
  optional: true,
272
272
  type: Array,
273
273
  verify_block: proc do |value|
@@ -312,7 +312,7 @@ module Pilot
312
312
  # rubocop:disable Layout/LineLength
313
313
  FastlaneCore::ConfigItem.new(key: :itc_provider,
314
314
  env_name: "PILOT_ITC_PROVIDER",
315
- description: "The provider short name to be used with the iTMSTransporter to identify your team. This value will override the automatically detected provider short name. To get provider short name run `pathToXcode.app/Contents/Applications/Application\\ Loader.app/Contents/itms/bin/iTMSTransporter -m provider -u 'USERNAME' -p 'PASSWORD' -account_type itunes_connect -v off`. The short names of providers should be listed in the second column",
315
+ description: "The provider short name to be used with the iTMSTransporter to identify your team. This value will override the automatically detected provider short name. To get provider short name run `xcrun iTMSTransporter -m provider -u 'USERNAME' -p 'PASSWORD' -account_type itunes_connect -v off`. The short names of providers should be listed in the second column",
316
316
  optional: true),
317
317
  FastlaneCore::ConfigItem.new(key: :provider_public_id,
318
318
  env_name: "PILOT_PROVIDER_PUBLIC_ID",
@@ -13,7 +13,7 @@ module Pilot
13
13
  UI.user_error!("You must provide 1 or more groups (with the `:groups` option)") unless groups_param
14
14
 
15
15
  app.get_beta_groups.select do |group|
16
- next unless groups_param.include?(group.name)
16
+ next unless group.matches_identifiers?(groups_param)
17
17
  user = {
18
18
  email: config[:email],
19
19
  firstName: config[:first_name],
@@ -54,7 +54,7 @@ module Pilot
54
54
  UI.success("Successfully removed tester #{tester.email} from app: #{app.name}")
55
55
  else
56
56
  groups = tester.beta_groups.select do |group|
57
- config[:groups].include?(group.name)
57
+ group.matches_identifiers?(config[:groups])
58
58
  end
59
59
  tester.delete_from_beta_groups(beta_groups: groups)
60
60
 
@@ -11,7 +11,7 @@ module Precheck
11
11
  end
12
12
 
13
13
  def self.friendly_name
14
- "Incorrect, or missing copyright date"
14
+ "No incorrect or missing copyright date"
15
15
  end
16
16
 
17
17
  def self.description
@@ -1,5 +1,5 @@
1
1
  require 'addressable'
2
- require 'faraday_middleware'
2
+ require 'faraday/follow_redirects'
3
3
 
4
4
  require_relative '../rule'
5
5
 
@@ -30,7 +30,7 @@ module Precheck
30
30
  uri = Addressable::URI.parse(url)
31
31
  uri.fragment = nil
32
32
  request = Faraday.new(uri.normalize.to_s) do |connection|
33
- connection.use(FaradayMiddleware::FollowRedirects)
33
+ connection.response(:follow_redirects)
34
34
  connection.adapter(:net_http)
35
35
  end
36
36
  return RuleReturn.new(validation_state: Precheck::VALIDATION_STATES[:failed], failure_data: "HTTP #{request.head.status}: #{url}") unless request.head.status == 200
@@ -81,7 +81,10 @@ module Snapshot
81
81
 
82
82
  unless launcher_config.headless
83
83
  simulator_path = File.join(Helper.xcode_path, 'Applications', 'Simulator.app')
84
- Helper.backticks("open -a #{simulator_path} -g", print: FastlaneCore::Globals.verbose?)
84
+ device_udid = TestCommandGenerator.device_udid(device_types.first)
85
+ command = "open -a #{simulator_path} -g"
86
+ command += " --args -CurrentDeviceUDID #{device_udid}" if device_udid
87
+ Helper.backticks(command, print: FastlaneCore::Globals.verbose?)
85
88
  end
86
89
  end
87
90
 
@@ -1,7 +1,6 @@
1
1
  require 'babosa'
2
2
  require 'faraday' # HTTP Client
3
3
  require 'faraday-cookie_jar'
4
- require 'faraday_middleware'
5
4
  require 'logger'
6
5
  require 'tmpdir'
7
6
  require 'cgi'
@@ -1,8 +1,8 @@
1
1
  require 'faraday' # HTTP Client
2
2
  require 'faraday-cookie_jar'
3
- require 'faraday_middleware'
4
3
 
5
4
  require 'spaceship/globals'
5
+ require_relative '../helper/plist_middleware'
6
6
 
7
7
  require 'openssl'
8
8
 
@@ -27,6 +27,8 @@ module Spaceship
27
27
  attr_accessor :loot_box
28
28
  attr_accessor :messaging_and_chat
29
29
  attr_accessor :parental_controls
30
+ attr_accessor :social_media
31
+ attr_accessor :social_media_age_restricted
30
32
  attr_accessor :unrestricted_web_access
31
33
  attr_accessor :user_generated_content
32
34
 
@@ -96,6 +98,8 @@ module Spaceship
96
98
  "profanityOrCrudeHumor" => "profanity_or_crude_humor",
97
99
  "sexualContentGraphicAndNudity" => "sexual_content_graphic_and_nudity",
98
100
  "sexualContentOrNudity" => "sexual_content_or_nudity",
101
+ "socialMedia" => "social_media",
102
+ "socialMediaAgeRestricted" => "social_media_age_restricted",
99
103
  "unrestrictedWebAccess" => "unrestricted_web_access",
100
104
  "userGeneratedContent" => "user_generated_content",
101
105
  "violenceCartoonOrFantasy" => "violence_cartoon_or_fantasy",
@@ -174,6 +178,8 @@ module Spaceship
174
178
  "lootBox",
175
179
  "messagingAndChat",
176
180
  "parentalControls",
181
+ "socialMedia",
182
+ "socialMediaAgeRestricted",
177
183
  "unrestrictedWebAccess",
178
184
  "userGeneratedContent"
179
185
  ]
@@ -32,6 +32,11 @@ module Spaceship
32
32
  return "betaGroups"
33
33
  end
34
34
 
35
+ # Whether this group is referenced by any of the given identifiers (its name or id)
36
+ def matches_identifiers?(identifiers)
37
+ identifiers.include?(name) || identifiers.include?(id)
38
+ end
39
+
35
40
  #
36
41
  # API
37
42
  #
@@ -1,16 +1,45 @@
1
- require 'faraday_middleware/response_middleware'
1
+ require 'faraday'
2
2
 
3
- module FaradayMiddleware
4
- class PlistMiddleware < ResponseMiddleware
5
- dependency do
3
+ module Spaceship
4
+ class PlistMiddleware < Faraday::Middleware
5
+ def on_complete(env)
6
+ process_response(env) if parse_response?(env)
7
+ end
8
+
9
+ private
10
+
11
+ def process_response(env)
12
+ env.body = parse(env.body)
13
+ end
14
+
15
+ def parse(body)
6
16
  require 'plist' unless Object.const_defined?("Plist")
17
+ Plist.parse_xml(body.force_encoding("UTF-8"))
18
+ rescue StandardError, SyntaxError => e
19
+ raise Faraday::ParsingError.new(e, env)
20
+ end
21
+
22
+ def parse_response?(env)
23
+ env.body.kind_of?(String) && process_response_type?(env) && env.parse_body?
24
+ end
25
+
26
+ def process_response_type?(env)
27
+ type = response_type(env)
28
+ content_types.empty? || content_types.any? do |pattern|
29
+ pattern.kind_of?(Regexp) ? type.match?(pattern) : type == pattern
30
+ end
31
+ end
32
+
33
+ def response_type(env)
34
+ type = env.response_headers['Content-Type'].to_s
35
+ type = type.split(';', 2).first if type.index(';')
36
+ type
7
37
  end
8
38
 
9
- define_parser do |body|
10
- body = body.force_encoding("UTF-8")
11
- Plist.parse_xml(body)
39
+ def content_types
40
+ @content_types ||= Array(options[:content_type])
12
41
  end
13
42
  end
14
43
  end
15
44
 
16
- Faraday::Response.register_middleware(plist: FaradayMiddleware::PlistMiddleware)
45
+ Faraday::Response.register_middleware(plist: Spaceship::PlistMiddleware)
metadata CHANGED
@@ -1,40 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.237.0
4
+ version: 2.238.0
5
5
  platform: ruby
6
6
  authors:
7
- - Jimmy Dee
8
- - Josh Holtz
7
+ - Łukasz Grabowski
8
+ - Jérôme Lacoste
9
+ - Felix Krause
9
10
  - Joshua Liebowitz
10
- - Daniel Jankowski
11
- - Satoshi Namai
12
- - Luka Mirosevic
13
- - Olivier Halligon
14
- - Maksym Grebenets
15
11
  - Roger Oba
16
- - Andrew McBurney
17
- - Manish Rathi
12
+ - Olivier Halligon
13
+ - Helmut Januschka
18
14
  - Connor Tumbleson
15
+ - Josh Holtz
16
+ - Max Ott
17
+ - Satoshi Namai
19
18
  - Jorge Revuelta H
20
- - Felix Krause
21
- - Jérôme Lacoste
19
+ - Aaron Brager
20
+ - Luka Mirosevic
21
+ - Kohki Miki
22
22
  - Stefan Natchev
23
- - Manu Wallner
23
+ - Andrew McBurney
24
24
  - Fumiya Nakamura
25
- - Łukasz Grabowski
26
- - Jan Piotrowski
27
25
  - Iulian Onofrei
28
- - Aaron Brager
29
- - Kohki Miki
30
- - Max Ott
31
- - Matthew Ellis
32
- - Helmut Januschka
33
26
  - Danielle Tomlinson
27
+ - Manu Wallner
28
+ - Daniel Jankowski
29
+ - Jan Piotrowski
30
+ - Matthew Ellis
31
+ - Jimmy Dee
32
+ - Maksym Grebenets
33
+ - Manish Rathi
34
34
  autorequire:
35
35
  bindir: bin
36
36
  cert_chain: []
37
- date: 2026-07-05 00:00:00.000000000 Z
37
+ date: 2026-08-12 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: addressable
@@ -233,35 +233,49 @@ dependencies:
233
233
  - !ruby/object:Gem::Version
234
234
  version: 2.0.0
235
235
  - !ruby/object:Gem::Dependency
236
- name: faraday_middleware
236
+ name: faraday
237
237
  requirement: !ruby/object:Gem::Requirement
238
238
  requirements:
239
239
  - - "~>"
240
240
  - !ruby/object:Gem::Version
241
- version: '1.0'
241
+ version: '2.7'
242
242
  type: :runtime
243
243
  prerelease: false
244
244
  version_requirements: !ruby/object:Gem::Requirement
245
245
  requirements:
246
246
  - - "~>"
247
247
  - !ruby/object:Gem::Version
248
- version: '1.0'
248
+ version: '2.7'
249
249
  - !ruby/object:Gem::Dependency
250
250
  name: faraday-cookie_jar
251
251
  requirement: !ruby/object:Gem::Requirement
252
252
  requirements:
253
253
  - - "~>"
254
254
  - !ruby/object:Gem::Version
255
- version: 0.0.6
255
+ version: 0.0.8
256
256
  type: :runtime
257
257
  prerelease: false
258
258
  version_requirements: !ruby/object:Gem::Requirement
259
259
  requirements:
260
260
  - - "~>"
261
261
  - !ruby/object:Gem::Version
262
- version: 0.0.6
262
+ version: 0.0.8
263
263
  - !ruby/object:Gem::Dependency
264
- name: faraday
264
+ name: faraday-follow_redirects
265
+ requirement: !ruby/object:Gem::Requirement
266
+ requirements:
267
+ - - "~>"
268
+ - !ruby/object:Gem::Version
269
+ version: '0.3'
270
+ type: :runtime
271
+ prerelease: false
272
+ version_requirements: !ruby/object:Gem::Requirement
273
+ requirements:
274
+ - - "~>"
275
+ - !ruby/object:Gem::Version
276
+ version: '0.3'
277
+ - !ruby/object:Gem::Dependency
278
+ name: faraday-multipart
265
279
  requirement: !ruby/object:Gem::Requirement
266
280
  requirements:
267
281
  - - "~>"
@@ -274,6 +288,20 @@ dependencies:
274
288
  - - "~>"
275
289
  - !ruby/object:Gem::Version
276
290
  version: '1.0'
291
+ - !ruby/object:Gem::Dependency
292
+ name: faraday-retry
293
+ requirement: !ruby/object:Gem::Requirement
294
+ requirements:
295
+ - - "~>"
296
+ - !ruby/object:Gem::Version
297
+ version: '2.0'
298
+ type: :runtime
299
+ prerelease: false
300
+ version_requirements: !ruby/object:Gem::Requirement
301
+ requirements:
302
+ - - "~>"
303
+ - !ruby/object:Gem::Version
304
+ version: '2.0'
277
305
  - !ruby/object:Gem::Dependency
278
306
  name: fastimage
279
307
  requirement: !ruby/object:Gem::Requirement
@@ -634,14 +662,14 @@ dependencies:
634
662
  requirements:
635
663
  - - "~>"
636
664
  - !ruby/object:Gem::Version
637
- version: '3'
665
+ version: '4'
638
666
  type: :runtime
639
667
  prerelease: false
640
668
  version_requirements: !ruby/object:Gem::Requirement
641
669
  requirements:
642
670
  - - "~>"
643
671
  - !ruby/object:Gem::Version
644
- version: '3'
672
+ version: '4'
645
673
  - !ruby/object:Gem::Dependency
646
674
  name: tty-screen
647
675
  requirement: !ruby/object:Gem::Requirement
@@ -820,6 +848,20 @@ dependencies:
820
848
  - - "~>"
821
849
  - !ruby/object:Gem::Version
822
850
  version: '0.2'
851
+ - !ruby/object:Gem::Dependency
852
+ name: irb
853
+ requirement: !ruby/object:Gem::Requirement
854
+ requirements:
855
+ - - ">="
856
+ - !ruby/object:Gem::Version
857
+ version: '1.8'
858
+ type: :runtime
859
+ prerelease: false
860
+ version_requirements: !ruby/object:Gem::Requirement
861
+ requirements:
862
+ - - ">="
863
+ - !ruby/object:Gem::Version
864
+ version: '1.8'
823
865
  - !ruby/object:Gem::Dependency
824
866
  name: logger
825
867
  requirement: !ruby/object:Gem::Requirement