fastlane 2.226.0 → 2.227.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +96 -96
  3. data/cert/lib/cert/options.rb +7 -2
  4. data/cert/lib/cert/runner.rb +23 -11
  5. data/deliver/lib/deliver/options.rb +1 -1
  6. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +1 -1
  7. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +1 -1
  8. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +1 -1
  9. data/fastlane/lib/fastlane/actions/notarize.rb +4 -0
  10. data/fastlane/lib/fastlane/actions/onesignal.rb +1 -1
  11. data/fastlane/lib/fastlane/actions/setup_ci.rb +14 -4
  12. data/fastlane/lib/fastlane/actions/testfairy.rb +5 -2
  13. data/fastlane/lib/fastlane/actions/unlock_keychain.rb +6 -1
  14. data/fastlane/lib/fastlane/version.rb +1 -1
  15. data/fastlane/swift/Actions.swift +1 -1
  16. data/fastlane/swift/Appfile.swift +1 -1
  17. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  18. data/fastlane/swift/Atomic.swift +1 -1
  19. data/fastlane/swift/ControlCommand.swift +1 -1
  20. data/fastlane/swift/Deliverfile.swift +2 -2
  21. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  22. data/fastlane/swift/Fastlane.swift +20 -10
  23. data/fastlane/swift/Gymfile.swift +2 -2
  24. data/fastlane/swift/GymfileProtocol.swift +2 -2
  25. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  26. data/fastlane/swift/MainProcess.swift +1 -1
  27. data/fastlane/swift/Matchfile.swift +2 -2
  28. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  29. data/fastlane/swift/OptionalConfigValue.swift +1 -1
  30. data/fastlane/swift/Plugins.swift +1 -1
  31. data/fastlane/swift/Precheckfile.swift +2 -2
  32. data/fastlane/swift/PrecheckfileProtocol.swift +2 -2
  33. data/fastlane/swift/RubyCommand.swift +1 -1
  34. data/fastlane/swift/RubyCommandable.swift +1 -1
  35. data/fastlane/swift/Runner.swift +1 -1
  36. data/fastlane/swift/RunnerArgument.swift +1 -1
  37. data/fastlane/swift/Scanfile.swift +2 -2
  38. data/fastlane/swift/ScanfileProtocol.swift +2 -2
  39. data/fastlane/swift/Screengrabfile.swift +2 -2
  40. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  41. data/fastlane/swift/Snapshotfile.swift +2 -2
  42. data/fastlane/swift/SnapshotfileProtocol.swift +2 -2
  43. data/fastlane/swift/SocketClient.swift +1 -1
  44. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  45. data/fastlane/swift/SocketResponse.swift +1 -1
  46. data/fastlane/swift/main.swift +1 -1
  47. data/fastlane_core/lib/fastlane_core/helper.rb +6 -1
  48. data/match/lib/assets/READMETemplate.md +2 -2
  49. data/match/lib/match/generator.rb +2 -2
  50. data/match/lib/match/runner.rb +1 -1
  51. data/precheck/lib/precheck/options.rb +1 -1
  52. data/produce/lib/produce/options.rb +1 -1
  53. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +1 -0
  54. data/supply/lib/supply/uploader.rb +19 -12
  55. data/trainer/lib/trainer/legacy_xcresult.rb +586 -0
  56. data/trainer/lib/trainer/options.rb +5 -0
  57. data/trainer/lib/trainer/plist_test_summary_parser.rb +84 -0
  58. data/trainer/lib/trainer/test_parser.rb +12 -293
  59. data/trainer/lib/trainer/xcresult/helper.rb +53 -0
  60. data/trainer/lib/trainer/xcresult/repetition.rb +39 -0
  61. data/trainer/lib/trainer/xcresult/test_case.rb +221 -0
  62. data/trainer/lib/trainer/xcresult/test_case_attributes.rb +49 -0
  63. data/trainer/lib/trainer/xcresult/test_plan.rb +91 -0
  64. data/trainer/lib/trainer/xcresult/test_suite.rb +134 -0
  65. data/trainer/lib/trainer/xcresult.rb +31 -388
  66. data/trainer/lib/trainer.rb +3 -1
  67. metadata +29 -21
@@ -1,398 +1,41 @@
1
- module Trainer
2
- module XCResult
3
- # Model attributes and relationships taken from running the following command:
4
- # xcrun xcresulttool formatDescription
5
-
6
- class AbstractObject
7
- attr_accessor :type
8
- def initialize(data)
9
- self.type = data["_type"]["_name"]
10
- end
11
-
12
- def fetch_value(data, key)
13
- return (data[key] || {})["_value"]
14
- end
15
-
16
- def fetch_values(data, key)
17
- return (data[key] || {})["_values"] || []
18
- end
19
- end
20
-
21
- # - ActionTestPlanRunSummaries
22
- # * Kind: object
23
- # * Properties:
24
- # + summaries: [ActionTestPlanRunSummary]
25
- class ActionTestPlanRunSummaries < AbstractObject
26
- attr_accessor :summaries
27
- def initialize(data)
28
- self.summaries = fetch_values(data, "summaries").map do |summary_data|
29
- ActionTestPlanRunSummary.new(summary_data)
30
- end
31
- super
32
- end
33
- end
34
-
35
- # - ActionAbstractTestSummary
36
- # * Kind: object
37
- # * Properties:
38
- # + name: String?
39
- class ActionAbstractTestSummary < AbstractObject
40
- attr_accessor :name
41
- def initialize(data)
42
- self.name = fetch_value(data, "name")
43
- super
44
- end
45
- end
46
-
47
- # - ActionTestPlanRunSummary
48
- # * Supertype: ActionAbstractTestSummary
49
- # * Kind: object
50
- # * Properties:
51
- # + testableSummaries: [ActionTestableSummary]
52
- class ActionTestPlanRunSummary < ActionAbstractTestSummary
53
- attr_accessor :testable_summaries
54
- def initialize(data)
55
- self.testable_summaries = fetch_values(data, "testableSummaries").map do |summary_data|
56
- ActionTestableSummary.new(summary_data)
57
- end
58
- super
59
- end
60
- end
61
-
62
- # - ActionTestableSummary
63
- # * Supertype: ActionAbstractTestSummary
64
- # * Kind: object
65
- # * Properties:
66
- # + projectRelativePath: String?
67
- # + targetName: String?
68
- # + testKind: String?
69
- # + tests: [ActionTestSummaryIdentifiableObject]
70
- # + diagnosticsDirectoryName: String?
71
- # + failureSummaries: [ActionTestFailureSummary]
72
- # + testLanguage: String?
73
- # + testRegion: String?
74
- class ActionTestableSummary < ActionAbstractTestSummary
75
- attr_accessor :project_relative_path
76
- attr_accessor :target_name
77
- attr_accessor :test_kind
78
- attr_accessor :tests
79
- def initialize(data)
80
- self.project_relative_path = fetch_value(data, "projectRelativePath")
81
- self.target_name = fetch_value(data, "targetName")
82
- self.test_kind = fetch_value(data, "testKind")
83
- self.tests = fetch_values(data, "tests").map do |tests_data|
84
- ActionTestSummaryIdentifiableObject.create(tests_data, self)
85
- end
86
- super
87
- end
88
-
89
- def all_tests
90
- return tests.map(&:all_subtests).flatten
91
- end
92
- end
93
-
94
- # - ActionTestSummaryIdentifiableObject
95
- # * Supertype: ActionAbstractTestSummary
96
- # * Kind: object
97
- # * Properties:
98
- # + identifier: String?
99
- class ActionTestSummaryIdentifiableObject < ActionAbstractTestSummary
100
- attr_accessor :identifier
101
- attr_accessor :parent
102
- def initialize(data, parent)
103
- self.identifier = fetch_value(data, "identifier")
104
- self.parent = parent
105
- super(data)
106
- end
107
-
108
- def all_subtests
109
- raise "Not overridden"
110
- end
111
-
112
- def self.create(data, parent)
113
- type = data["_type"]["_name"]
114
- if type == "ActionTestSummaryGroup"
115
- return ActionTestSummaryGroup.new(data, parent)
116
- elsif type == "ActionTestMetadata"
117
- return ActionTestMetadata.new(data, parent)
118
- else
119
- raise "Unsupported type: #{type}"
120
- end
121
- end
122
- end
123
-
124
- # - ActionTestSummaryGroup
125
- # * Supertype: ActionTestSummaryIdentifiableObject
126
- # * Kind: object
127
- # * Properties:
128
- # + duration: Double
129
- # + subtests: [ActionTestSummaryIdentifiableObject]
130
- class ActionTestSummaryGroup < ActionTestSummaryIdentifiableObject
131
- attr_accessor :duration
132
- attr_accessor :subtests
133
- def initialize(data, parent)
134
- self.duration = fetch_value(data, "duration").to_f
135
- self.subtests = fetch_values(data, "subtests").map do |subtests_data|
136
- ActionTestSummaryIdentifiableObject.create(subtests_data, self)
137
- end
138
- super(data, parent)
139
- end
140
-
141
- def all_subtests
142
- return subtests.map(&:all_subtests).flatten
143
- end
144
- end
1
+ require 'json'
2
+ require 'open3'
145
3
 
146
- # - ActionTestMetadata
147
- # * Supertype: ActionTestSummaryIdentifiableObject
148
- # * Kind: object
149
- # * Properties:
150
- # + testStatus: String
151
- # + duration: Double?
152
- # + summaryRef: Reference?
153
- # + performanceMetricsCount: Int
154
- # + failureSummariesCount: Int
155
- # + activitySummariesCount: Int
156
- class ActionTestMetadata < ActionTestSummaryIdentifiableObject
157
- attr_accessor :test_status
158
- attr_accessor :duration
159
- attr_accessor :performance_metrics_count
160
- attr_accessor :failure_summaries_count
161
- attr_accessor :activity_summaries_count
162
- def initialize(data, parent)
163
- self.test_status = fetch_value(data, "testStatus")
164
- self.duration = fetch_value(data, "duration").to_f
165
- self.performance_metrics_count = fetch_value(data, "performanceMetricsCount")
166
- self.failure_summaries_count = fetch_value(data, "failureSummariesCount")
167
- self.activity_summaries_count = fetch_value(data, "activitySummariesCount")
168
- super(data, parent)
169
- end
170
-
171
- def all_subtests
172
- return [self]
173
- end
4
+ require_relative 'xcresult/helper'
5
+ require_relative 'xcresult/test_case_attributes'
6
+ require_relative 'xcresult/repetition'
7
+ require_relative 'xcresult/test_case'
8
+ require_relative 'xcresult/test_suite'
9
+ require_relative 'xcresult/test_plan'
174
10
 
175
- def find_failure(failures)
176
- sanitizer = proc { |name| name.gsub(/\W/, "_") }
177
- sanitized_identifier = sanitizer.call(self.identifier)
178
- if self.test_status == "Failure"
179
- # Tries to match failure on test case name
180
- # Example TestFailureIssueSummary:
181
- # producingTarget: "TestThisDude"
182
- # test_case_name: "TestThisDude.testFailureJosh2()" (when Swift)
183
- # or "-[TestThisDudeTests testFailureJosh2]" (when Objective-C)
184
- # Example ActionTestMetadata
185
- # identifier: "TestThisDude/testFailureJosh2()" (when Swift)
186
- # or identifier: "TestThisDude/testFailureJosh2" (when Objective-C)
187
-
188
- found_failure = failures.find do |failure|
189
- # Sanitize both test case name and identifier in a consistent fashion, then replace all non-word
190
- # chars with underscore, and compare them
191
- sanitized_test_case_name = sanitizer.call(failure.test_case_name)
192
- sanitized_identifier == sanitized_test_case_name
11
+ module Trainer
12
+ # Model xcresulttool JSON output for Xcode16+ version of xcresulttool
13
+ # See JSON schema from `xcrun xcresulttool get test-results tests --help`
14
+ module XCResult
15
+ module Parser
16
+ class << self
17
+ # Parses an xcresult file and returns a TestPlan object
18
+ #
19
+ # @param path [String] The path to the xcresult file
20
+ # @param output_remove_retry_attempts [Boolean] Whether to remove retry attempts from the output
21
+ # @return [TestPlan] A TestPlan object containing the test results
22
+ def parse_xcresult(path:, output_remove_retry_attempts: false)
23
+ json = xcresult_to_json(path)
24
+
25
+ TestPlan.from_json(
26
+ json: json
27
+ ).tap do |test_plan|
28
+ test_plan.output_remove_retry_attempts = output_remove_retry_attempts
193
29
  end
194
- return found_failure
195
- else
196
- return nil
197
- end
198
- end
199
- end
200
-
201
- # - ActionsInvocationRecord
202
- # * Kind: object
203
- # * Properties:
204
- # + metadataRef: Reference?
205
- # + metrics: ResultMetrics
206
- # + issues: ResultIssueSummaries
207
- # + actions: [ActionRecord]
208
- # + archive: ArchiveInfo?
209
- class ActionsInvocationRecord < AbstractObject
210
- attr_accessor :actions
211
- attr_accessor :issues
212
- def initialize(data)
213
- self.actions = fetch_values(data, "actions").map do |action_data|
214
- ActionRecord.new(action_data)
215
- end
216
- self.issues = ResultIssueSummaries.new(data["issues"])
217
- super
218
- end
219
- end
220
-
221
- # - ActionRecord
222
- # * Kind: object
223
- # * Properties:
224
- # + schemeCommandName: String
225
- # + schemeTaskName: String
226
- # + title: String?
227
- # + startedTime: Date
228
- # + endedTime: Date
229
- # + runDestination: ActionRunDestinationRecord
230
- # + buildResult: ActionResult
231
- # + actionResult: ActionResult
232
- class ActionRecord < AbstractObject
233
- attr_accessor :scheme_command_name
234
- attr_accessor :scheme_task_name
235
- attr_accessor :title
236
- attr_accessor :build_result
237
- attr_accessor :action_result
238
- def initialize(data)
239
- self.scheme_command_name = fetch_value(data, "schemeCommandName")
240
- self.scheme_task_name = fetch_value(data, "schemeTaskName")
241
- self.title = fetch_value(data, "title")
242
- self.build_result = ActionResult.new(data["buildResult"])
243
- self.action_result = ActionResult.new(data["actionResult"])
244
- super
245
- end
246
- end
247
-
248
- # - ActionResult
249
- # * Kind: object
250
- # * Properties:
251
- # + resultName: String
252
- # + status: String
253
- # + metrics: ResultMetrics
254
- # + issues: ResultIssueSummaries
255
- # + coverage: CodeCoverageInfo
256
- # + timelineRef: Reference?
257
- # + logRef: Reference?
258
- # + testsRef: Reference?
259
- # + diagnosticsRef: Reference?
260
- class ActionResult < AbstractObject
261
- attr_accessor :result_name
262
- attr_accessor :status
263
- attr_accessor :issues
264
- attr_accessor :timeline_ref
265
- attr_accessor :log_ref
266
- attr_accessor :tests_ref
267
- attr_accessor :diagnostics_ref
268
- def initialize(data)
269
- self.result_name = fetch_value(data, "resultName")
270
- self.status = fetch_value(data, "status")
271
- self.issues = ResultIssueSummaries.new(data["issues"])
272
-
273
- self.timeline_ref = Reference.new(data["timelineRef"]) if data["timelineRef"]
274
- self.log_ref = Reference.new(data["logRef"]) if data["logRef"]
275
- self.tests_ref = Reference.new(data["testsRef"]) if data["testsRef"]
276
- self.diagnostics_ref = Reference.new(data["diagnosticsRef"]) if data["diagnosticsRef"]
277
- super
278
- end
279
- end
280
-
281
- # - Reference
282
- # * Kind: object
283
- # * Properties:
284
- # + id: String
285
- # + targetType: TypeDefinition?
286
- class Reference < AbstractObject
287
- attr_accessor :id
288
- attr_accessor :target_type
289
- def initialize(data)
290
- self.id = fetch_value(data, "id")
291
- self.target_type = TypeDefinition.new(data["targetType"]) if data["targetType"]
292
- super
293
- end
294
- end
295
-
296
- # - TypeDefinition
297
- # * Kind: object
298
- # * Properties:
299
- # + name: String
300
- # + supertype: TypeDefinition?
301
- class TypeDefinition < AbstractObject
302
- attr_accessor :name
303
- attr_accessor :supertype
304
- def initialize(data)
305
- self.name = fetch_value(data, "name")
306
- self.supertype = TypeDefinition.new(data["supertype"]) if data["supertype"]
307
- super
308
- end
309
- end
310
-
311
- # - DocumentLocation
312
- # * Kind: object
313
- # * Properties:
314
- # + url: String
315
- # + concreteTypeName: String
316
- class DocumentLocation < AbstractObject
317
- attr_accessor :url
318
- attr_accessor :concrete_type_name
319
- def initialize(data)
320
- self.url = fetch_value(data, "url")
321
- self.concrete_type_name = data["concreteTypeName"]["_value"]
322
- super
323
- end
324
- end
325
-
326
- # - IssueSummary
327
- # * Kind: object
328
- # * Properties:
329
- # + issueType: String
330
- # + message: String
331
- # + producingTarget: String?
332
- # + documentLocationInCreatingWorkspace: DocumentLocation?
333
- class IssueSummary < AbstractObject
334
- attr_accessor :issue_type
335
- attr_accessor :message
336
- attr_accessor :producing_target
337
- attr_accessor :document_location_in_creating_workspace
338
- def initialize(data)
339
- self.issue_type = fetch_value(data, "issueType")
340
- self.message = fetch_value(data, "message")
341
- self.producing_target = fetch_value(data, "producingTarget")
342
- self.document_location_in_creating_workspace = DocumentLocation.new(data["documentLocationInCreatingWorkspace"]) if data["documentLocationInCreatingWorkspace"]
343
- super
344
- end
345
- end
346
-
347
- # - ResultIssueSummaries
348
- # * Kind: object
349
- # * Properties:
350
- # + analyzerWarningSummaries: [IssueSummary]
351
- # + errorSummaries: [IssueSummary]
352
- # + testFailureSummaries: [TestFailureIssueSummary]
353
- # + warningSummaries: [IssueSummary]
354
- class ResultIssueSummaries < AbstractObject
355
- attr_accessor :analyzer_warning_summaries
356
- attr_accessor :error_summaries
357
- attr_accessor :test_failure_summaries
358
- attr_accessor :warning_summaries
359
- def initialize(data)
360
- self.analyzer_warning_summaries = fetch_values(data, "analyzerWarningSummaries").map do |summary_data|
361
- IssueSummary.new(summary_data)
362
- end
363
- self.error_summaries = fetch_values(data, "errorSummaries").map do |summary_data|
364
- IssueSummary.new(summary_data)
365
- end
366
- self.test_failure_summaries = fetch_values(data, "testFailureSummaries").map do |summary_data|
367
- TestFailureIssueSummary.new(summary_data)
368
30
  end
369
- self.warning_summaries = fetch_values(data, "warningSummaries").map do |summary_data|
370
- IssueSummary.new(summary_data)
371
- end
372
- super
373
- end
374
- end
375
31
 
376
- # - TestFailureIssueSummary
377
- # * Supertype: IssueSummary
378
- # * Kind: object
379
- # * Properties:
380
- # + testCaseName: String
381
- class TestFailureIssueSummary < IssueSummary
382
- attr_accessor :test_case_name
383
- def initialize(data)
384
- self.test_case_name = fetch_value(data, "testCaseName")
385
- super
386
- end
32
+ private
387
33
 
388
- def failure_message
389
- new_message = self.message
390
- if self.document_location_in_creating_workspace&.url
391
- file_path = self.document_location_in_creating_workspace.url.gsub("file://", "")
392
- new_message += " (#{file_path})"
34
+ def xcresult_to_json(path)
35
+ stdout, stderr, status = Open3.capture3('xcrun', 'xcresulttool', 'get', 'test-results', 'tests', '--path', path)
36
+ raise "Failed to execute xcresulttool command - #{stderr}" unless status.success?
37
+ JSON.parse(stdout)
393
38
  end
394
-
395
- return new_message
396
39
  end
397
40
  end
398
41
  end
@@ -2,6 +2,8 @@ require 'fastlane'
2
2
 
3
3
  require 'trainer/options'
4
4
  require 'trainer/test_parser'
5
- require 'trainer/junit_generator'
6
5
  require 'trainer/xcresult'
6
+ require 'trainer/junit_generator'
7
+ require 'trainer/legacy_xcresult'
8
+ require 'trainer/plist_test_summary_parser'
7
9
  require 'trainer/module'
metadata CHANGED
@@ -1,39 +1,39 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.226.0
4
+ version: 2.227.0
5
5
  platform: ruby
6
6
  authors:
7
- - Roger Oba
8
- - Luka Mirosevic
9
- - Daniel Jankowski
10
- - Max Ott
11
- - Joshua Liebowitz
7
+ - Maksym Grebenets
8
+ - Felix Krause
9
+ - Matthew Ellis
10
+ - Stefan Natchev
11
+ - Iulian Onofrei
12
+ - Aaron Brager
13
+ - Helmut Januschka
14
+ - Jimmy Dee
12
15
  - Jorge Revuelta H
13
- - Łukasz Grabowski
14
16
  - Danielle Tomlinson
15
- - Aaron Brager
17
+ - Olivier Halligon
18
+ - Luka Mirosevic
19
+ - Manu Wallner
16
20
  - Jan Piotrowski
17
- - Iulian Onofrei
21
+ - Joshua Liebowitz
22
+ - Fumiya Nakamura
18
23
  - Kohki Miki
19
- - Maksym Grebenets
20
- - Stefan Natchev
24
+ - Łukasz Grabowski
21
25
  - Andrew McBurney
22
- - Jimmy Dee
23
- - Matthew Ellis
24
- - Satoshi Namai
25
- - Felix Krause
26
- - Helmut Januschka
27
- - Manish Rathi
28
- - Fumiya Nakamura
29
26
  - Josh Holtz
27
+ - Roger Oba
28
+ - Max Ott
29
+ - Daniel Jankowski
30
+ - Manish Rathi
30
31
  - Jérôme Lacoste
31
- - Manu Wallner
32
- - Olivier Halligon
32
+ - Satoshi Namai
33
33
  autorequire:
34
34
  bindir: bin
35
35
  cert_chain: []
36
- date: 2024-12-10 00:00:00.000000000 Z
36
+ date: 2025-03-13 00:00:00.000000000 Z
37
37
  dependencies:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: addressable
@@ -1662,10 +1662,18 @@ files:
1662
1662
  - trainer/lib/trainer.rb
1663
1663
  - trainer/lib/trainer/commands_generator.rb
1664
1664
  - trainer/lib/trainer/junit_generator.rb
1665
+ - trainer/lib/trainer/legacy_xcresult.rb
1665
1666
  - trainer/lib/trainer/module.rb
1666
1667
  - trainer/lib/trainer/options.rb
1668
+ - trainer/lib/trainer/plist_test_summary_parser.rb
1667
1669
  - trainer/lib/trainer/test_parser.rb
1668
1670
  - trainer/lib/trainer/xcresult.rb
1671
+ - trainer/lib/trainer/xcresult/helper.rb
1672
+ - trainer/lib/trainer/xcresult/repetition.rb
1673
+ - trainer/lib/trainer/xcresult/test_case.rb
1674
+ - trainer/lib/trainer/xcresult/test_case_attributes.rb
1675
+ - trainer/lib/trainer/xcresult/test_plan.rb
1676
+ - trainer/lib/trainer/xcresult/test_suite.rb
1669
1677
  homepage: https://fastlane.tools
1670
1678
  licenses:
1671
1679
  - MIT