fastlane 2.139.0 → 2.144.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +85 -72
  4. data/cert/lib/cert/options.rb +12 -5
  5. data/cert/lib/cert/runner.rb +13 -0
  6. data/deliver/lib/deliver/options.rb +28 -2
  7. data/deliver/lib/deliver/runner.rb +13 -2
  8. data/fastlane/lib/fastlane/action.rb +1 -1
  9. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  10. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  11. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  12. data/fastlane/lib/fastlane/actions/README.md +2 -0
  13. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +13 -5
  14. data/fastlane/lib/fastlane/actions/automatic_code_signing.rb +7 -1
  15. data/fastlane/lib/fastlane/actions/build_app.rb +157 -6
  16. data/fastlane/lib/fastlane/actions/build_ios_app.rb +28 -132
  17. data/fastlane/lib/fastlane/actions/build_mac_app.rb +46 -0
  18. data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +3 -0
  19. data/fastlane/lib/fastlane/actions/cocoapods.rb +2 -2
  20. data/fastlane/lib/fastlane/actions/crashlytics.rb +14 -2
  21. data/fastlane/lib/fastlane/actions/create_pull_request.rb +29 -0
  22. data/fastlane/lib/fastlane/actions/docs/{build_ios_app.md → build_app.md} +1 -1
  23. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +22 -6
  24. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +22 -6
  25. data/fastlane/lib/fastlane/actions/ensure_git_branch.rb +1 -1
  26. data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +35 -7
  27. data/fastlane/lib/fastlane/actions/frame_screenshots.rb +2 -1
  28. data/fastlane/lib/fastlane/actions/get_github_release.rb +3 -0
  29. data/fastlane/lib/fastlane/actions/gradle.rb +43 -2
  30. data/fastlane/lib/fastlane/actions/gym.rb +3 -7
  31. data/fastlane/lib/fastlane/actions/import_from_git.rb +4 -0
  32. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +9 -3
  33. data/fastlane/lib/fastlane/actions/notarize.rb +183 -0
  34. data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +7 -1
  35. data/fastlane/lib/fastlane/actions/run_tests.rb +5 -22
  36. data/fastlane/lib/fastlane/actions/s3.rb +5 -291
  37. data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
  38. data/fastlane/lib/fastlane/actions/spm.rb +8 -0
  39. data/fastlane/lib/fastlane/actions/swiftlint.rb +45 -9
  40. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +190 -0
  41. data/fastlane/lib/fastlane/actions/update_plist.rb +37 -2
  42. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +13 -3
  43. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -0
  44. data/fastlane/lib/fastlane/fast_file.rb +13 -3
  45. data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
  46. data/fastlane/lib/fastlane/helper/s3_client_helper.rb +56 -0
  47. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +1 -1
  48. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
  49. data/fastlane/lib/fastlane/runner.rb +23 -18
  50. data/fastlane/lib/fastlane/server/socket_server_action_command_executor.rb +1 -1
  51. data/fastlane/lib/fastlane/version.rb +1 -1
  52. data/fastlane/swift/Deliverfile.swift +1 -1
  53. data/fastlane/swift/DeliverfileProtocol.swift +3 -3
  54. data/fastlane/swift/Fastlane.swift +422 -45
  55. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  56. data/fastlane/swift/Gymfile.swift +1 -1
  57. data/fastlane/swift/GymfileProtocol.swift +17 -1
  58. data/fastlane/swift/Matchfile.swift +1 -1
  59. data/fastlane/swift/MatchfileProtocol.swift +23 -3
  60. data/fastlane/swift/Precheckfile.swift +1 -1
  61. data/fastlane/swift/RubyCommand.swift +1 -1
  62. data/fastlane/swift/Scanfile.swift +1 -1
  63. data/fastlane/swift/ScanfileProtocol.swift +21 -1
  64. data/fastlane/swift/Screengrabfile.swift +1 -1
  65. data/fastlane/swift/Snapshotfile.swift +1 -1
  66. data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
  67. data/fastlane_core/lib/fastlane_core/cert_checker.rb +28 -0
  68. data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
  69. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +1 -0
  70. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +2 -0
  71. data/fastlane_core/lib/fastlane_core/project.rb +27 -0
  72. data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +15 -2
  73. data/frameit/lib/frameit/commands_generator.rb +25 -0
  74. data/frameit/lib/frameit/config_parser.rb +31 -9
  75. data/frameit/lib/frameit/device.rb +90 -0
  76. data/frameit/lib/frameit/device_types.rb +121 -5
  77. data/frameit/lib/frameit/editor.rb +28 -40
  78. data/frameit/lib/frameit/offsets.rb +8 -1
  79. data/frameit/lib/frameit/options.rb +81 -54
  80. data/frameit/lib/frameit/runner.rb +17 -7
  81. data/frameit/lib/frameit/screenshot.rb +35 -47
  82. data/frameit/lib/frameit/template_finder.rb +15 -12
  83. data/gym/lib/gym/code_signing_mapping.rb +32 -3
  84. data/gym/lib/gym/detect_values.rb +34 -2
  85. data/gym/lib/gym/generators/package_command_generator.rb +8 -0
  86. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +52 -17
  87. data/gym/lib/gym/module.rb +8 -0
  88. data/gym/lib/gym/options.rb +25 -1
  89. data/gym/lib/gym/runner.rb +70 -21
  90. data/match/lib/match/change_password.rb +1 -1
  91. data/match/lib/match/encryption.rb +4 -0
  92. data/match/lib/match/encryption/openssl.rb +1 -1
  93. data/match/lib/match/generator.rb +17 -3
  94. data/match/lib/match/importer.rb +35 -20
  95. data/match/lib/match/module.rb +5 -2
  96. data/match/lib/match/nuke.rb +59 -17
  97. data/match/lib/match/options.rb +38 -15
  98. data/match/lib/match/runner.rb +24 -8
  99. data/match/lib/match/setup.rb +1 -1
  100. data/match/lib/match/spaceship_ensure.rb +19 -9
  101. data/match/lib/match/storage.rb +4 -0
  102. data/match/lib/match/storage/git_storage.rb +5 -2
  103. data/match/lib/match/storage/google_cloud_storage.rb +2 -2
  104. data/match/lib/match/storage/s3_storage.rb +162 -0
  105. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  106. data/pilot/lib/pilot/build_manager.rb +24 -9
  107. data/scan/lib/scan/detect_values.rb +6 -1
  108. data/scan/lib/scan/manager.rb +18 -1
  109. data/scan/lib/scan/options.rb +28 -1
  110. data/scan/lib/scan/runner.rb +9 -7
  111. data/scan/lib/scan/slack_poster.rb +1 -1
  112. data/scan/lib/scan/test_command_generator.rb +12 -5
  113. data/screengrab/lib/screengrab/runner.rb +31 -18
  114. data/sigh/lib/sigh/.runner.rb.swp +0 -0
  115. data/snapshot/lib/snapshot/fixes/simulator_shared_pasteboard.rb +16 -0
  116. data/snapshot/lib/snapshot/options.rb +12 -1
  117. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  118. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +13 -0
  119. data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
  120. data/spaceship/lib/spaceship/connect_api/models/.bundle_id.rb.swp +0 -0
  121. data/{gym/lib/gym/.runner.rb.swp → spaceship/lib/spaceship/connect_api/models/.bundle_id_capability.rb.swp} +0 -0
  122. data/spaceship/lib/spaceship/connect_api/models/app.rb +11 -0
  123. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +4 -0
  124. data/spaceship/lib/spaceship/connect_api/models/build.rb +1 -2
  125. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -0
  126. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +29 -0
  127. data/spaceship/lib/spaceship/portal/app.rb +11 -2
  128. data/spaceship/lib/spaceship/tunes/app_version.rb +6 -1
  129. data/spaceship/lib/spaceship/tunes/iap.rb +11 -11
  130. data/spaceship/lib/spaceship/tunes/iap_detail.rb +7 -3
  131. data/spaceship/lib/spaceship/tunes/iap_families.rb +12 -1
  132. data/spaceship/lib/spaceship/tunes/iap_family_details.rb +26 -17
  133. data/spaceship/lib/spaceship/tunes/iap_status.rb +5 -1
  134. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  135. data/supply/lib/supply/client.rb +1 -1
  136. metadata +63 -18
@@ -2,23 +2,16 @@ require_relative 'spaceship_ensure'
2
2
  require_relative 'encryption'
3
3
  require_relative 'storage'
4
4
  require_relative 'module'
5
+ require 'fastlane_core/provisioning_profile'
5
6
  require 'fileutils'
6
7
 
7
8
  module Match
8
9
  class Importer
9
- def import_cert(params, cert_path: nil, p12_path: nil)
10
- # Get and verify cert and p12 path
11
- cert_path ||= UI.input("Certificate (.cer) path:")
12
- p12_path ||= UI.input("Private key (.p12) path:")
13
-
14
- cert_path = File.absolute_path(cert_path)
15
- p12_path = File.absolute_path(p12_path)
16
-
17
- UI.user_error!("Certificate does not exist at path: #{cert_path}") unless File.exist?(cert_path)
18
- UI.user_error!("Private key does not exist at path: #{p12_path}") unless File.exist?(p12_path)
19
-
20
- # Base64 encode contents to find match from API to find a cert ID
21
- cert_contents_base_64 = Base64.strict_encode64(File.open(cert_path).read)
10
+ def import_cert(params, cert_path: nil, p12_path: nil, profile_path: nil)
11
+ # Get and verify cert, p12 and profiles path
12
+ cert_path = ensure_valid_file_path(cert_path, "Certificate", ".cer")
13
+ p12_path = ensure_valid_file_path(p12_path, "Private key", ".p12")
14
+ profile_path = ensure_valid_file_path(profile_path, "Provisioning profile", ".mobileprovision or .provisionprofile", optional: true)
22
15
 
23
16
  # Storage
24
17
  storage = Storage.for_mode(params[:storage_mode], {
@@ -54,20 +47,23 @@ module Match
54
47
 
55
48
  case cert_type
56
49
  when :development
57
- certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT
50
+ certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT + "," + Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT
58
51
  when :distribution, :enterprise
59
- certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
52
+ certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION + "," + Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION
60
53
  else
61
54
  UI.user_error!("Cert type '#{cert_type}' is not supported")
62
55
  end
63
56
 
64
- output_dir = File.join(storage.prefixed_working_directory, "certs", cert_type.to_s)
57
+ output_dir_certs = File.join(storage.prefixed_working_directory, "certs", cert_type.to_s)
58
+ output_dir_profiles = File.join(storage.prefixed_working_directory, "profiles", cert_type.to_s)
65
59
 
66
60
  # Need to get the cert id by comparing base64 encoded cert content with certificate content from the API responses
67
61
  Spaceship::Portal.login(params[:username])
68
62
  Spaceship::Portal.select_team(team_id: params[:team_id], team_name: params[:team_name])
69
63
  certs = Spaceship::ConnectAPI::Certificate.all(filter: { certificateType: certificate_type })
70
64
 
65
+ # Base64 encode contents to find match from API to find a cert ID
66
+ cert_contents_base_64 = Base64.strict_encode64(File.binread(cert_path))
71
67
  matching_cert = certs.find do |cert|
72
68
  cert.certificate_content == cert_contents_base_64
73
69
  end
@@ -75,18 +71,37 @@ module Match
75
71
  UI.user_error!("This certificate cannot be imported - the certificate contents did not match with any available on the Developer Portal") if matching_cert.nil?
76
72
 
77
73
  # Make dir if doesn't exist
78
- FileUtils.mkdir_p(output_dir)
79
- dest_cert_path = File.join(output_dir, "#{matching_cert.id}.cer")
80
- dest_p12_path = File.join(output_dir, "#{matching_cert.id}.p12")
74
+ FileUtils.mkdir_p(output_dir_certs)
75
+ dest_cert_path = File.join(output_dir_certs, "#{matching_cert.id}.cer")
76
+ dest_p12_path = File.join(output_dir_certs, "#{matching_cert.id}.p12")
77
+
78
+ files_to_commit = [dest_cert_path, dest_p12_path]
81
79
 
82
80
  # Copy files
83
81
  IO.copy_stream(cert_path, dest_cert_path)
84
82
  IO.copy_stream(p12_path, dest_p12_path)
85
- files_to_commit = [dest_cert_path, dest_p12_path]
83
+ unless profile_path.nil?
84
+ FileUtils.mkdir_p(output_dir_profiles)
85
+ bundle_id = FastlaneCore::ProvisioningProfile.bundle_id(profile_path)
86
+ profile_extension = FastlaneCore::ProvisioningProfile.profile_extension(profile_path)
87
+ dest_profile_path = File.join(output_dir_profiles, "#{cert_type.to_s.capitalize}_#{bundle_id}#{profile_extension}")
88
+ files_to_commit.push(dest_profile_path)
89
+ IO.copy_stream(profile_path, dest_profile_path)
90
+ end
86
91
 
87
92
  # Encrypt and commit
88
93
  encryption.encrypt_files if encryption
89
94
  storage.save_changes!(files_to_commit: files_to_commit)
90
95
  end
96
+
97
+ def ensure_valid_file_path(file_path, file_description, file_extension, optional: false)
98
+ optional_file_message = optional ? " or leave empty to skip this file" : ""
99
+ file_path ||= UI.input("#{file_description} (#{file_extension}) path#{optional_file_message}:")
100
+
101
+ file_path = File.absolute_path(file_path) unless file_path == ""
102
+ file_path = File.exist?(file_path) ? file_path : nil
103
+ UI.user_error!("#{file_description} does not exist at path: #{file_path}") unless !file_path.nil? || optional
104
+ file_path
105
+ end
91
106
  end
92
107
  end
@@ -9,11 +9,11 @@ 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
16
- return %w(git google_cloud)
16
+ return %w(git google_cloud s3)
17
17
  end
18
18
 
19
19
  def self.profile_type_sym(type)
@@ -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)
@@ -37,7 +37,11 @@ module Match
37
37
  clone_branch_directly: params[:clone_branch_directly],
38
38
  google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
39
39
  google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
40
- google_cloud_project_id: params[:google_cloud_project_id].to_s
40
+ google_cloud_project_id: params[:google_cloud_project_id].to_s,
41
+ s3_region: params[:s3_region].to_s,
42
+ s3_access_key: params[:s3_access_key].to_s,
43
+ s3_secret_access_key: params[:s3_secret_access_key].to_s,
44
+ s3_bucket: params[:s3_bucket].to_s
41
45
  })
42
46
  self.storage.download
43
47
 
@@ -93,10 +97,11 @@ module Match
93
97
  def prepare_list
94
98
  UI.message("Fetching certificates and profiles...")
95
99
  cert_type = Match.cert_type_sym(type)
100
+ cert_types = [cert_type]
96
101
 
97
102
  prov_types = []
98
103
  prov_types = [:development] if cert_type == :development
99
- prov_types = [:appstore, :adhoc] if cert_type == :distribution
104
+ prov_types = [:appstore, :adhoc, :developer_id] if cert_type == :distribution
100
105
  prov_types = [:enterprise] if cert_type == :enterprise
101
106
 
102
107
  Spaceship.login(params[:username])
@@ -112,17 +117,39 @@ module Match
112
117
  UI.user_error!("Enterprise account nuke cancelled") unless UI.confirm("Do you really want to nuke your Enterprise account?")
113
118
  end
114
119
 
115
- self.certs = certificate_type(cert_type).flat_map(&:all)
120
+ # Get all iOS and macOS profile
116
121
  self.profiles = []
117
122
  prov_types.each do |prov_type|
118
- self.profiles += profile_type(prov_type).all
123
+ self.profiles += profile_type(prov_type).all(mac: false)
124
+ self.profiles += profile_type(prov_type).all(mac: true)
119
125
  end
120
126
 
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")]
127
+ # Gets the main and additional cert types
128
+ cert_types += (params[:additional_cert_types] || []).map do |ct|
129
+ Match.cert_type_sym(ct)
130
+ end
131
+
132
+ # Gets all the certs form the cert types
133
+ self.certs = []
134
+ self.certs += cert_types.map do |ct|
135
+ certificate_type(ct).flat_map do |cert|
136
+ cert.all(mac: false) + cert.all(mac: true)
137
+ end
138
+ end.flatten
139
+
140
+ # Finds all the .cer and .p12 files in the file storage
141
+ certs = []
142
+ keys = []
143
+ cert_types.each do |ct|
144
+ certs += Dir[File.join(self.storage.working_directory, "**", ct.to_s, "*.cer")]
145
+ keys += Dir[File.join(self.storage.working_directory, "**", ct.to_s, "*.p12")]
146
+ end
147
+
148
+ # Finds all the iOS and macOS profofiles in the file storage
123
149
  profiles = []
124
150
  prov_types.each do |prov_type|
125
151
  profiles += Dir[File.join(self.storage.working_directory, "**", prov_type.to_s, "*.mobileprovision")]
152
+ profiles += Dir[File.join(self.storage.working_directory, "**", prov_type.to_s, "*.provisionprofile")]
126
153
  end
127
154
 
128
155
  self.files = certs + keys + profiles
@@ -240,21 +267,36 @@ module Match
240
267
 
241
268
  # The kind of certificate we're interested in
242
269
  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}'"
270
+ case type.to_sym
271
+ when :mac_installer_distribution
272
+ return [Spaceship.certificate.mac_installer_distribution]
273
+ when :distribution
274
+ return [Spaceship.certificate.production, Spaceship.certificate.apple_distribution]
275
+ when :development
276
+ return [Spaceship.certificate.development, Spaceship.certificate.apple_development]
277
+ when :enterprise
278
+ return [Spaceship.certificate.in_house]
279
+ else
280
+ raise "Unknown type '#{type}'"
281
+ end
248
282
  end
249
283
 
250
284
  # The kind of provisioning profile we're interested in
251
285
  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}'"
286
+ case prov_type.to_sym
287
+ when :appstore
288
+ return Spaceship.provisioning_profile.app_store
289
+ when :development
290
+ return Spaceship.provisioning_profile.development
291
+ when :enterprise
292
+ return Spaceship.provisioning_profile.in_house
293
+ when :adhoc
294
+ return Spaceship.provisioning_profile.ad_hoc
295
+ when :developer_id
296
+ return Spaceship.provisioning_profile.direct
297
+ else
298
+ raise "Unknown provisioning type '#{prov_type}'"
299
+ end
258
300
  end
259
301
  end
260
302
  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",
@@ -153,6 +159,24 @@ module Match
153
159
  description: "ID of the Google Cloud project to use for authentication",
154
160
  optional: true),
155
161
 
162
+ # Storage: S3
163
+ FastlaneCore::ConfigItem.new(key: :s3_region,
164
+ env_name: "MATCH_S3_REGION",
165
+ description: "Name of the S3 region",
166
+ optional: true),
167
+ FastlaneCore::ConfigItem.new(key: :s3_access_key,
168
+ env_name: "MATCH_S3_ACCESS_KEY",
169
+ description: "S3 access key",
170
+ optional: true),
171
+ FastlaneCore::ConfigItem.new(key: :s3_secret_access_key,
172
+ env_name: "MATCH_S3_SECRET_ACCESS_KEY",
173
+ description: "S3 secret secret access key",
174
+ optional: true),
175
+ FastlaneCore::ConfigItem.new(key: :s3_bucket,
176
+ env_name: "MATCH_S3_BUCKET",
177
+ description: "Name of the S3 bucket",
178
+ optional: true),
179
+
156
180
  # Keychain
157
181
  FastlaneCore::ConfigItem.new(key: :keychain_name,
158
182
  short_option: "-s",
@@ -170,32 +194,31 @@ module Match
170
194
  FastlaneCore::ConfigItem.new(key: :force,
171
195
  env_name: "MATCH_FORCE",
172
196
  description: "Renew the provisioning profiles every time you run match",
173
- is_string: false,
197
+ type: Boolean,
174
198
  default_value: false),
175
199
  FastlaneCore::ConfigItem.new(key: :force_for_new_devices,
176
200
  env_name: "MATCH_FORCE_FOR_NEW_DEVICES",
177
201
  description: "Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile type 'appstore'",
178
- is_string: false,
202
+ type: Boolean,
179
203
  default_value: false),
180
204
  FastlaneCore::ConfigItem.new(key: :skip_confirmation,
181
205
  env_name: "MATCH_SKIP_CONFIRMATION",
182
206
  description: "Disables confirmation prompts during nuke, answering them with yes",
183
- is_string: false,
207
+ type: Boolean,
184
208
  default_value: false),
185
209
  FastlaneCore::ConfigItem.new(key: :skip_docs,
186
210
  env_name: "MATCH_SKIP_DOCS",
187
211
  description: "Skip generation of a README.md for the created git repository",
188
- is_string: false,
212
+ type: Boolean,
189
213
  default_value: false),
190
214
  FastlaneCore::ConfigItem.new(key: :platform,
191
215
  short_option: '-o',
192
216
  env_name: "MATCH_PLATFORM",
193
- description: "Set the provisioning profile's platform to work with (i.e. ios, tvos)",
194
- is_string: false,
217
+ description: "Set the provisioning profile's platform to work with (i.e. ios, tvos, macos)",
195
218
  default_value: "ios",
196
219
  verify_block: proc do |value|
197
220
  value = value.to_s
198
- pt = %w(tvos ios)
221
+ pt = %w(tvos ios macos)
199
222
  UI.user_error!("Unsupported platform, must be: #{pt}") unless pt.include?(value)
200
223
  end),
201
224
  FastlaneCore::ConfigItem.new(key: :template_name,
@@ -212,7 +235,7 @@ module Match
212
235
  FastlaneCore::ConfigItem.new(key: :verbose,
213
236
  env_name: "MATCH_VERBOSE",
214
237
  description: "Print out extra information and all commands",
215
- is_string: false,
238
+ type: Boolean,
216
239
  default_value: false,
217
240
  verify_block: proc do |value|
218
241
  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
 
@@ -45,6 +46,10 @@ module Match
45
46
  google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
46
47
  google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
47
48
  google_cloud_project_id: params[:google_cloud_project_id].to_s,
49
+ s3_region: params[:s3_region].to_s,
50
+ s3_access_key: params[:s3_access_key].to_s,
51
+ s3_secret_access_key: params[:s3_secret_access_key].to_s,
52
+ s3_bucket: params[:s3_bucket].to_s,
48
53
  readonly: params[:readonly],
49
54
  username: params[:readonly] ? nil : params[:username], # only pass username if not readonly
50
55
  team_id: params[:team_id],
@@ -79,13 +84,21 @@ module Match
79
84
  # Verify the App ID (as we don't want 'match' to fail at a later point)
80
85
  if spaceship
81
86
  app_identifiers.each do |app_identifier|
82
- spaceship.bundle_identifier_exists(username: params[:username], app_identifier: app_identifier)
87
+ spaceship.bundle_identifier_exists(username: params[:username], app_identifier: app_identifier, platform: params[:platform])
83
88
  end
84
89
  end
85
90
 
86
91
  # Certificate
87
92
  cert_id = fetch_certificate(params: params, working_directory: storage.working_directory)
88
- spaceship.certificate_exists(username: params[:username], certificate_id: cert_id) if spaceship
93
+
94
+ # Mac Installer Distribution Certificate
95
+ additional_cert_types = params[:additional_cert_types] || []
96
+ cert_ids = additional_cert_types.map do |additional_cert_type|
97
+ fetch_certificate(params: params, working_directory: storage.working_directory, specific_cert_type: additional_cert_type)
98
+ end
99
+
100
+ cert_ids << cert_id
101
+ spaceship.certificates_exists(username: params[:username], certificate_ids: cert_ids, platform: params[:platform]) if spaceship
89
102
 
90
103
  # Provisioning Profiles
91
104
  unless params[:skip_provisioning_profiles]
@@ -119,6 +132,7 @@ module Match
119
132
  ensure
120
133
  storage.clear_changes if storage
121
134
  end
135
+ # rubocop:enable Metrics/PerceivedComplexity
122
136
 
123
137
  # Used when creating a new certificate or profile
124
138
  def prefixed_working_directory
@@ -133,8 +147,8 @@ module Match
133
147
  end
134
148
  end
135
149
 
136
- def fetch_certificate(params: nil, working_directory: nil)
137
- cert_type = Match.cert_type_sym(params[:type])
150
+ def fetch_certificate(params: nil, working_directory: nil, specific_cert_type: nil)
151
+ cert_type = Match.cert_type_sym(specific_cert_type || params[:type])
138
152
 
139
153
  certs = Dir[File.join(prefixed_working_directory, "certs", cert_type.to_s, "*.cer")]
140
154
  keys = Dir[File.join(prefixed_working_directory, "certs", cert_type.to_s, "*.p12")]
@@ -142,7 +156,7 @@ module Match
142
156
  if certs.count == 0 || keys.count == 0
143
157
  UI.important("Couldn't find a valid code signing identity for #{cert_type}... creating one for you now")
144
158
  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)
159
+ cert_path = Generator.generate_certificate(params, cert_type, prefixed_working_directory, specific_cert_type: specific_cert_type)
146
160
  private_key_path = cert_path.gsub(".cer", ".p12")
147
161
 
148
162
  self.files_to_commit << cert_path
@@ -196,13 +210,15 @@ module Match
196
210
  prov_type = Match.profile_type_sym(params[:type])
197
211
 
198
212
  names = [Match::Generator.profile_type_name(prov_type), app_identifier]
199
- if params[:platform].to_s != :ios.to_s
213
+ if params[:platform].to_s == :tvos.to_s
200
214
  names.push(params[:platform])
201
215
  end
202
216
 
203
217
  profile_name = names.join("_").gsub("*", '\*') # this is important, as it shouldn't be a wildcard
204
218
  base_dir = File.join(prefixed_working_directory, "profiles", prov_type.to_s)
205
- profiles = Dir[File.join(base_dir, "#{profile_name}.mobileprovision")]
219
+
220
+ extension = params[:platform].to_s == :macos.to_s ? ".provisionprofile" : ".mobileprovision"
221
+ profiles = Dir[File.join(base_dir, "#{profile_name}#{extension}")]
206
222
  if Helper.mac?
207
223
  keychain_path = FastlaneCore::Helper.keychain_path(params[:keychain_name]) unless params[:keychain_name].nil?
208
224
  end
@@ -254,7 +270,7 @@ module Match
254
270
  FileUtils.cp(profile, params[:output_path])
255
271
  end
256
272
 
257
- if spaceship && !spaceship.profile_exists(username: params[:username], uuid: uuid)
273
+ if spaceship && !spaceship.profile_exists(username: params[:username], uuid: uuid, platform: params[:platform])
258
274
  # This profile is invalid, let's remove the local file and generate a new one
259
275
  File.delete(profile)
260
276
  # This method will be called again, no need to modify `files_to_commit`