fastlane 2.217.0 → 2.218.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +96 -96
  3. data/deliver/lib/deliver/app_screenshot.rb +2 -2
  4. data/deliver/lib/deliver/app_screenshot_iterator.rb +2 -2
  5. data/deliver/lib/deliver/detect_values.rb +1 -1
  6. data/deliver/lib/deliver/languages.rb +1 -1
  7. data/deliver/lib/deliver/loader.rb +2 -2
  8. data/deliver/lib/deliver/options.rb +4 -4
  9. data/deliver/lib/deliver/runner.rb +1 -1
  10. data/deliver/lib/deliver/sync_screenshots.rb +2 -2
  11. data/deliver/lib/deliver/upload_metadata.rb +4 -4
  12. data/deliver/lib/deliver/upload_price_tier.rb +1 -1
  13. data/deliver/lib/deliver/upload_screenshots.rb +3 -3
  14. data/fastlane/lib/fastlane/action.rb +1 -1
  15. data/fastlane/lib/fastlane/actions/appledoc.rb +1 -1
  16. data/fastlane/lib/fastlane/actions/apteligent.rb +1 -1
  17. data/fastlane/lib/fastlane/actions/backup_xcarchive.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/commit_github_file.rb +2 -2
  19. data/fastlane/lib/fastlane/actions/copy_artifacts.rb +1 -1
  20. data/fastlane/lib/fastlane/actions/create_app_online.rb +1 -1
  21. data/fastlane/lib/fastlane/actions/create_pull_request.rb +1 -1
  22. data/fastlane/lib/fastlane/actions/get_certificates.rb +1 -1
  23. data/fastlane/lib/fastlane/actions/get_github_release.rb +1 -1
  24. data/fastlane/lib/fastlane/actions/get_provisioning_profile.rb +1 -1
  25. data/fastlane/lib/fastlane/actions/github_api.rb +1 -1
  26. data/fastlane/lib/fastlane/actions/gradle.rb +1 -1
  27. data/fastlane/lib/fastlane/actions/install_on_device.rb +1 -1
  28. data/fastlane/lib/fastlane/actions/ipa.rb +1 -1
  29. data/fastlane/lib/fastlane/actions/jazzy.rb +1 -1
  30. data/fastlane/lib/fastlane/actions/oclint.rb +3 -3
  31. data/fastlane/lib/fastlane/actions/opt_out_crash_reporting.rb +2 -2
  32. data/fastlane/lib/fastlane/actions/restore_file.rb +1 -1
  33. data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
  34. data/fastlane/lib/fastlane/actions/slather.rb +1 -1
  35. data/fastlane/lib/fastlane/actions/sonar.rb +12 -3
  36. data/fastlane/lib/fastlane/actions/splunkmint.rb +1 -1
  37. data/fastlane/lib/fastlane/actions/spm.rb +76 -2
  38. data/fastlane/lib/fastlane/actions/update_info_plist.rb +1 -1
  39. data/fastlane/lib/fastlane/actions/update_urban_airship_configuration.rb +1 -1
  40. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -0
  41. data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +1 -1
  42. data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +2 -2
  43. data/fastlane/lib/fastlane/actions/verify_build.rb +7 -4
  44. data/fastlane/lib/fastlane/actions/xcov.rb +1 -1
  45. data/fastlane/lib/fastlane/cli_tools_distributor.rb +1 -1
  46. data/fastlane/lib/fastlane/command_line_handler.rb +2 -4
  47. data/fastlane/lib/fastlane/commands_generator.rb +2 -2
  48. data/fastlane/lib/fastlane/fast_file.rb +1 -1
  49. data/fastlane/lib/fastlane/helper/dotenv_helper.rb +1 -1
  50. data/fastlane/lib/fastlane/junit_generator.rb +1 -1
  51. data/fastlane/lib/fastlane/lane_manager.rb +1 -2
  52. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +0 -11
  53. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +5 -1
  54. data/fastlane/lib/fastlane/plugins/template/Gemfile.erb +27 -0
  55. data/fastlane/lib/fastlane/runner.rb +1 -1
  56. data/fastlane/lib/fastlane/setup/setup.rb +1 -1
  57. data/fastlane/lib/fastlane/swift_lane_manager.rb +2 -5
  58. data/fastlane/lib/fastlane/swift_runner_upgrader.rb +7 -4
  59. data/fastlane/lib/fastlane/version.rb +1 -1
  60. data/fastlane/swift/Actions.swift +1 -1
  61. data/fastlane/swift/Appfile.swift +1 -1
  62. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  63. data/fastlane/swift/Atomic.swift +1 -1
  64. data/fastlane/swift/ControlCommand.swift +1 -1
  65. data/fastlane/swift/Deliverfile.swift +2 -2
  66. data/fastlane/swift/DeliverfileProtocol.swift +4 -4
  67. data/fastlane/swift/Fastlane.swift +79 -27
  68. data/fastlane/swift/Gymfile.swift +2 -2
  69. data/fastlane/swift/GymfileProtocol.swift +2 -2
  70. data/fastlane/swift/LaneFileProtocol.swift +5 -5
  71. data/fastlane/swift/MainProcess.swift +1 -1
  72. data/fastlane/swift/Matchfile.swift +2 -2
  73. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  74. data/fastlane/swift/OptionalConfigValue.swift +1 -1
  75. data/fastlane/swift/Plugins.swift +1 -1
  76. data/fastlane/swift/Precheckfile.swift +2 -2
  77. data/fastlane/swift/PrecheckfileProtocol.swift +2 -2
  78. data/fastlane/swift/RubyCommand.swift +1 -1
  79. data/fastlane/swift/RubyCommandable.swift +1 -1
  80. data/fastlane/swift/Runner.swift +1 -1
  81. data/fastlane/swift/RunnerArgument.swift +1 -1
  82. data/fastlane/swift/Scanfile.swift +2 -2
  83. data/fastlane/swift/ScanfileProtocol.swift +2 -2
  84. data/fastlane/swift/Screengrabfile.swift +2 -2
  85. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  86. data/fastlane/swift/Snapshotfile.swift +2 -2
  87. data/fastlane/swift/SnapshotfileProtocol.swift +2 -2
  88. data/fastlane/swift/SocketClient.swift +1 -1
  89. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  90. data/fastlane/swift/SocketResponse.swift +1 -1
  91. data/fastlane/swift/formatting/Brewfile.lock.json +18 -18
  92. data/fastlane/swift/main.swift +1 -1
  93. data/fastlane_core/lib/fastlane_core/build_watcher.rb +1 -1
  94. data/fastlane_core/lib/fastlane_core/cert_checker.rb +2 -2
  95. data/fastlane_core/lib/fastlane_core/configuration/configuration_file.rb +1 -1
  96. data/fastlane_core/lib/fastlane_core/device_manager.rb +17 -15
  97. data/fastlane_core/lib/fastlane_core/fastlane_pty.rb +34 -12
  98. data/fastlane_core/lib/fastlane_core/helper.rb +1 -1
  99. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +5 -2
  100. data/fastlane_core/lib/fastlane_core/project.rb +3 -2
  101. data/fastlane_core/lib/fastlane_core/queue_worker.rb +1 -1
  102. data/fastlane_core/lib/fastlane_core/string_filters.rb +6 -6
  103. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +2 -2
  104. data/frameit/lib/frameit/editor.rb +4 -4
  105. data/frameit/lib/frameit/trim_box.rb +1 -1
  106. data/gym/lib/gym/error_handler.rb +1 -1
  107. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +3 -3
  108. data/gym/lib/gym/runner.rb +1 -1
  109. data/gym/lib/gym/xcodebuild_fixes/README.md +1 -1
  110. data/match/lib/match/generator.rb +9 -1
  111. data/match/lib/match/module.rb +2 -1
  112. data/match/lib/match/portal_cache.rb +106 -0
  113. data/match/lib/match/portal_fetcher.rb +72 -0
  114. data/match/lib/match/profile_includes.rb +120 -0
  115. data/match/lib/match/runner.rb +70 -169
  116. data/match/lib/match/spaceship_ensure.rb +15 -11
  117. data/match/lib/match/storage/git_storage.rb +8 -3
  118. data/match/lib/match/storage/gitlab/client.rb +1 -1
  119. data/match/lib/match/storage/gitlab_secure_files.rb +1 -1
  120. data/match/lib/match/storage/interface.rb +1 -1
  121. data/match/lib/match/storage/s3_storage.rb +1 -1
  122. data/match/lib/match.rb +3 -0
  123. data/produce/lib/produce/itunes_connect.rb +1 -1
  124. data/scan/lib/scan/detect_values.rb +78 -20
  125. data/scan/lib/scan/options.rb +1 -1
  126. data/scan/lib/scan/runner.rb +1 -1
  127. data/screengrab/lib/screengrab/runner.rb +1 -1
  128. data/sigh/lib/assets/resign.sh +10 -10
  129. data/sigh/lib/sigh/commands_generator.rb +1 -1
  130. data/sigh/lib/sigh/module.rb +98 -0
  131. data/sigh/lib/sigh/options.rb +55 -1
  132. data/sigh/lib/sigh/resign.rb +1 -1
  133. data/sigh/lib/sigh/runner.rb +35 -111
  134. data/snapshot/lib/snapshot/setup.rb +2 -2
  135. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +23 -22
  136. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +2 -2
  137. data/spaceship/lib/spaceship/client.rb +1 -1
  138. data/spaceship/lib/spaceship/connect_api/api_client.rb +1 -1
  139. data/spaceship/lib/spaceship/connect_api/client.rb +4 -4
  140. data/spaceship/lib/spaceship/connect_api/models/app_preview_set.rb +2 -0
  141. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +2 -2
  142. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +2 -2
  143. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -2
  144. data/spaceship/lib/spaceship/connect_api/models/device.rb +82 -3
  145. data/spaceship/lib/spaceship/connect_api/models/profile.rb +3 -2
  146. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +3 -3
  147. data/spaceship/lib/spaceship/connect_api.rb +2 -0
  148. data/spaceship/lib/spaceship/portal/app.rb +1 -1
  149. data/spaceship/lib/spaceship/portal/app_group.rb +1 -1
  150. data/spaceship/lib/spaceship/test_flight/client.rb +1 -1
  151. data/spaceship/lib/spaceship/test_flight/tester.rb +1 -1
  152. data/spaceship/lib/spaceship/tunes/app_details.rb +2 -2
  153. data/spaceship/lib/spaceship/tunes/app_image.rb +1 -1
  154. data/spaceship/lib/spaceship/tunes/app_review_attachment.rb +1 -1
  155. data/spaceship/lib/spaceship/tunes/app_submission.rb +1 -1
  156. data/spaceship/lib/spaceship/tunes/app_version.rb +5 -5
  157. data/spaceship/lib/spaceship/tunes/build_details.rb +1 -1
  158. data/spaceship/lib/spaceship/tunes/iap.rb +3 -3
  159. data/spaceship/lib/spaceship/tunes/iap_detail.rb +2 -2
  160. data/spaceship/lib/spaceship/tunes/iap_families.rb +1 -1
  161. data/spaceship/lib/spaceship/tunes/iap_family_details.rb +2 -2
  162. data/spaceship/lib/spaceship/tunes/iap_family_list.rb +1 -1
  163. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  164. data/supply/lib/supply/client.rb +1 -1
  165. data/supply/lib/supply/setup.rb +1 -1
  166. data/trainer/lib/trainer/junit_generator.rb +1 -1
  167. data/trainer/lib/trainer/test_parser.rb +1 -1
  168. metadata +26 -289
  169. data/fastlane/lib/fastlane/plugins/template/Gemfile +0 -6
@@ -1,5 +1,6 @@
1
1
  require 'spaceship'
2
2
  require_relative 'module'
3
+ require_relative 'portal_fetcher'
3
4
 
4
5
  module Match
5
6
  # Ensures the certificate and profiles are also available on App Store Connect
@@ -41,8 +42,9 @@ module Match
41
42
  return @team_id
42
43
  end
43
44
 
44
- def bundle_identifier_exists(username: nil, app_identifier: nil, platform: nil)
45
- found = Spaceship::ConnectAPI::BundleId.find(app_identifier)
45
+ def bundle_identifier_exists(username: nil, app_identifier: nil, cached_bundle_ids: nil)
46
+ search_bundle_ids = cached_bundle_ids || Match::Portal::Fetcher.bundle_ids(bundle_id_identifiers: [app_identifier])
47
+ found = search_bundle_ids.any? { |bundle_id| bundle_id.identifier == app_identifier }
46
48
  return if found
47
49
 
48
50
  require 'sigh/runner'
@@ -52,14 +54,17 @@ module Match
52
54
  })
53
55
  UI.error("An app with that bundle ID needs to exist in order to create a provisioning profile for it")
54
56
  UI.error("================================================================")
55
- available_apps = Spaceship::ConnectAPI::BundleId.all.collect { |a| "#{a.identifier} (#{a.name})" }
57
+ all_bundle_ids = Match::Portal::Fetcher.bundle_ids
58
+ available_apps = all_bundle_ids.collect { |a| "#{a.identifier} (#{a.name})" }
56
59
  UI.message("Available apps:\n- #{available_apps.join("\n- ")}")
57
60
  UI.error("Make sure to run `fastlane match` with the same user and team every time.")
58
61
  UI.user_error!("Couldn't find bundle identifier '#{app_identifier}' for the user '#{username}'")
59
62
  end
60
63
 
61
- def certificates_exists(username: nil, certificate_ids: [])
62
- Spaceship::ConnectAPI::Certificate.all.each do |cert|
64
+ def certificates_exists(username: nil, certificate_ids: [], platform:, profile_type:, cached_certificates:)
65
+ certificates = cached_certificates
66
+ certificates ||= Match::Portal::Fetcher.certificates(platform: platform, profile_type: profile_type)
67
+ certificates.each do |cert|
63
68
  certificate_ids.delete(cert.id)
64
69
  end
65
70
  return if certificate_ids.empty?
@@ -74,12 +79,11 @@ module Match
74
79
  UI.user_error!("To reset the certificates of your Apple account, you can use the `fastlane match nuke` feature, more information on https://docs.fastlane.tools/actions/match/")
75
80
  end
76
81
 
77
- def profile_exists(type: nil, username: nil, uuid: nil, platform: nil)
78
- # App Store Connect API does not allow filter of profile by platform or uuid (as of 2020-07-30)
79
- # Need to fetch all profiles and search for uuid on client side
80
- # But we can filter provisioning profiles based on their type (this, in general way faster than getting all profiles)
81
- filter = { profileType: Match.profile_types(type).join(",") } if type
82
- found = Spaceship::ConnectAPI::Profile.all(filter: filter).find do |profile|
82
+ def profile_exists(profile_type: nil, name: nil, username: nil, uuid: nil, cached_profiles: nil)
83
+ profiles = cached_profiles
84
+ profiles ||= Match::Portal::Fetcher.profiles(profile_type: profile_type, name: name)
85
+
86
+ found = profiles.find do |profile|
83
87
  profile.uuid == uuid
84
88
  end
85
89
 
@@ -85,16 +85,21 @@ module Match
85
85
  self.working_directory = Dir.mktmpdir
86
86
 
87
87
  command = "git clone #{self.git_url.shellescape} #{self.working_directory.shellescape}"
88
- # HTTP headers are supposed to be be case insensitive but
88
+ # HTTP headers are supposed to be case-insensitive but
89
89
  # Bitbucket requires `Authorization: Basic` and `Authorization Bearer` to work
90
90
  # https://github.com/fastlane/fastlane/pull/15928
91
91
  command << " -c http.extraheader='Authorization: Basic #{self.git_basic_authorization}'" unless self.git_basic_authorization.nil?
92
92
  command << " -c http.extraheader='Authorization: Bearer #{self.git_bearer_authorization}'" unless self.git_bearer_authorization.nil?
93
93
 
94
94
  if self.shallow_clone
95
- command << " --depth 1 --no-single-branch"
96
- elsif self.clone_branch_directly
95
+ command << " --depth 1"
96
+ end
97
+
98
+ if self.clone_branch_directly
97
99
  command += " -b #{self.branch.shellescape} --single-branch"
100
+ elsif self.shallow_clone
101
+ # shallow clone all branches if not cloning branch directly
102
+ command += " --no-single-branch"
98
103
  end
99
104
 
100
105
  command = command_from_private_key(command) unless self.git_private_key.nil?
@@ -40,7 +40,7 @@ module Match
40
40
  def files
41
41
  @files ||= begin
42
42
  url = URI.parse(base_url)
43
- # 100 is maximum number of Secure files available on Gitlab https://docs.gitlab.com/ee/api/secure_files.html
43
+ # 100 is maximum number of Secure files available on GitLab https://docs.gitlab.com/ee/api/secure_files.html
44
44
  url.query = [url.query, "per_page=100"].compact.join('&')
45
45
 
46
46
  request = Net::HTTP::Get.new(url.request_uri)
@@ -132,7 +132,7 @@ module Match
132
132
  return api_token
133
133
  end
134
134
 
135
- # Returns a short string describing + identifing the current
135
+ # Returns a short string describing + identifying the current
136
136
  # storage backend. This will be printed when nuking a storage
137
137
  def human_readable_description
138
138
  "GitLab Secure Files Storage [#{self.project_id}]"
@@ -36,7 +36,7 @@ module Match
36
36
  not_implemented(__method__)
37
37
  end
38
38
 
39
- # Returns a short string describing + identifing the current
39
+ # Returns a short string describing + identifying the current
40
40
  # storage backend. This will be printed when nuking a storage
41
41
  def human_readable_description
42
42
  not_implemented(__method__)
@@ -121,7 +121,7 @@ module Match
121
121
  UI.verbose("Successfully downloaded files from S3 to #{self.working_directory}")
122
122
  end
123
123
 
124
- # Returns a short string describing + identifing the current
124
+ # Returns a short string describing + identifying the current
125
125
  # storage backend. This will be printed when nuking a storage
126
126
  def human_readable_description
127
127
  return "S3 Bucket [#{s3_bucket}] on region #{s3_region}"
data/match/lib/match.rb CHANGED
@@ -12,3 +12,6 @@ require_relative 'match/importer'
12
12
  require_relative 'match/storage'
13
13
  require_relative 'match/encryption'
14
14
  require_relative 'match/module'
15
+ require_relative 'match/portal_cache'
16
+ require_relative 'match/portal_fetcher'
17
+ require_relative 'match/profile_includes'
@@ -71,7 +71,7 @@ module Produce
71
71
  # Add users to app
72
72
  unless user_ids.empty?
73
73
  application.add_users(user_ids: user_ids)
74
- UI.message("Successfuly added #{user_ids.size} #{user_ids.count == 1 ? 'user' : 'users'} to app")
74
+ UI.message("Successfully added #{user_ids.size} #{user_ids.count == 1 ? 'user' : 'users'} to app")
75
75
  end
76
76
 
77
77
  UI.success("Successfully created new app '#{Produce.config[:app_name]}' on App Store Connect with ID #{application.id}")
@@ -1,10 +1,19 @@
1
1
  require 'fastlane_core/device_manager'
2
2
  require 'fastlane_core/project'
3
+ require 'pathname'
4
+ require 'set'
3
5
  require_relative 'module'
4
6
 
5
7
  module Scan
6
8
  # This class detects all kinds of default values
7
9
  class DetectValues
10
+ PLATFORMS = {
11
+ 'iOS' => { simulator: 'iphonesimulator', name: 'com.apple.platform.iphoneos' },
12
+ 'tvOS' => { simulator: 'appletvsimulator', name: 'com.apple.platform.appletvos' },
13
+ 'watchOS' => { simulator: 'watchsimulator', name: 'com.apple.platform.watchos' },
14
+ 'visionOS' => { simulator: 'xrsimulator', name: 'com.apple.platform.xros' }
15
+ }.freeze
16
+
8
17
  # This is needed as these are more complex default values
9
18
  # Returns the finished config object
10
19
  def self.set_additional_default_values
@@ -100,6 +109,66 @@ module Scan
100
109
  end
101
110
  end
102
111
 
112
+ def self.default_os_version(os_type)
113
+ @os_versions ||= {}
114
+ @os_versions[os_type] ||= begin
115
+ UI.crash!("Unknown platform: #{os_type}") unless PLATFORMS.key?(os_type)
116
+ platform = PLATFORMS[os_type]
117
+
118
+ _, error, = Open3.capture3('xcrun simctl runtime -h')
119
+ unless error.include?('Usage: simctl runtime <operation> <arguments>')
120
+ UI.error("xcrun simctl runtime broken, run 'xcrun simctl runtime' and make sure it works")
121
+ UI.user_error!("xcrun simctl runtime not working.")
122
+ end
123
+
124
+ # `match list` subcommand added in Xcode 15
125
+ if error.include?('match list')
126
+
127
+ # list SDK version for currently running Xcode
128
+ sdks_output, status = Open3.capture2('xcodebuild -showsdks -json')
129
+ sdk_version = begin
130
+ raise status unless status.success?
131
+ JSON.parse(sdks_output).find { |e| e['platform'] == platform[:simulator] }['sdkVersion']
132
+ rescue StandardError => e
133
+ UI.error(e)
134
+ UI.error("xcodebuild CLI broken, please run `xcodebuild` and make sure it works")
135
+ UI.user_error!("xcodebuild not working")
136
+ end
137
+
138
+ # Get runtime build from SDK version
139
+ runtime_output, status = Open3.capture2('xcrun simctl runtime match list -j')
140
+ runtime_build = begin
141
+ raise status unless status.success?
142
+ JSON.parse(runtime_output).values.find { |elem| elem['platform'] == platform[:name] && elem['sdkVersion'] == sdk_version }['chosenRuntimeBuild']
143
+ rescue StandardError => e
144
+ UI.error(e)
145
+ UI.error("xcrun simctl runtime broken, please verify that `xcrun simctl runtime match list` and `xcrun simctl runtime list` work")
146
+ UI.user_error!("xcrun simctl runtime not working")
147
+ end
148
+
149
+ # Get OS version corresponding to build
150
+ Gem::Version.new(FastlaneCore::DeviceManager.runtime_build_os_versions[runtime_build])
151
+ end
152
+ end
153
+ end
154
+
155
+ def self.clear_cache
156
+ @os_versions = nil
157
+ end
158
+
159
+ def self.compatibility_constraint(sim, device_name)
160
+ latest_os = default_os_version(sim.os_type)
161
+ sim.name == device_name && (latest_os.nil? || Gem::Version.new(sim.os_version) <= latest_os)
162
+ end
163
+
164
+ def self.highest_compatible_simulator(simulators, device_name)
165
+ simulators
166
+ .select { |sim| compatibility_constraint(sim, device_name) }
167
+ .reverse
168
+ .sort_by! { |sim| Gem::Version.new(sim.os_version) }
169
+ .last
170
+ end
171
+
103
172
  def self.regular_expression_for_split_on_whitespace_followed_by_parenthesized_version
104
173
  # %r{
105
174
  # \s # a whitespace character
@@ -114,10 +183,9 @@ module Scan
114
183
  end
115
184
 
116
185
  def self.detect_simulator(devices, requested_os_type, deployment_target_key, default_device_name, simulator_type_descriptor)
117
- require 'set'
186
+ clear_cache
118
187
 
119
188
  deployment_target_version = get_deployment_target_version(deployment_target_key)
120
-
121
189
  simulators = filter_simulators(
122
190
  FastlaneCore::DeviceManager.simulators(requested_os_type).tap do |array|
123
191
  if array.empty?
@@ -137,26 +205,23 @@ module Scan
137
205
  # We create 2 lambdas, which we iterate over later on
138
206
  # If the first lambda `matches` found a simulator to use
139
207
  # we'll never call the second one
140
-
141
208
  matches = lambda do
142
209
  set_of_simulators = devices.inject(
143
210
  Set.new # of simulators
144
211
  ) do |set, device_string|
145
212
  pieces = device_string.split(regular_expression_for_split_on_whitespace_followed_by_parenthesized_version)
146
213
 
147
- selector = ->(sim) { pieces.count > 0 && sim.name == pieces.first }
214
+ display_device = "'#{device_string}'"
148
215
 
149
216
  set + (
150
217
  if pieces.count == 0
151
218
  [] # empty array
152
219
  elsif pieces.count == 1
153
- simulators
154
- .select(&selector)
155
- .reverse # more efficient, because `simctl` prints higher versions first
156
- .sort_by! { |sim| Gem::Version.new(sim.os_version) }
157
- .pop(1)
220
+ [ highest_compatible_simulator(simulators, pieces.first) ]
158
221
  else # pieces.count == 2 -- mathematically, because of the 'end of line' part of our regular expression
159
222
  version = pieces[1].tr('()', '')
223
+ display_device = "'#{pieces[0]}' with version #{version}"
224
+
160
225
  potential_emptiness_error = lambda do |sims|
161
226
  if sims.empty?
162
227
  UI.error("No simulators found that are equal to the version " \
@@ -164,12 +229,12 @@ module Scan
164
229
  "of deployment target (#{deployment_target_version})")
165
230
  end
166
231
  end
167
- filter_simulators(simulators, :equal, version).tap(&potential_emptiness_error).select(&selector)
232
+ filter_simulators(simulators, :equal, version).tap(&potential_emptiness_error).select { |sim| sim.name == pieces.first }
168
233
  end
169
234
  ).tap do |array|
170
235
  if array.empty?
171
- UI.test_failure!("No device found with name '#{device_string}'") if Scan.config[:ensure_devices_found]
172
- UI.error("Ignoring '#{device_string}', couldnt find matching simulator")
236
+ UI.test_failure!("No device found with name #{display_device}") if Scan.config[:ensure_devices_found]
237
+ UI.error("Ignoring '#{device_string}', couldn't find matching simulator")
173
238
  end
174
239
  end
175
240
  end
@@ -181,13 +246,7 @@ module Scan
181
246
  default = lambda do
182
247
  UI.error("Couldn't find any matching simulators for '#{devices}' - falling back to default simulator") if (devices || []).count > 0
183
248
 
184
- result = Array(
185
- simulators
186
- .select { |sim| sim.name == default_device_name }
187
- .reverse # more efficient, because `simctl` prints higher versions first
188
- .sort_by! { |sim| Gem::Version.new(sim.os_version) }
189
- .last || simulators.first
190
- )
249
+ result = [ highest_compatible_simulator(simulators, default_device_name) || simulators.first ]
191
250
 
192
251
  UI.message("Found simulator \"#{result.first.name} (#{result.first.os_version})\"") if result.first
193
252
 
@@ -244,7 +303,6 @@ module Scan
244
303
  version = Scan.config[:deployment_target_version]
245
304
  version ||= Scan.project.build_settings(key: deployment_target_key) if Scan.project
246
305
  version ||= 0
247
-
248
306
  return version
249
307
  end
250
308
  end
@@ -269,7 +269,7 @@ module Scan
269
269
  default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
270
270
  default_value_dynamic: true),
271
271
  FastlaneCore::ConfigItem.new(key: :output_remove_retry_attempts,
272
- env_name: "SCAN_OUTPUT_REMOVE_RETRY_ATTEMPS",
272
+ env_names: ["SCAN_OUTPUT_REMOVE_RETRY_ATTEMPS", "SCAN_OUTPUT_REMOVE_RETRY_ATTEMPTS"], # The version with typo must be deprecated
273
273
  description: "Remove retry attempts from test results table and the JUnit report (if not using xcpretty)",
274
274
  type: Boolean,
275
275
  default_value: false),
@@ -397,7 +397,7 @@ module Scan
397
397
 
398
398
  # Return early unless the user wants to prelaunch simulators. Or if the user wants simulator logs
399
399
  # then we must prelaunch simulators because Xcode's headless
400
- # mode launches and shutsdown the simulators before we can collect the logs.
400
+ # mode launches and shuts down the simulators before we can collect the logs.
401
401
  return unless Scan.config[:prelaunch_simulator] || Scan.config[:include_simulator_logs]
402
402
 
403
403
  devices_to_shutdown = []
@@ -37,7 +37,7 @@ module Screengrab
37
37
  test_packages_to_use = @config[:use_tests_in_packages]
38
38
 
39
39
  if test_classes_to_use && test_classes_to_use.any? && test_packages_to_use && test_packages_to_use.any?
40
- UI.error("'use_tests_in_classes' and 'use_tests_in_packages' can not be combined. Please use one or the other.")
40
+ UI.error("'use_tests_in_classes' and 'use_tests_in_packages' cannot be combined. Please use one or the other.")
41
41
  return
42
42
  end
43
43
 
@@ -37,7 +37,7 @@
37
37
  # ./floatsign source "iPhone Distribution: Name" -p "path/to/profile" [-d "display name"] [-e entitlements] [-k keychain] [-b "BundleIdentifier"] outputIpa
38
38
  #
39
39
  #
40
- # Modifed 26th January 2012
40
+ # Modified 26th January 2012
41
41
  #
42
42
  # new features January 2012:
43
43
  # 1. change the app display name
@@ -82,12 +82,12 @@
82
82
  # 1. fix the way app entitlements are extracted
83
83
  #
84
84
  # new features October 2021
85
- # 1. change codesign signatue to use --generate-entitlement-der to include DER encoded entitlements
85
+ # 1. change codesign signature to use --generate-entitlement-der to include DER encoded entitlements
86
86
 
87
87
  # Logging functions
88
88
 
89
89
  log() {
90
- # Make sure it returns 0 code even when verose mode is off (test 1)
90
+ # Make sure it returns 0 code even when verbose mode is off (test 1)
91
91
  # To use like [[ condition ]] && log "x" && something
92
92
  if [[ -n "$VERBOSE" ]]; then echo -e "$@"; else test 1; fi
93
93
  }
@@ -149,7 +149,7 @@ usage() {
149
149
  echo -e "\t\t\t\t\t\t\tCan't use together with '-n, --version-number' option." >&2
150
150
  echo -e "\t-b, --bundle-id bundleId\t\tSpecify new bundle identifier (CFBundleIdentifier)." >&2
151
151
  echo -e "\t\t\t\t\t\t\tWarning: will NOT apply for nested apps and extensions." >&2
152
- echo -e "\t --use-app-entitlements\t\tExtract app bundle codesigning entitlements and combine with entitlements from new provisionin profile." >&2
152
+ echo -e "\t --use-app-entitlements\t\tExtract app bundle codesigning entitlements and combine with entitlements from new provisioning profile." >&2
153
153
  echo -e "\t\t\t\t\t\t\tCan't use together with '-e, --entitlements' option." >&2
154
154
  echo -e "\t--keychain-path path\t\t\tSpecify the path to a keychain that /usr/bin/codesign should use." >&2
155
155
  echo -e "\t-v, --verbose\t\t\t\tVerbose output." >&2
@@ -561,7 +561,7 @@ function resign {
561
561
  FRAMEWORKS_DIR="$APP_PATH/Frameworks"
562
562
  if [ -d "$FRAMEWORKS_DIR" ]; then
563
563
  if [ "$TEAM_IDENTIFIER" == "" ]; then
564
- error "ERROR: embedded frameworks detected, re-signing iOS 8 (or higher) applications wihout a team identifier in the certificate/profile does not work"
564
+ error "ERROR: embedded frameworks detected, re-signing iOS 8 (or higher) applications without a team identifier in the certificate/profile does not work"
565
565
  fi
566
566
 
567
567
  log "Resigning embedded frameworks using certificate: '$CERTIFICATE'"
@@ -569,7 +569,7 @@ function resign {
569
569
  do
570
570
  if [[ "$framework" == *.framework || "$framework" == *.dylib ]]; then
571
571
  log "Resigning '$framework'"
572
- # Must not qote KEYCHAIN_FLAG because it needs to be unwrapped and passed to codesign with spaces
572
+ # Must not quote KEYCHAIN_FLAG because it needs to be unwrapped and passed to codesign with spaces
573
573
  # shellcheck disable=SC2086
574
574
  /usr/bin/codesign ${VERBOSE} --generate-entitlement-der ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" "$framework"
575
575
  checkStatus
@@ -741,7 +741,7 @@ function resign {
741
741
  done
742
742
 
743
743
  # List of rules for transferring entitlements from app to profile plist
744
- # The format for each enty is "KEY[|ID_TYPE]"
744
+ # The format for each entry is "KEY[|ID_TYPE]"
745
745
  # Where KEY is the plist key, e.g. "keychain-access-groups"
746
746
  # and ID_TYPE is optional part separated by '|' that specifies what value to patch:
747
747
  # TEAM_ID - patch the TeamIdentifierPrefix
@@ -838,7 +838,7 @@ function resign {
838
838
  ENTITLEMENTS_VALUE=$(echo "$ENTITLEMENTS_VALUE" | /usr/bin/sed -e "s/$OLD_ICLOUD_ENV/$NEW_ICLOUD_ENV/g")
839
839
  fi
840
840
 
841
- # Remove the entry for current key from profisioning profile entitlements (if exists)
841
+ # Remove the entry for current key from provisioning profile entitlements (if exists)
842
842
  PlistBuddy -c "Delete $KEY" "$PATCHED_ENTITLEMENTS" 2>/dev/null
843
843
 
844
844
  # Add new entry to patched entitlements
@@ -882,7 +882,7 @@ function resign {
882
882
  log "Creating an archived-expanded-entitlements.xcent file for Xcode 9 builds or earlier"
883
883
  cp -- "$TEMP_DIR/newEntitlements" "$APP_PATH/archived-expanded-entitlements.xcent"
884
884
  fi
885
- # Must not qote KEYCHAIN_FLAG because it needs to be unwrapped and passed to codesign with spaces
885
+ # Must not quote KEYCHAIN_FLAG because it needs to be unwrapped and passed to codesign with spaces
886
886
  # shellcheck disable=SC2086
887
887
  /usr/bin/codesign ${VERBOSE} --generate-entitlement-der ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" --entitlements "$TEMP_DIR/newEntitlements" "$APP_PATH"
888
888
  checkStatus
@@ -916,7 +916,7 @@ log "Repackaging as $NEW_FILE"
916
916
  # Zip up the contents of the "$TEMP_DIR" folder
917
917
  # Navigate to the temporary directory (sending the output to null)
918
918
  # Zip all the contents, saving the zip file in the above directory
919
- # Navigate back to the orignating directory (sending the output to null)
919
+ # Navigate back to the originating directory (sending the output to null)
920
920
  pushd "$TEMP_DIR" > /dev/null
921
921
  # TODO: Fix shellcheck warning and remove directive
922
922
  # shellcheck disable=SC2035
@@ -111,7 +111,7 @@ module Sigh
111
111
  c.option('-e', '--entitlements PATH', String, 'The path to the entitlements file to use.')
112
112
  c.option('--short_version STRING', String, 'Short version string to force binary and all nested binaries to use (CFBundleShortVersionString).')
113
113
  c.option('--bundle_version STRING', String, 'Bundle version to force binary and all nested binaries to use (CFBundleVersion).')
114
- c.option('--use_app_entitlements', 'Extract app bundle codesigning entitlements and combine with entitlements from new provisionin profile.')
114
+ c.option('--use_app_entitlements', 'Extract app bundle codesigning entitlements and combine with entitlements from new provisioning profile.')
115
115
  c.option('-g', '--new_bundle_id STRING', String, 'New application bundle ID (CFBundleIdentifier)')
116
116
  c.option('--keychain_path STRING', String, 'Path to the keychain that /usr/bin/codesign should use')
117
117
 
@@ -33,6 +33,104 @@ module Sigh
33
33
  "Direct"
34
34
  end
35
35
  end
36
+
37
+ def profile_type_for_config(platform:, in_house:, config:)
38
+ profile_type = nil
39
+
40
+ case platform.to_s
41
+ when "ios"
42
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_STORE
43
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_INHOUSE if in_house
44
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_ADHOC if config[:adhoc]
45
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_DEVELOPMENT if config[:development]
46
+ when "tvos"
47
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_STORE
48
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_INHOUSE if in_house
49
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_ADHOC if config[:adhoc]
50
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_DEVELOPMENT if config[:development]
51
+ when "macos"
52
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_STORE
53
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE if in_house
54
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DEVELOPMENT if config[:development]
55
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT if config[:developer_id]
56
+ when "catalyst"
57
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_STORE
58
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE if in_house
59
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DEVELOPMENT if config[:development]
60
+ profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT if config[:developer_id]
61
+ end
62
+
63
+ profile_type
64
+ end
65
+
66
+ def profile_type_for_distribution_type(platform:, distribution_type:)
67
+ config = { distribution_type.to_sym => true }
68
+ in_house = distribution_type == "enterprise"
69
+
70
+ self.profile_type_for_config(platform: platform, in_house: in_house, config: config)
71
+ end
72
+
73
+ def certificate_types_for_profile_and_platform(platform:, profile_type:)
74
+ types = []
75
+
76
+ case platform
77
+ when 'ios', 'tvos'
78
+ if profile_type == Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_DEVELOPMENT || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_DEVELOPMENT
79
+ types = [
80
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT,
81
+ Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT
82
+ ]
83
+ elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_INHOUSE || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_INHOUSE
84
+ # Enterprise accounts don't have access to Apple Distribution certificates
85
+ types = [
86
+ Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
87
+ ]
88
+ # handles case where the desired certificate type is adhoc but the account is an enterprise account
89
+ # the apple dev portal api has a weird quirk in it where if you query for distribution certificates
90
+ # for enterprise accounts, you get nothing back even if they exist.
91
+ elsif (profile_type == Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_ADHOC || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_ADHOC) && Spaceship::ConnectAPI.client && Spaceship::ConnectAPI.client.in_house?
92
+ # Enterprise accounts don't have access to Apple Distribution certificates
93
+ types = [
94
+ Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
95
+ ]
96
+ else
97
+ types = [
98
+ Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION,
99
+ Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
100
+ ]
101
+ end
102
+
103
+ when 'macos', 'catalyst'
104
+ if profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DEVELOPMENT || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DEVELOPMENT
105
+ types = [
106
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT,
107
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DEVELOPMENT
108
+ ]
109
+ elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_STORE || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_STORE
110
+ types = [
111
+ Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION,
112
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DISTRIBUTION
113
+ ]
114
+ elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT
115
+ types = [
116
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION,
117
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION_G2
118
+ ]
119
+ elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE
120
+ # Enterprise accounts don't have access to Apple Distribution certificates
121
+ types = [
122
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DISTRIBUTION
123
+ ]
124
+ else
125
+ types = [
126
+ Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION,
127
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DISTRIBUTION
128
+ ]
129
+ end
130
+ end
131
+
132
+ types
133
+ end
36
134
  end
37
135
 
38
136
  Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
@@ -1,6 +1,10 @@
1
1
  require 'fastlane_core/configuration/configuration'
2
2
  require 'credentials_manager/appfile_config'
3
3
  require_relative 'module'
4
+ require 'spaceship/connect_api/models/device'
5
+ require 'spaceship/connect_api/models/certificate'
6
+ require 'spaceship/connect_api/models/bundle_id'
7
+ require 'spaceship/connect_api/models/profile'
4
8
 
5
9
  module Sigh
6
10
  class Options
@@ -192,7 +196,57 @@ module Sigh
192
196
  description: "Should the command fail if it was about to create a duplicate of an existing provisioning profile. It can happen due to issues on Apple Developer Portal, when profile to be recreated was not properly deleted first",
193
197
  optional: true,
194
198
  is_string: false,
195
- default_value: false)
199
+ default_value: false),
200
+
201
+ # Cache
202
+ FastlaneCore::ConfigItem.new(key: :cached_certificates,
203
+ description: "A list of cached certificates",
204
+ optional: true,
205
+ is_string: false,
206
+ default_value: nil,
207
+ verify_block: proc do |value|
208
+ if !value.kind_of?(Array) ||
209
+ value.empty? ||
210
+ !value.all?(Spaceship::ConnectAPI::Certificate)
211
+ UI.user_error!("cached_certificates parameter must be a non-empty array of Spaceship::ConnectAPI::Certificate") unless value.kind_of?(Array)
212
+ end
213
+ end),
214
+ FastlaneCore::ConfigItem.new(key: :cached_devices,
215
+ description: "A list of cached devices",
216
+ optional: true,
217
+ is_string: false,
218
+ default_value: nil,
219
+ verify_block: proc do |value|
220
+ if !value.kind_of?(Array) ||
221
+ value.empty? ||
222
+ !value.all?(Spaceship::ConnectAPI::Device)
223
+ UI.user_error!("cached_devices parameter must be a non-empty array of Spaceship::ConnectAPI::Device")
224
+ end
225
+ end),
226
+ FastlaneCore::ConfigItem.new(key: :cached_bundle_ids,
227
+ description: "A list of cached bundle ids",
228
+ optional: true,
229
+ is_string: false,
230
+ default_value: nil,
231
+ verify_block: proc do |value|
232
+ if !value.kind_of?(Array) ||
233
+ value.empty? ||
234
+ !value.all?(Spaceship::ConnectAPI::BundleId)
235
+ UI.user_error!("cached_bundle_ids parameter must be a non-empty array of Spaceship::ConnectAPI::BundleId")
236
+ end
237
+ end),
238
+ FastlaneCore::ConfigItem.new(key: :cached_profiles,
239
+ description: "A list of cached bundle ids",
240
+ optional: true,
241
+ is_string: false,
242
+ default_value: nil,
243
+ verify_block: proc do |value|
244
+ if !value.kind_of?(Array) ||
245
+ value.empty? ||
246
+ !value.all?(Spaceship::ConnectAPI::Profile)
247
+ UI.user_error!("cached_profiles parameter must be a non-empty array of Spaceship::ConnectAPI::Profile")
248
+ end
249
+ end)
196
250
  ]
197
251
  end
198
252
  end
@@ -58,7 +58,7 @@ module Sigh
58
58
  resign_path.shellescape,
59
59
  ipa.shellescape,
60
60
  signing_identity.shellescape,
61
- provisioning_options, # we are aleady shellescaping this above, when we create the provisioning_options from the provisioning_profiles
61
+ provisioning_options, # we are already shellescaping this above, when we create the provisioning_options from the provisioning_profiles
62
62
  entitlements,
63
63
  version,
64
64
  display_name,