fastlane 2.138.0 → 2.143.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +75 -62
  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 +2 -2
  7. data/deliver/lib/deliver/runner.rb +13 -2
  8. data/deliver/lib/deliver/submit_for_review.rb +7 -1
  9. data/fastlane/lib/fastlane/action.rb +2 -2
  10. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  11. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  12. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  13. data/fastlane/lib/fastlane/actions/README.md +2 -0
  14. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +13 -5
  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/cocoapods.rb +2 -2
  19. data/fastlane/lib/fastlane/actions/create_pull_request.rb +71 -2
  20. data/fastlane/lib/fastlane/actions/docs/{build_ios_app.md → build_app.md} +1 -1
  21. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +22 -6
  22. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +20 -4
  23. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +10 -0
  24. data/fastlane/lib/fastlane/actions/ensure_git_branch.rb +1 -1
  25. data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +35 -7
  26. data/fastlane/lib/fastlane/actions/frame_screenshots.rb +2 -1
  27. data/fastlane/lib/fastlane/actions/get_github_release.rb +3 -0
  28. data/fastlane/lib/fastlane/actions/gradle.rb +43 -2
  29. data/fastlane/lib/fastlane/actions/gym.rb +3 -7
  30. data/fastlane/lib/fastlane/actions/import_from_git.rb +4 -0
  31. data/fastlane/lib/fastlane/actions/last_git_tag.rb +14 -5
  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/run_tests.rb +5 -22
  35. data/fastlane/lib/fastlane/actions/s3.rb +5 -291
  36. data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
  37. data/fastlane/lib/fastlane/actions/setup_ci.rb +14 -8
  38. data/fastlane/lib/fastlane/actions/spm.rb +8 -0
  39. data/fastlane/lib/fastlane/actions/swiftlint.rb +17 -2
  40. data/fastlane/lib/fastlane/actions/update_plist.rb +37 -2
  41. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +13 -3
  42. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -0
  43. data/fastlane/lib/fastlane/actions/upload_to_play_store_internal_app_sharing.rb +78 -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 +429 -50
  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/build_watcher.rb +6 -2
  68. data/fastlane_core/lib/fastlane_core/cert_checker.rb +28 -0
  69. data/fastlane_core/lib/fastlane_core/device_manager.rb +20 -0
  70. data/fastlane_core/lib/fastlane_core/helper.rb +7 -1
  71. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +1 -0
  72. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +2 -0
  73. data/fastlane_core/lib/fastlane_core/project.rb +27 -0
  74. data/frameit/lib/frameit/commands_generator.rb +25 -0
  75. data/frameit/lib/frameit/config_parser.rb +31 -9
  76. data/frameit/lib/frameit/device.rb +90 -0
  77. data/frameit/lib/frameit/device_types.rb +121 -5
  78. data/frameit/lib/frameit/editor.rb +31 -40
  79. data/frameit/lib/frameit/offsets.rb +8 -1
  80. data/frameit/lib/frameit/options.rb +81 -54
  81. data/frameit/lib/frameit/runner.rb +17 -7
  82. data/frameit/lib/frameit/screenshot.rb +35 -47
  83. data/frameit/lib/frameit/template_finder.rb +15 -12
  84. data/gym/lib/gym/code_signing_mapping.rb +32 -3
  85. data/gym/lib/gym/detect_values.rb +34 -2
  86. data/gym/lib/gym/generators/build_command_generator.rb +1 -0
  87. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  88. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +47 -17
  89. data/gym/lib/gym/module.rb +8 -0
  90. data/gym/lib/gym/options.rb +25 -1
  91. data/gym/lib/gym/runner.rb +64 -24
  92. data/match/lib/match/change_password.rb +1 -1
  93. data/match/lib/match/encryption.rb +4 -0
  94. data/match/lib/match/encryption/openssl.rb +1 -1
  95. data/match/lib/match/generator.rb +17 -3
  96. data/match/lib/match/importer.rb +2 -2
  97. data/match/lib/match/module.rb +5 -2
  98. data/match/lib/match/nuke.rb +59 -17
  99. data/match/lib/match/options.rb +38 -15
  100. data/match/lib/match/runner.rb +24 -8
  101. data/match/lib/match/setup.rb +1 -1
  102. data/match/lib/match/spaceship_ensure.rb +19 -9
  103. data/match/lib/match/storage.rb +4 -0
  104. data/match/lib/match/storage/git_storage.rb +5 -2
  105. data/match/lib/match/storage/google_cloud_storage.rb +2 -2
  106. data/match/lib/match/storage/s3_storage.rb +162 -0
  107. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  108. data/pilot/lib/pilot/build_manager.rb +55 -15
  109. data/pilot/lib/pilot/options.rb +3 -1
  110. data/scan/lib/scan/detect_values.rb +6 -1
  111. data/scan/lib/scan/manager.rb +18 -1
  112. data/scan/lib/scan/options.rb +28 -1
  113. data/scan/lib/scan/runner.rb +11 -3
  114. data/scan/lib/scan/slack_poster.rb +1 -1
  115. data/scan/lib/scan/test_command_generator.rb +9 -5
  116. data/screengrab/lib/screengrab/runner.rb +31 -18
  117. data/snapshot/lib/snapshot/fixes/simulator_shared_pasteboard.rb +16 -0
  118. data/snapshot/lib/snapshot/options.rb +12 -1
  119. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  120. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +13 -0
  121. data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
  122. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +4 -0
  123. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -0
  124. data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +5 -0
  125. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -0
  126. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +6 -0
  127. data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
  128. data/spaceship/lib/spaceship/portal/app.rb +11 -2
  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 +26 -0
  136. data/supply/lib/supply/uploader.rb +28 -0
  137. metadata +64 -20
@@ -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`
@@ -34,7 +34,7 @@ module Match
34
34
  end
35
35
 
36
36
  def storage_options
37
- return ["git", "google_cloud"]
37
+ return ["git", "google_cloud", "s3"]
38
38
  end
39
39
  end
40
40
  end
@@ -28,8 +28,8 @@ module Match
28
28
  return Spaceship.client.team_id
29
29
  end
30
30
 
31
- def bundle_identifier_exists(username: nil, app_identifier: nil)
32
- found = Spaceship.app.find(app_identifier)
31
+ def bundle_identifier_exists(username: nil, app_identifier: nil, platform: nil)
32
+ found = Spaceship.app.find(app_identifier, mac: platform == "macos")
33
33
  return if found
34
34
 
35
35
  require 'sigh/runner'
@@ -45,24 +45,34 @@ module Match
45
45
  UI.user_error!("Couldn't find bundle identifier '#{app_identifier}' for the user '#{username}'")
46
46
  end
47
47
 
48
- def certificate_exists(username: nil, certificate_id: nil)
49
- found = Spaceship.certificate.all.find do |cert|
50
- cert.id == certificate_id
48
+ def certificates_exists(username: nil, certificate_ids: [], platform: nil)
49
+ Spaceship.certificate.all(mac: platform == "macos").each do |cert|
50
+ certificate_ids.delete(cert.id)
51
51
  end
52
- return if found
52
+ return if certificate_ids.empty?
53
53
 
54
- UI.error("Certificate '#{certificate_id}' (stored in your storage) is not available on the Developer Portal")
54
+ certificate_ids.each do |certificate_id|
55
+ UI.error("Certificate '#{certificate_id}' (stored in your storage) is not available on the Developer Portal")
56
+ end
55
57
  UI.error("for the user #{username}")
56
58
  UI.error("Make sure to use the same user and team every time you run 'match' for this")
57
59
  UI.error("Git repository. This might be caused by revoking the certificate on the Dev Portal")
58
60
  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/")
59
61
  end
60
62
 
61
- def profile_exists(username: nil, uuid: nil)
62
- found = Spaceship.provisioning_profile.all.find do |profile|
63
+ def profile_exists(username: nil, uuid: nil, platform: nil)
64
+ is_mac = platform == "macos"
65
+ found = Spaceship.provisioning_profile.all(mac: is_mac).find do |profile|
63
66
  profile.uuid == uuid
64
67
  end
65
68
 
69
+ # Look for iOS after looking for macOS (needed for Catalyst apps)
70
+ if !found && is_mac
71
+ found = Spaceship.provisioning_profile.all(mac: false).find do |profile|
72
+ profile.uuid == uuid
73
+ end
74
+ end
75
+
66
76
  unless found
67
77
  UI.error("Provisioning profile '#{uuid}' is not available on the Developer Portal for the user #{username}, fixing this now for you 🔨")
68
78
  return false
@@ -1,6 +1,7 @@
1
1
  require_relative 'storage/interface'
2
2
  require_relative 'storage/git_storage'
3
3
  require_relative 'storage/google_cloud_storage'
4
+ require_relative 'storage/s3_storage'
4
5
 
5
6
  module Match
6
7
  module Storage
@@ -12,6 +13,9 @@ module Match
12
13
  },
13
14
  "google_cloud" => lambda { |params|
14
15
  return Storage::GoogleCloudStorage.configure(params)
16
+ },
17
+ "s3" => lambda { |params|
18
+ return Storage::S3Storage.configure(params)
15
19
  }
16
20
  }
17
21
  end