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
@@ -24,6 +24,14 @@ module Gym
24
24
  # Import all the fixes
25
25
  require 'gym/xcodebuild_fixes/generic_archive_fix'
26
26
  end
27
+
28
+ def building_mac_catalyst_for_ios?
29
+ Gym.project.supports_mac_catalyst? && Gym.config[:catalyst_platform] == "ios"
30
+ end
31
+
32
+ def building_mac_catalyst_for_mac?
33
+ Gym.project.supports_mac_catalyst? && Gym.config[:catalyst_platform] == "macos"
34
+ end
27
35
  end
28
36
 
29
37
  Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
@@ -85,6 +85,11 @@ module Gym
85
85
  description: "Should we skip packaging the ipa?",
86
86
  type: Boolean,
87
87
  default_value: false),
88
+ FastlaneCore::ConfigItem.new(key: :skip_package_pkg,
89
+ env_name: "GYM_SKIP_PACKAGE_PKG",
90
+ description: "Should we skip packaging the pkg?",
91
+ type: Boolean,
92
+ default_value: false),
88
93
  FastlaneCore::ConfigItem.new(key: :include_symbols,
89
94
  short_option: "-m",
90
95
  env_name: "GYM_INCLUDE_SYMBOLS",
@@ -139,6 +144,20 @@ module Gym
139
144
  description: "Build without codesigning",
140
145
  type: Boolean,
141
146
  optional: true),
147
+ FastlaneCore::ConfigItem.new(key: :catalyst_platform,
148
+ env_name: "GYM_CATALYST_PLATFORM",
149
+ description: "Platform to build when using a Catalyst enabled app. Valid values are: ios, macos",
150
+ type: String,
151
+ optional: true,
152
+ verify_block: proc do |value|
153
+ av = %w(ios macos)
154
+ UI.user_error!("Unsupported export_method '#{value}', must be: #{av}") unless av.include?(value)
155
+ end),
156
+ FastlaneCore::ConfigItem.new(key: :installer_cert_name,
157
+ env_name: "GYM_INSTALLER_CERT_NAME",
158
+ description: "Full name of 3rd Party Mac Developer Installer or Deveoper ID Installer certificate. Example: `3rd Party Mac Developer Installer: Your Company (ABC1234XWYZ)`",
159
+ type: String,
160
+ optional: true),
142
161
  # Very optional
143
162
  FastlaneCore::ConfigItem.new(key: :build_path,
144
163
  env_name: "GYM_BUILD_PATH",
@@ -255,7 +274,12 @@ module Gym
255
274
  description: "Do not try to build a profile mapping from the xcodeproj. Match or a manually provided mapping should be used",
256
275
  optional: true,
257
276
  type: Boolean,
258
- default_value: false)
277
+ default_value: false),
278
+ FastlaneCore::ConfigItem.new(key: :cloned_source_packages_path,
279
+ env_name: "GYM_CLONED_SOURCE_PACKAGES_PATH",
280
+ description: "Sets a custom path for Swift Package Manager dependencies",
281
+ type: String,
282
+ optional: true)
259
283
  ]
260
284
  end
261
285
  end
@@ -23,7 +23,12 @@ module Gym
23
23
 
24
24
  FileUtils.mkdir_p(File.expand_path(Gym.config[:output_directory]))
25
25
 
26
- if Gym.project.ios? || Gym.project.tvos?
26
+ # Determine platform to archive
27
+ is_mac = Gym.project.mac? || Gym.building_mac_catalyst_for_mac?
28
+ is_ios = !is_mac && (Gym.project.ios? || Gym.project.tvos?)
29
+
30
+ # Archive
31
+ if is_ios
27
32
  fix_generic_archive # See https://github.com/fastlane/fastlane/pull/4325
28
33
  return BuildCommandGenerator.archive_path if Gym.config[:skip_package_ipa]
29
34
 
@@ -34,11 +39,15 @@ module Gym
34
39
  move_app_thinning
35
40
  move_app_thinning_size_report
36
41
  move_apps_folder
37
- elsif Gym.project.mac?
42
+ elsif is_mac
38
43
  path = File.expand_path(Gym.config[:output_directory])
39
44
  compress_and_move_dsym
40
- if Gym.project.mac_app?
41
- copy_mac_app
45
+ if Gym.project.mac_app? || Gym.building_mac_catalyst_for_mac?
46
+ path = copy_mac_app
47
+ return path if Gym.config[:skip_package_pkg]
48
+
49
+ package_app
50
+ path = move_pkg
42
51
  return path
43
52
  end
44
53
  copy_files_from_path(File.join(BuildCommandGenerator.archive_path, "Products/usr/local/bin/*")) if Gym.project.command_line_tool?
@@ -226,6 +235,17 @@ module Gym
226
235
  ipa_path
227
236
  end
228
237
 
238
+ # Moves over the binary and dsym file to the output directory
239
+ # @return (String) The path to the resulting pkg file
240
+ def move_pkg
241
+ FileUtils.mv(PackageCommandGenerator.pkg_path, File.expand_path(Gym.config[:output_directory]), force: true)
242
+ pkg_path = File.expand_path(File.join(Gym.config[:output_directory], File.basename(PackageCommandGenerator.pkg_path)))
243
+
244
+ UI.success("Successfully exported and signed the pkg file:")
245
+ UI.message(pkg_path)
246
+ pkg_path
247
+ end
248
+
229
249
  # copys framework from temp folder:
230
250
 
231
251
  def copy_files_from_path(path)
@@ -248,6 +268,7 @@ module Gym
248
268
  def copy_mac_app
249
269
  exe_name = Gym.project.build_settings(key: "EXECUTABLE_NAME")
250
270
  app_path = File.join(BuildCommandGenerator.archive_path, "Products/Applications/#{exe_name}.app")
271
+
251
272
  UI.crash!("Couldn't find application in '#{BuildCommandGenerator.archive_path}'") unless File.exist?(app_path)
252
273
  FileUtils.cp_r(app_path, File.expand_path(Gym.config[:output_directory]), remove_destination: true)
253
274
  app_path = File.join(Gym.config[:output_directory], File.basename(app_path))
@@ -71,7 +71,7 @@ module Match
71
71
  private
72
72
 
73
73
  def iterate(source_path)
74
- Dir[File.join(source_path, "**", "*.{cer,p12,mobileprovision}")].each do |path|
74
+ Dir[File.join(source_path, "**", "*.{cer,p12,mobileprovision,provisionprofile}")].each do |path|
75
75
  next if File.directory?(path)
76
76
  yield(path)
77
77
  end
@@ -3,14 +3,20 @@ require_relative 'module'
3
3
  module Match
4
4
  # Generate missing resources
5
5
  class Generator
6
- def self.generate_certificate(params, cert_type, working_directory)
6
+ def self.generate_certificate(params, cert_type, working_directory, specific_cert_type: nil)
7
7
  require 'cert/runner'
8
8
  require 'cert/options'
9
9
 
10
10
  output_path = File.join(working_directory, "certs", cert_type.to_s)
11
11
 
12
+ # Mapping match option to cert option for "Developer ID Application"
13
+ if cert_type.to_sym == :developer_id_application
14
+ specific_cert_type = cert_type.to_s
15
+ end
16
+
12
17
  arguments = FastlaneCore::Configuration.create(Cert::Options.available_options, {
13
18
  development: params[:type] == "development",
19
+ type: specific_cert_type,
14
20
  generate_apple_certs: params[:generate_apple_certs],
15
21
  output_path: output_path,
16
22
  force: true, # we don't need a certificate without its private key, we only care about a new certificate
@@ -70,8 +76,15 @@ module Match
70
76
  }
71
77
 
72
78
  values[:platform] = params[:platform]
73
- values[:adhoc] = true if prov_type == :adhoc
74
- values[:development] = true if prov_type == :development
79
+
80
+ # These options are all conflicting so can only set one
81
+ if params[:type] == "developer_id"
82
+ values[:developer_id] = true
83
+ elsif prov_type == :adhoc
84
+ values[:adhoc] = true
85
+ elsif prov_type == :development
86
+ values[:development] = true
87
+ end
75
88
 
76
89
  arguments = FastlaneCore::Configuration.create(Sigh::Options.available_options, values)
77
90
 
@@ -82,6 +95,7 @@ module Match
82
95
 
83
96
  # @return the name of the provisioning profile type
84
97
  def self.profile_type_name(type)
98
+ return "Direct" if type == :developer_id
85
99
  return "Development" if type == :development
86
100
  return "AdHoc" if type == :adhoc
87
101
  return "AppStore" if type == :appstore
@@ -9,7 +9,7 @@ module Match
9
9
  DESCRIPTION = "Easily sync your certificates and profiles across your team"
10
10
 
11
11
  def self.environments
12
- return %w(appstore adhoc development enterprise)
12
+ return %w(appstore adhoc development enterprise developer_id)
13
13
  end
14
14
 
15
15
  def self.storage_modes
@@ -21,6 +21,9 @@ module Match
21
21
  end
22
22
 
23
23
  def self.cert_type_sym(type)
24
+ return :mac_installer_distribution if type == "mac_installer_distribution"
25
+ return :developer_id_installer if type == "developer_id_installer"
26
+ return :developer_id_application if type == "developer_id"
24
27
  return :enterprise if type == "enterprise"
25
28
  return :development if type == "development"
26
29
  return :distribution if ["adhoc", "appstore", "distribution"].include?(type)
@@ -93,10 +93,11 @@ module Match
93
93
  def prepare_list
94
94
  UI.message("Fetching certificates and profiles...")
95
95
  cert_type = Match.cert_type_sym(type)
96
+ cert_types = [cert_type]
96
97
 
97
98
  prov_types = []
98
99
  prov_types = [:development] if cert_type == :development
99
- prov_types = [:appstore, :adhoc] if cert_type == :distribution
100
+ prov_types = [:appstore, :adhoc, :developer_id] if cert_type == :distribution
100
101
  prov_types = [:enterprise] if cert_type == :enterprise
101
102
 
102
103
  Spaceship.login(params[:username])
@@ -112,17 +113,39 @@ module Match
112
113
  UI.user_error!("Enterprise account nuke cancelled") unless UI.confirm("Do you really want to nuke your Enterprise account?")
113
114
  end
114
115
 
115
- self.certs = certificate_type(cert_type).flat_map(&:all)
116
+ # Get all iOS and macOS profile
116
117
  self.profiles = []
117
118
  prov_types.each do |prov_type|
118
- self.profiles += profile_type(prov_type).all
119
+ self.profiles += profile_type(prov_type).all(mac: false)
120
+ self.profiles += profile_type(prov_type).all(mac: true)
119
121
  end
120
122
 
121
- certs = Dir[File.join(self.storage.working_directory, "**", cert_type.to_s, "*.cer")]
122
- keys = Dir[File.join(self.storage.working_directory, "**", cert_type.to_s, "*.p12")]
123
+ # Gets the main and additional cert types
124
+ cert_types += (params[:additional_cert_types] || []).map do |ct|
125
+ Match.cert_type_sym(ct)
126
+ end
127
+
128
+ # Gets all the certs form the cert types
129
+ self.certs = []
130
+ self.certs += cert_types.map do |ct|
131
+ certificate_type(ct).flat_map do |cert|
132
+ cert.all(mac: false) + cert.all(mac: true)
133
+ end
134
+ end.flatten
135
+
136
+ # Finds all the .cer and .p12 files in the file storage
137
+ certs = []
138
+ keys = []
139
+ cert_types.each do |ct|
140
+ certs += Dir[File.join(self.storage.working_directory, "**", ct.to_s, "*.cer")]
141
+ keys += Dir[File.join(self.storage.working_directory, "**", ct.to_s, "*.p12")]
142
+ end
143
+
144
+ # Finds all the iOS and macOS profofiles in the file storage
123
145
  profiles = []
124
146
  prov_types.each do |prov_type|
125
147
  profiles += Dir[File.join(self.storage.working_directory, "**", prov_type.to_s, "*.mobileprovision")]
148
+ profiles += Dir[File.join(self.storage.working_directory, "**", prov_type.to_s, "*.provisionprofile")]
126
149
  end
127
150
 
128
151
  self.files = certs + keys + profiles
@@ -240,21 +263,36 @@ module Match
240
263
 
241
264
  # The kind of certificate we're interested in
242
265
  def certificate_type(type)
243
- {
244
- distribution: [Spaceship.certificate.production, Spaceship.certificate.apple_distribution],
245
- development: [Spaceship.certificate.development, Spaceship.certificate.apple_development],
246
- enterprise: [Spaceship.certificate.in_house]
247
- }[type] ||= raise "Unknown type '#{type}'"
266
+ case type.to_sym
267
+ when :mac_installer_distribution
268
+ return [Spaceship.certificate.mac_installer_distribution]
269
+ when :distribution
270
+ return [Spaceship.certificate.production, Spaceship.certificate.apple_distribution]
271
+ when :development
272
+ return [Spaceship.certificate.development, Spaceship.certificate.apple_development]
273
+ when :enterprise
274
+ return [Spaceship.certificate.in_house]
275
+ else
276
+ raise "Unknown type '#{type}'"
277
+ end
248
278
  end
249
279
 
250
280
  # The kind of provisioning profile we're interested in
251
281
  def profile_type(prov_type)
252
- {
253
- appstore: Spaceship.provisioning_profile.app_store,
254
- development: Spaceship.provisioning_profile.development,
255
- enterprise: Spaceship.provisioning_profile.in_house,
256
- adhoc: Spaceship.provisioning_profile.ad_hoc
257
- }[prov_type] ||= raise "Unknown provisioning type '#{prov_type}'"
282
+ case prov_type.to_sym
283
+ when :appstore
284
+ return Spaceship.provisioning_profile.app_store
285
+ when :development
286
+ return Spaceship.provisioning_profile.development
287
+ when :enterprise
288
+ return Spaceship.provisioning_profile.in_house
289
+ when :adhoc
290
+ return Spaceship.provisioning_profile.ad_hoc
291
+ when :developer_id
292
+ return Spaceship.provisioning_profile.direct
293
+ else
294
+ raise "Unknown provisioning type '#{prov_type}'"
295
+ end
258
296
  end
259
297
  end
260
298
  end
@@ -19,7 +19,6 @@ module Match
19
19
  FastlaneCore::ConfigItem.new(key: :type,
20
20
  env_name: "MATCH_TYPE",
21
21
  description: "Define the profile type, can be #{Match.environments.join(', ')}",
22
- is_string: true,
23
22
  short_option: "-y",
24
23
  default_value: 'development',
25
24
  verify_block: proc do |value|
@@ -27,10 +26,19 @@ module Match
27
26
  UI.user_error!("Unsupported environment #{value}, must be in #{Match.environments.join(', ')}")
28
27
  end
29
28
  end),
29
+ FastlaneCore::ConfigItem.new(key: :additional_cert_types,
30
+ env_name: "MATCH_ADDITIONAL_CERT_TYPES",
31
+ description: "Create additional cert types needed for macOS installers (valid values: mac_installer_distribution, developer_id_installer)",
32
+ optional: true,
33
+ type: Array,
34
+ verify_block: proc do |values|
35
+ types = %w(mac_installer_distribution developer_id_installer)
36
+ UI.user_error!("Unsupported types, must be: #{types}") unless (values - types).empty?
37
+ end),
30
38
  FastlaneCore::ConfigItem.new(key: :readonly,
31
39
  env_name: "MATCH_READONLY",
32
40
  description: "Only fetch existing certificates and profiles, don't generate new ones",
33
- is_string: false,
41
+ type: Boolean,
34
42
  default_value: false),
35
43
  FastlaneCore::ConfigItem.new(key: :generate_apple_certs,
36
44
  env_name: "MATCH_GENERATE_APPLE_CERTS",
@@ -41,7 +49,7 @@ module Match
41
49
  FastlaneCore::ConfigItem.new(key: :skip_provisioning_profiles,
42
50
  env_name: "MATCH_SKIP_PROVISIONING_PROFILES",
43
51
  description: "Skip syncing provisioning profiles",
44
- is_string: false,
52
+ type: Boolean,
45
53
  default_value: false),
46
54
 
47
55
  # app
@@ -49,7 +57,6 @@ module Match
49
57
  short_option: "-a",
50
58
  env_name: "MATCH_APP_IDENTIFIER",
51
59
  description: "The bundle identifier(s) of your app (comma-separated)",
52
- is_string: false,
53
60
  type: Array, # we actually allow String and Array here
54
61
  skip_type_validation: true,
55
62
  code_gen_sensitive: true,
@@ -82,7 +89,6 @@ module Match
82
89
  FastlaneCore::ConfigItem.new(key: :storage_mode,
83
90
  env_name: "MATCH_STORAGE_MODE",
84
91
  description: "Define where you want to store your certificates",
85
- is_string: true,
86
92
  short_option: "-q",
87
93
  default_value: 'git',
88
94
  verify_block: proc do |value|
@@ -114,12 +120,12 @@ module Match
114
120
  FastlaneCore::ConfigItem.new(key: :shallow_clone,
115
121
  env_name: "MATCH_SHALLOW_CLONE",
116
122
  description: "Make a shallow clone of the repository (truncate the history to 1 revision)",
117
- is_string: false,
123
+ type: Boolean,
118
124
  default_value: false),
119
125
  FastlaneCore::ConfigItem.new(key: :clone_branch_directly,
120
126
  env_name: "MATCH_CLONE_BRANCH_DIRECTLY",
121
127
  description: "Clone just the branch specified, instead of the whole repo. This requires that the branch already exists. Otherwise the command will fail",
122
- is_string: false,
128
+ type: Boolean,
123
129
  default_value: false),
124
130
  FastlaneCore::ConfigItem.new(key: :git_basic_authorization,
125
131
  env_name: "MATCH_GIT_BASIC_AUTHORIZATION",
@@ -170,32 +176,31 @@ module Match
170
176
  FastlaneCore::ConfigItem.new(key: :force,
171
177
  env_name: "MATCH_FORCE",
172
178
  description: "Renew the provisioning profiles every time you run match",
173
- is_string: false,
179
+ type: Boolean,
174
180
  default_value: false),
175
181
  FastlaneCore::ConfigItem.new(key: :force_for_new_devices,
176
182
  env_name: "MATCH_FORCE_FOR_NEW_DEVICES",
177
183
  description: "Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile type 'appstore'",
178
- is_string: false,
184
+ type: Boolean,
179
185
  default_value: false),
180
186
  FastlaneCore::ConfigItem.new(key: :skip_confirmation,
181
187
  env_name: "MATCH_SKIP_CONFIRMATION",
182
188
  description: "Disables confirmation prompts during nuke, answering them with yes",
183
- is_string: false,
189
+ type: Boolean,
184
190
  default_value: false),
185
191
  FastlaneCore::ConfigItem.new(key: :skip_docs,
186
192
  env_name: "MATCH_SKIP_DOCS",
187
193
  description: "Skip generation of a README.md for the created git repository",
188
- is_string: false,
194
+ type: Boolean,
189
195
  default_value: false),
190
196
  FastlaneCore::ConfigItem.new(key: :platform,
191
197
  short_option: '-o',
192
198
  env_name: "MATCH_PLATFORM",
193
- description: "Set the provisioning profile's platform to work with (i.e. ios, tvos)",
194
- is_string: false,
199
+ description: "Set the provisioning profile's platform to work with (i.e. ios, tvos, macos)",
195
200
  default_value: "ios",
196
201
  verify_block: proc do |value|
197
202
  value = value.to_s
198
- pt = %w(tvos ios)
203
+ pt = %w(tvos ios macos)
199
204
  UI.user_error!("Unsupported platform, must be: #{pt}") unless pt.include?(value)
200
205
  end),
201
206
  FastlaneCore::ConfigItem.new(key: :template_name,
@@ -212,7 +217,7 @@ module Match
212
217
  FastlaneCore::ConfigItem.new(key: :verbose,
213
218
  env_name: "MATCH_VERBOSE",
214
219
  description: "Print out extra information and all commands",
215
- is_string: false,
220
+ type: Boolean,
216
221
  default_value: false,
217
222
  verify_block: proc do |value|
218
223
  FastlaneCore::Globals.verbose = true if value
@@ -18,6 +18,7 @@ module Match
18
18
 
19
19
  attr_accessor :storage
20
20
 
21
+ # rubocop:disable Metrics/PerceivedComplexity
21
22
  def run(params)
22
23
  self.files_to_commit = []
23
24
 
@@ -79,13 +80,21 @@ module Match
79
80
  # Verify the App ID (as we don't want 'match' to fail at a later point)
80
81
  if spaceship
81
82
  app_identifiers.each do |app_identifier|
82
- spaceship.bundle_identifier_exists(username: params[:username], app_identifier: app_identifier)
83
+ spaceship.bundle_identifier_exists(username: params[:username], app_identifier: app_identifier, platform: params[:platform])
83
84
  end
84
85
  end
85
86
 
86
87
  # Certificate
87
88
  cert_id = fetch_certificate(params: params, working_directory: storage.working_directory)
88
- spaceship.certificate_exists(username: params[:username], certificate_id: cert_id) if spaceship
89
+
90
+ # Mac Installer Distribution Certificate
91
+ additional_cert_types = params[:additional_cert_types] || []
92
+ cert_ids = additional_cert_types.map do |additional_cert_type|
93
+ fetch_certificate(params: params, working_directory: storage.working_directory, specific_cert_type: additional_cert_type)
94
+ end
95
+
96
+ cert_ids << cert_id
97
+ spaceship.certificates_exists(username: params[:username], certificate_ids: cert_ids, platform: params[:platform]) if spaceship
89
98
 
90
99
  # Provisioning Profiles
91
100
  unless params[:skip_provisioning_profiles]
@@ -119,6 +128,7 @@ module Match
119
128
  ensure
120
129
  storage.clear_changes if storage
121
130
  end
131
+ # rubocop:enable Metrics/PerceivedComplexity
122
132
 
123
133
  # Used when creating a new certificate or profile
124
134
  def prefixed_working_directory
@@ -133,8 +143,8 @@ module Match
133
143
  end
134
144
  end
135
145
 
136
- def fetch_certificate(params: nil, working_directory: nil)
137
- cert_type = Match.cert_type_sym(params[:type])
146
+ def fetch_certificate(params: nil, working_directory: nil, specific_cert_type: nil)
147
+ cert_type = Match.cert_type_sym(specific_cert_type || params[:type])
138
148
 
139
149
  certs = Dir[File.join(prefixed_working_directory, "certs", cert_type.to_s, "*.cer")]
140
150
  keys = Dir[File.join(prefixed_working_directory, "certs", cert_type.to_s, "*.p12")]
@@ -142,7 +152,7 @@ module Match
142
152
  if certs.count == 0 || keys.count == 0
143
153
  UI.important("Couldn't find a valid code signing identity for #{cert_type}... creating one for you now")
144
154
  UI.crash!("No code signing identity found and can not create a new one because you enabled `readonly`") if params[:readonly]
145
- cert_path = Generator.generate_certificate(params, cert_type, prefixed_working_directory)
155
+ cert_path = Generator.generate_certificate(params, cert_type, prefixed_working_directory, specific_cert_type: specific_cert_type)
146
156
  private_key_path = cert_path.gsub(".cer", ".p12")
147
157
 
148
158
  self.files_to_commit << cert_path
@@ -196,13 +206,15 @@ module Match
196
206
  prov_type = Match.profile_type_sym(params[:type])
197
207
 
198
208
  names = [Match::Generator.profile_type_name(prov_type), app_identifier]
199
- if params[:platform].to_s != :ios.to_s
209
+ if params[:platform].to_s == :tvos.to_s
200
210
  names.push(params[:platform])
201
211
  end
202
212
 
203
213
  profile_name = names.join("_").gsub("*", '\*') # this is important, as it shouldn't be a wildcard
204
214
  base_dir = File.join(prefixed_working_directory, "profiles", prov_type.to_s)
205
- profiles = Dir[File.join(base_dir, "#{profile_name}.mobileprovision")]
215
+
216
+ extension = params[:platform].to_s == :macos.to_s ? ".provisionprofile" : ".mobileprovision"
217
+ profiles = Dir[File.join(base_dir, "#{profile_name}#{extension}")]
206
218
  if Helper.mac?
207
219
  keychain_path = FastlaneCore::Helper.keychain_path(params[:keychain_name]) unless params[:keychain_name].nil?
208
220
  end
@@ -254,7 +266,7 @@ module Match
254
266
  FileUtils.cp(profile, params[:output_path])
255
267
  end
256
268
 
257
- if spaceship && !spaceship.profile_exists(username: params[:username], uuid: uuid)
269
+ if spaceship && !spaceship.profile_exists(username: params[:username], uuid: uuid, platform: params[:platform])
258
270
  # This profile is invalid, let's remove the local file and generate a new one
259
271
  File.delete(profile)
260
272
  # This method will be called again, no need to modify `files_to_commit`