fastlane 2.140.0 → 2.141.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -68
  3. data/cert/lib/cert/options.rb +12 -5
  4. data/cert/lib/cert/runner.rb +13 -0
  5. data/deliver/lib/deliver/options.rb +2 -2
  6. data/deliver/lib/deliver/runner.rb +13 -2
  7. data/fastlane/lib/fastlane/actions/build_app.rb +157 -6
  8. data/fastlane/lib/fastlane/actions/build_ios_app.rb +28 -132
  9. data/fastlane/lib/fastlane/actions/build_mac_app.rb +46 -0
  10. data/fastlane/lib/fastlane/actions/create_pull_request.rb +29 -0
  11. data/fastlane/lib/fastlane/actions/docs/{build_ios_app.md → build_app.md} +1 -1
  12. data/fastlane/lib/fastlane/actions/gym.rb +3 -7
  13. data/fastlane/lib/fastlane/actions/import_from_git.rb +4 -0
  14. data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
  15. data/fastlane/lib/fastlane/actions/update_plist.rb +37 -2
  16. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -0
  17. data/fastlane/lib/fastlane/fast_file.rb +13 -3
  18. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
  19. data/fastlane/lib/fastlane/version.rb +1 -1
  20. data/fastlane/swift/Deliverfile.swift +1 -1
  21. data/fastlane/swift/DeliverfileProtocol.swift +3 -3
  22. data/fastlane/swift/Fastlane.swift +239 -35
  23. data/fastlane/swift/Gymfile.swift +1 -1
  24. data/fastlane/swift/GymfileProtocol.swift +17 -1
  25. data/fastlane/swift/Matchfile.swift +1 -1
  26. data/fastlane/swift/MatchfileProtocol.swift +7 -3
  27. data/fastlane/swift/Precheckfile.swift +1 -1
  28. data/fastlane/swift/Scanfile.swift +1 -1
  29. data/fastlane/swift/ScanfileProtocol.swift +5 -1
  30. data/fastlane/swift/Screengrabfile.swift +1 -1
  31. data/fastlane/swift/Snapshotfile.swift +1 -1
  32. data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
  33. data/fastlane_core/lib/fastlane_core/cert_checker.rb +28 -0
  34. data/fastlane_core/lib/fastlane_core/project.rb +23 -0
  35. data/gym/lib/gym/code_signing_mapping.rb +32 -3
  36. data/gym/lib/gym/detect_values.rb +34 -2
  37. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  38. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +47 -17
  39. data/gym/lib/gym/module.rb +8 -0
  40. data/gym/lib/gym/options.rb +25 -1
  41. data/gym/lib/gym/runner.rb +25 -4
  42. data/match/lib/match/encryption/openssl.rb +1 -1
  43. data/match/lib/match/generator.rb +17 -3
  44. data/match/lib/match/module.rb +4 -1
  45. data/match/lib/match/nuke.rb +54 -16
  46. data/match/lib/match/options.rb +20 -15
  47. data/match/lib/match/runner.rb +20 -8
  48. data/match/lib/match/spaceship_ensure.rb +19 -9
  49. data/match/lib/match/storage/git_storage.rb +5 -2
  50. data/scan/lib/scan/options.rb +6 -1
  51. data/snapshot/lib/snapshot/options.rb +12 -1
  52. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  53. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +11 -0
  54. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +4 -0
  55. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +6 -0
  56. data/spaceship/lib/spaceship/portal/app.rb +11 -2
  57. data/spaceship/lib/spaceship/tunes/iap_status.rb +5 -1
  58. metadata +20 -25
  59. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  60. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  61. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  62. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  63. data/fastlane_core/lib/fastlane_core/.build_watcher.rb.swp +0 -0
  64. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  65. data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
  66. data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
@@ -18,4 +18,4 @@ class Gymfile: GymfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.140.0
21
+ // Generated with fastlane 2.141.0
@@ -30,6 +30,9 @@ protocol GymfileProtocol: class {
30
30
  /// Should we skip packaging the ipa?
31
31
  var skipPackageIpa: Bool { get }
32
32
 
33
+ /// Should we skip packaging the pkg?
34
+ var skipPackagePkg: Bool { get }
35
+
33
36
  /// Should the ipa file include symbols?
34
37
  var includeSymbols: Bool? { get }
35
38
 
@@ -54,6 +57,12 @@ protocol GymfileProtocol: class {
54
57
  /// Build without codesigning
55
58
  var skipCodesigning: Bool? { get }
56
59
 
60
+ /// Platform to build when using a Catalyst enabled app. Valid values are: ios, macos
61
+ var catalystPlatform: String? { get }
62
+
63
+ /// Full name of 3rd Party Mac Developer Installer or Deveoper ID Installer certificate. Example: `3rd Party Mac Developer Installer: Your Company (ABC1234XWYZ)`
64
+ var installerCertName: String? { get }
65
+
57
66
  /// The directory in which the archive should be stored in
58
67
  var buildPath: String? { get }
59
68
 
@@ -119,6 +128,9 @@ protocol GymfileProtocol: class {
119
128
 
120
129
  /// Do not try to build a profile mapping from the xcodeproj. Match or a manually provided mapping should be used
121
130
  var skipProfileDetection: Bool { get }
131
+
132
+ /// Sets a custom path for Swift Package Manager dependencies
133
+ var clonedSourcePackagesPath: String? { get }
122
134
  }
123
135
 
124
136
  extension GymfileProtocol {
@@ -132,6 +144,7 @@ extension GymfileProtocol {
132
144
  var silent: Bool { return false }
133
145
  var codesigningIdentity: String? { return nil }
134
146
  var skipPackageIpa: Bool { return false }
147
+ var skipPackagePkg: Bool { return false }
135
148
  var includeSymbols: Bool? { return nil }
136
149
  var includeBitcode: Bool? { return nil }
137
150
  var exportMethod: String? { return nil }
@@ -140,6 +153,8 @@ extension GymfileProtocol {
140
153
  var skipBuildArchive: Bool? { return nil }
141
154
  var skipArchive: Bool? { return nil }
142
155
  var skipCodesigning: Bool? { return nil }
156
+ var catalystPlatform: String? { return nil }
157
+ var installerCertName: String? { return nil }
143
158
  var buildPath: String? { return nil }
144
159
  var archivePath: String? { return nil }
145
160
  var derivedDataPath: String? { return nil }
@@ -162,8 +177,9 @@ extension GymfileProtocol {
162
177
  var analyzeBuildTime: Bool? { return nil }
163
178
  var xcprettyUtf: Bool? { return nil }
164
179
  var skipProfileDetection: Bool { return false }
180
+ var clonedSourcePackagesPath: String? { return nil }
165
181
  }
166
182
 
167
183
  // Please don't remove the lines below
168
184
  // They are used to detect outdated files
169
- // FastlaneRunnerAPIVersion [0.9.17]
185
+ // FastlaneRunnerAPIVersion [0.9.18]
@@ -18,4 +18,4 @@ class Matchfile: MatchfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.140.0
21
+ // Generated with fastlane 2.141.0
@@ -1,8 +1,11 @@
1
1
  protocol MatchfileProtocol: class {
2
2
 
3
- /// Define the profile type, can be appstore, adhoc, development, enterprise
3
+ /// Define the profile type, can be appstore, adhoc, development, enterprise, developer_id
4
4
  var type: String { get }
5
5
 
6
+ /// Create additional cert types needed for macOS installers (valid values: mac_installer_distribution, developer_id_installer)
7
+ var additionalCertTypes: [String]? { get }
8
+
6
9
  /// Only fetch existing certificates and profiles, don't generate new ones
7
10
  var readonly: Bool { get }
8
11
 
@@ -78,7 +81,7 @@ protocol MatchfileProtocol: class {
78
81
  /// Skip generation of a README.md for the created git repository
79
82
  var skipDocs: Bool { get }
80
83
 
81
- /// Set the provisioning profile's platform to work with (i.e. ios, tvos)
84
+ /// Set the provisioning profile's platform to work with (i.e. ios, tvos, macos)
82
85
  var platform: String { get }
83
86
 
84
87
  /// The name of provisioning profile template. If the developer account has provisioning profile templates (aka: custom entitlements), the template name can be found by inspecting the Entitlements drop-down while creating/editing a provisioning profile (e.g. "Apple Pay Pass Suppression Development")
@@ -93,6 +96,7 @@ protocol MatchfileProtocol: class {
93
96
 
94
97
  extension MatchfileProtocol {
95
98
  var type: String { return "development" }
99
+ var additionalCertTypes: [String]? { return nil }
96
100
  var readonly: Bool { return false }
97
101
  var generateAppleCerts: Bool { return true }
98
102
  var skipProvisioningProfiles: Bool { return false }
@@ -126,4 +130,4 @@ extension MatchfileProtocol {
126
130
 
127
131
  // Please don't remove the lines below
128
132
  // They are used to detect outdated files
129
- // FastlaneRunnerAPIVersion [0.9.12]
133
+ // FastlaneRunnerAPIVersion [0.9.13]
@@ -18,4 +18,4 @@ class Precheckfile: PrecheckfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.140.0
21
+ // Generated with fastlane 2.141.0
@@ -18,4 +18,4 @@ class Scanfile: ScanfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.140.0
21
+ // Generated with fastlane 2.141.0
@@ -168,6 +168,9 @@ protocol ScanfileProtocol: class {
168
168
  /// Allows for override of the default `xcodebuild` command
169
169
  var xcodebuildCommand: String { get }
170
170
 
171
+ /// Sets a custom path for Swift Package Manager dependencies
172
+ var clonedSourcePackagesPath: String? { get }
173
+
171
174
  /// Should this step stop the build if the tests fail? Set this to false if you're using trainer
172
175
  var failBuild: Bool { get }
173
176
  }
@@ -229,9 +232,10 @@ extension ScanfileProtocol {
229
232
  var destination: String? { return nil }
230
233
  var customReportFileName: String? { return nil }
231
234
  var xcodebuildCommand: String { return "env NSUnbufferedIO=YES xcodebuild" }
235
+ var clonedSourcePackagesPath: String? { return nil }
232
236
  var failBuild: Bool { return true }
233
237
  }
234
238
 
235
239
  // Please don't remove the lines below
236
240
  // They are used to detect outdated files
237
- // FastlaneRunnerAPIVersion [0.9.24]
241
+ // FastlaneRunnerAPIVersion [0.9.25]
@@ -18,4 +18,4 @@ class Screengrabfile: ScreengrabfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.140.0
21
+ // Generated with fastlane 2.141.0
@@ -18,4 +18,4 @@ class Snapshotfile: SnapshotfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.140.0
21
+ // Generated with fastlane 2.141.0
@@ -101,6 +101,12 @@ protocol SnapshotfileProtocol: class {
101
101
 
102
102
  /// Take snapshots on multiple simulators concurrently. Note: This option is only applicable when running against Xcode 9
103
103
  var concurrentSimulators: Bool { get }
104
+
105
+ /// Disable the simulator from showing the 'Slide to type' prompt
106
+ var disableSlideToType: Bool { get }
107
+
108
+ /// Sets a custom path for Swift Package Manager dependencies
109
+ var clonedSourcePackagesPath: String? { get }
104
110
  }
105
111
 
106
112
  extension SnapshotfileProtocol {
@@ -138,8 +144,10 @@ extension SnapshotfileProtocol {
138
144
  var testTargetName: String? { return nil }
139
145
  var namespaceLogFiles: String? { return nil }
140
146
  var concurrentSimulators: Bool { return true }
147
+ var disableSlideToType: Bool { return false }
148
+ var clonedSourcePackagesPath: String? { return nil }
141
149
  }
142
150
 
143
151
  // Please don't remove the lines below
144
152
  // They are used to detect outdated files
145
- // FastlaneRunnerAPIVersion [0.9.6]
153
+ // FastlaneRunnerAPIVersion [0.9.7]
@@ -10,6 +10,7 @@ module FastlaneCore
10
10
  UI.user_error!("Could not find file '#{path}'") unless File.exist?(path)
11
11
 
12
12
  ids = installed_identies(in_keychain: in_keychain)
13
+ ids += installed_installers(in_keychain: in_keychain)
13
14
  finger_print = sha1_fingerprint(path)
14
15
 
15
16
  return ids.include?(finger_print)
@@ -47,12 +48,39 @@ module FastlaneCore
47
48
  return ids
48
49
  end
49
50
 
51
+ def self.installed_installers(in_keychain: nil)
52
+ available = self.list_available_third_party_mac_installer(in_keychain: in_keychain)
53
+ available += self.list_available_developer_id_installer(in_keychain: in_keychain)
54
+
55
+ return available.scan(/^SHA-1 hash: ([[:xdigit:]]+)$/).flatten
56
+ end
57
+
50
58
  def self.list_available_identities(in_keychain: nil)
59
+ # -v Show valid identities only (default is to show all identities)
60
+ # -p Specify policy to evaluate
51
61
  commands = ['security find-identity -v -p codesigning']
52
62
  commands << in_keychain if in_keychain
53
63
  `#{commands.join(' ')}`
54
64
  end
55
65
 
66
+ def self.list_available_third_party_mac_installer(in_keychain: nil)
67
+ # -Z Print SHA-256 (and SHA-1) hash of the certificate
68
+ # -a Find all matching certificates, not just the first one
69
+ # -c Match on "name" when searching (optional)
70
+ commands = ['security find-certificate -Z -a -c "3rd Party Mac Developer Installer"']
71
+ commands << in_keychain if in_keychain
72
+ `#{commands.join(' ')}`
73
+ end
74
+
75
+ def self.list_available_developer_id_installer(in_keychain: nil)
76
+ # -Z Print SHA-256 (and SHA-1) hash of the certificate
77
+ # -a Find all matching certificates, not just the first one
78
+ # -c Match on "name" when searching (optional)
79
+ commands = ['security find-certificate -Z -a -c "Developer ID Installer"']
80
+ commands << in_keychain if in_keychain
81
+ `#{commands.join(' ')}`
82
+ end
83
+
56
84
  def self.wwdr_certificate_installed?
57
85
  certificate_name = "Apple Worldwide Developer Relations Certification Authority"
58
86
  keychain = wwdr_keychain
@@ -1,5 +1,6 @@
1
1
  require_relative 'helper'
2
2
  require 'xcodeproj'
3
+ require 'fastlane_core/command_executor'
3
4
 
4
5
  module FastlaneCore
5
6
  # Represents an Xcode project
@@ -273,6 +274,10 @@ module FastlaneCore
273
274
  (framework? && build_settings(key: "PLATFORM_NAME") == "macosx")
274
275
  end
275
276
 
277
+ def supports_mac_catalyst?
278
+ build_settings(key: "SUPPORTS_MACCATALYST") == "YES"
279
+ end
280
+
276
281
  def command_line_tool?
277
282
  (build_settings(key: "PRODUCT_TYPE") == "com.apple.product-type.tool")
278
283
  end
@@ -313,6 +318,10 @@ module FastlaneCore
313
318
  proj << "-configuration #{options[:configuration].shellescape}" if options[:configuration]
314
319
  proj << "-xcconfig #{options[:xcconfig].shellescape}" if options[:xcconfig]
315
320
 
321
+ if FastlaneCore::Helper.xcode_at_least?('11.0') && options[:cloned_source_packages_path]
322
+ proj << "-clonedSourcePackagesDirPath #{options[:cloned_source_packages_path].shellescape}"
323
+ end
324
+
316
325
  return proj
317
326
  end
318
327
 
@@ -335,6 +344,12 @@ module FastlaneCore
335
344
  command
336
345
  end
337
346
 
347
+ def build_xcodebuild_resolvepackagedependencies_command
348
+ command = "xcodebuild -resolvePackageDependencies #{xcodebuild_parameters.join(' ')}"
349
+ command += " 2> /dev/null" if xcodebuild_suppress_stderr
350
+ command
351
+ end
352
+
338
353
  # Get the build settings for our project
339
354
  # e.g. to properly get the DerivedData folder
340
355
  # @param [String] The key of which we want the value for (e.g. "PRODUCT_NAME")
@@ -347,6 +362,14 @@ module FastlaneCore
347
362
  options[:scheme] ||= schemes.first
348
363
  end
349
364
 
365
+ # SwiftPM support
366
+ if FastlaneCore::Helper.xcode_at_least?('11.0')
367
+ UI.important("Resolving Swift Package Manager dependencies...")
368
+ FastlaneCore::CommandExecutor.execute(command: build_xcodebuild_resolvepackagedependencies_command,
369
+ print_all: true,
370
+ print_command: !self.xcodebuild_list_silent)
371
+ end
372
+
350
373
  command = build_xcodebuild_showbuildsettings_command
351
374
 
352
375
  # Xcode might hang here and retrying fixes the problem, see fastlane#4059
@@ -88,6 +88,13 @@ module Gym
88
88
  when "tvOS"
89
89
  destination_sdkroot = ["appletvos"]
90
90
  end
91
+
92
+ # Catalyst projects will always have an "iphoneos" sdkroot
93
+ # Need to force a same platform when trying to build as macos
94
+ if Gym.building_mac_catalyst_for_mac?
95
+ return true
96
+ end
97
+
91
98
  return destination_sdkroot.include?(sdkroot)
92
99
  end
93
100
 
@@ -134,10 +141,31 @@ module Gym
134
141
  next unless same_platform?(sdkroot)
135
142
  next unless specified_configuration == build_configuration.name
136
143
 
137
- bundle_identifier = build_configuration.resolve_build_setting("PRODUCT_BUNDLE_IDENTIFIER", target)
144
+ # Catalyst apps will have some build settings that will have a configuration
145
+ # that is specfic for macos so going to do our best to capture those
146
+ #
147
+ # There are other platform filters besides "[sdk=macosx*]" that we could use but
148
+ # this is the default that Xcode will use so this will also be our default
149
+ sdk_specifier = Gym.building_mac_catalyst_for_mac? ? "[sdk=macosx*]" : ""
150
+
151
+ # Look for sdk specific bundle identifier (if set) and fallback to general configuration if none
152
+ bundle_identifier = build_configuration.resolve_build_setting("PRODUCT_BUNDLE_IDENTIFIER#{sdk_specifier}", target)
153
+ bundle_identifier ||= build_configuration.resolve_build_setting("PRODUCT_BUNDLE_IDENTIFIER", target)
138
154
  next unless bundle_identifier
139
- provisioning_profile_specifier = build_configuration.resolve_build_setting("PROVISIONING_PROFILE_SPECIFIER", target)
140
- provisioning_profile_uuid = build_configuration.resolve_build_setting("PROVISIONING_PROFILE", target)
155
+
156
+ # Xcode prefixes "maccatalyst." if building a Catalyst app for mac and
157
+ # if DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER is set to YES
158
+ if Gym.building_mac_catalyst_for_mac? && build_configuration.resolve_build_setting("DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER", target) == "YES"
159
+ bundle_identifier = "maccatalyst.#{bundle_identifier}"
160
+ end
161
+
162
+ # Look for sdk specific provisioning profile specifier (if set) and fallback to general configuration if none
163
+ provisioning_profile_specifier = build_configuration.resolve_build_setting("PROVISIONING_PROFILE_SPECIFIER#{sdk_specifier}", target)
164
+ provisioning_profile_specifier ||= build_configuration.resolve_build_setting("PROVISIONING_PROFILE_SPECIFIER", target)
165
+
166
+ # Look for sdk specific provisioning profile uuid (if set) and fallback to general configuration if none
167
+ provisioning_profile_uuid = build_configuration.resolve_build_setting("PROVISIONING_PROFILE#{sdk_specifier}", target)
168
+ provisioning_profile_uuid ||= build_configuration.resolve_build_setting("PROVISIONING_PROFILE", target)
141
169
 
142
170
  has_profile_specifier = provisioning_profile_specifier.to_s.length > 0
143
171
  has_profile_uuid = provisioning_profile_uuid.to_s.length > 0
@@ -177,5 +205,6 @@ module Gym
177
205
 
178
206
  return provisioning_profile_mapping
179
207
  end
208
+ # rubocop:enable Metrics/PerceivedComplexity
180
209
  end
181
210
  end
@@ -33,6 +33,7 @@ module Gym
33
33
  detect_selected_provisioning_profiles # we can only do that *after* we have the platform
34
34
  detect_configuration
35
35
  detect_toolchain
36
+ detect_third_party_installer
36
37
 
37
38
  config[:output_name] ||= Gym.project.app_name
38
39
 
@@ -100,6 +101,38 @@ module Gym
100
101
  end
101
102
  end
102
103
 
104
+ # Detects name of a "3rd Party Mac Developer Installer" cert for the configured team id
105
+ def self.detect_third_party_installer
106
+ return if Gym.config[:installer_cert_name]
107
+
108
+ team_id = Gym.config[:export_team_id] || Gym.project.build_settings(key: "DEVELOPMENT_TEAM")
109
+ return if team_id.nil?
110
+
111
+ case Gym.config[:export_method]
112
+ when "app-store"
113
+ prefix = "3rd Party Mac Developer Installer: "
114
+ when "developer-id"
115
+ prefix = "Developer ID Installer: "
116
+ else
117
+ return
118
+ end
119
+
120
+ output = Helper.backticks("security find-certificate -a -c \"#{prefix}\"", print: false)
121
+
122
+ # Find matches, filter by team_id, prepend prefix for full cert name
123
+ certs = output.scan(/"(?:#{prefix})(.*)"/)
124
+ certs = certs.flatten.uniq.select do |cert|
125
+ cert.include?(team_id)
126
+ end.map do |cert|
127
+ prefix + cert
128
+ end
129
+
130
+ if certs.first
131
+ UI.verbose("Detected installer certificate to use: #{certs.first}")
132
+ Gym.config[:installer_cert_name] = certs.first
133
+ end
134
+ end
135
+
103
136
  def self.detect_scheme
104
137
  Gym.project.select_scheme
105
138
  end
@@ -111,14 +144,13 @@ module Gym
111
144
  # Is it an iOS device or a Mac?
112
145
  def self.detect_platform
113
146
  return if Gym.config[:destination]
114
- platform = if Gym.project.mac?
147
+ platform = if Gym.project.mac? || Gym.building_mac_catalyst_for_mac?
115
148
  min_xcode8? ? "macOS" : "OS X"
116
149
  elsif Gym.project.tvos?
117
150
  "tvOS"
118
151
  else
119
152
  "iOS"
120
153
  end
121
-
122
154
  Gym.config[:destination] = "generic/platform=#{platform}"
123
155
  end
124
156
 
@@ -25,6 +25,10 @@ module Gym
25
25
  generator.ipa_path
26
26
  end
27
27
 
28
+ def pkg_path
29
+ generator.pkg_path
30
+ end
31
+
28
32
  def dsym_path
29
33
  generator.dsym_path
30
34
  end
@@ -58,27 +58,53 @@ module Gym
58
58
  end
59
59
 
60
60
  def ipa_path
61
- unless Gym.cache[:ipa_path]
62
- path = Dir[File.join(temporary_output_path, "*.ipa")].last
63
- # We need to process generic IPA
64
- if path
65
- # Try to find IPA file in the output directory, used when app thinning was not set
66
- Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
67
- FileUtils.mv(path, Gym.cache[:ipa_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:ipa_path]).downcase).zero?
68
- elsif Dir.exist?(apps_path)
69
- # Try to find "generic" IPA file inside "Apps" folder, used when app thinning was set
70
- files = Dir[File.join(apps_path, "*.ipa")]
71
- # Generic IPA file doesn't have suffix so its name is the shortest
72
- path = files.min_by(&:length)
73
- Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
74
- FileUtils.cp(path, Gym.cache[:ipa_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:ipa_path]).downcase).zero?
75
- else
76
- ErrorHandler.handle_empty_archive unless path
77
- end
61
+ path = Gym.cache[:ipa_path]
62
+ return path if path
63
+
64
+ path = Dir[File.join(temporary_output_path, "*.ipa")].last
65
+ # We need to process generic IPA
66
+ if path
67
+ # Try to find IPA file in the output directory, used when app thinning was not set
68
+ Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
69
+ FileUtils.mv(path, Gym.cache[:ipa_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:ipa_path]).downcase).zero?
70
+ elsif Dir.exist?(apps_path)
71
+ # Try to find "generic" IPA file inside "Apps" folder, used when app thinning was set
72
+ files = Dir[File.join(apps_path, "*.ipa")]
73
+ # Generic IPA file doesn't have suffix so its name is the shortest
74
+ path = files.min_by(&:length)
75
+ Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
76
+ FileUtils.cp(path, Gym.cache[:ipa_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:ipa_path]).downcase).zero?
77
+ else
78
+ ErrorHandler.handle_empty_archive unless path
78
79
  end
80
+
79
81
  Gym.cache[:ipa_path]
80
82
  end
81
83
 
84
+ def pkg_path
85
+ path = Gym.cache[:pkg_path]
86
+ return path if path
87
+
88
+ path = Dir[File.join(temporary_output_path, "*.pkg")].last
89
+ # We need to process generic PKG
90
+ if path
91
+ # Try to find PKG file in the output directory, used when app thinning was not set
92
+ Gym.cache[:pkg_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.pkg")
93
+ FileUtils.mv(path, Gym.cache[:pkg_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:pkg_path]).downcase).zero?
94
+ elsif Dir.exist?(apps_path)
95
+ # Try to find "generic" PKG file inside "Apps" folder, used when app thinning was set
96
+ files = Dir[File.join(apps_path, "*.pkg")]
97
+ # Generic PKG file doesn't have suffix so its name is the shortest
98
+ path = files.min_by(&:length)
99
+ Gym.cache[:pkg_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.pkg")
100
+ FileUtils.cp(path, Gym.cache[:pkg_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:pkg_path]).downcase).zero?
101
+ else
102
+ ErrorHandler.handle_empty_archive unless path
103
+ end
104
+
105
+ Gym.cache[:pkg_path]
106
+ end
107
+
82
108
  # The path the the dsym file for this app. Might be nil
83
109
  def dsym_path
84
110
  Dir[BuildCommandGenerator.archive_path + "/**/*.app.dSYM"].last
@@ -160,6 +186,10 @@ module Gym
160
186
  hash[:signingStyle] = 'manual'
161
187
  end
162
188
 
189
+ if Gym.config[:installer_cert_name] && (Gym.project.mac? || Gym.building_mac_catalyst_for_mac?)
190
+ hash[:installerSigningCertificate] = Gym.config[:installer_cert_name]
191
+ end
192
+
163
193
  hash[:teamID] = Gym.config[:export_team_id] if Gym.config[:export_team_id]
164
194
 
165
195
  UI.important("Generated plist file with the following values:")