fastlane 2.170.0 → 2.175.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 (134) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +74 -74
  3. data/cert/lib/cert/options.rb +2 -2
  4. data/deliver/lib/deliver/app_screenshot.rb +5 -7
  5. data/deliver/lib/deliver/app_screenshot_validator.rb +108 -0
  6. data/deliver/lib/deliver/commands_generator.rb +1 -1
  7. data/deliver/lib/deliver/loader.rb +13 -29
  8. data/deliver/lib/deliver/options.rb +2 -2
  9. data/deliver/lib/deliver/setup.rb +8 -3
  10. data/deliver/lib/deliver/upload_metadata.rb +2 -0
  11. data/deliver/lib/deliver/upload_screenshots.rb +2 -1
  12. data/fastlane/lib/fastlane/actions/adb.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/add_git_tag.rb +12 -3
  14. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +2 -2
  15. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +1 -0
  16. data/fastlane/lib/fastlane/actions/appetize.rb +13 -1
  17. data/fastlane/lib/fastlane/actions/artifactory.rb +36 -3
  18. data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +10 -2
  19. data/fastlane/lib/fastlane/actions/build_app.rb +3 -1
  20. data/fastlane/lib/fastlane/actions/carthage.rb +22 -0
  21. data/fastlane/lib/fastlane/actions/cocoapods.rb +15 -1
  22. data/fastlane/lib/fastlane/actions/create_pull_request.rb +16 -1
  23. data/fastlane/lib/fastlane/actions/create_xcframework.rb +118 -0
  24. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +1 -1
  25. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
  26. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +8 -2
  27. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +5 -1
  28. data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +142 -0
  29. data/fastlane/lib/fastlane/actions/download_dsyms.rb +5 -16
  30. data/fastlane/lib/fastlane/actions/git_commit.rb +7 -3
  31. data/fastlane/lib/fastlane/actions/github_api.rb +14 -3
  32. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -2
  33. data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
  34. data/fastlane/lib/fastlane/actions/pod_push.rb +9 -0
  35. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -1
  36. data/fastlane/lib/fastlane/actions/register_device.rb +3 -3
  37. data/fastlane/lib/fastlane/actions/register_devices.rb +4 -3
  38. data/fastlane/lib/fastlane/actions/set_changelog.rb +2 -2
  39. data/fastlane/lib/fastlane/actions/set_github_release.rb +21 -8
  40. data/fastlane/lib/fastlane/actions/slack.rb +4 -5
  41. data/fastlane/lib/fastlane/actions/spm.rb +2 -2
  42. data/fastlane/lib/fastlane/actions/swiftlint.rb +4 -4
  43. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +1 -1
  44. data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +4 -2
  45. data/fastlane/lib/fastlane/cli_tools_distributor.rb +3 -0
  46. data/fastlane/lib/fastlane/documentation/actions_list.rb +2 -2
  47. data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
  48. data/fastlane/lib/fastlane/helper/gem_helper.rb +2 -2
  49. data/fastlane/lib/fastlane/version.rb +1 -1
  50. data/fastlane/swift/Actions.swift +1 -1
  51. data/fastlane/swift/Appfile.swift +1 -1
  52. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  53. data/fastlane/swift/ControlCommand.swift +1 -1
  54. data/fastlane/swift/Deliverfile.swift +2 -2
  55. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  56. data/fastlane/swift/Fastlane.swift +213 -38
  57. data/fastlane/swift/Gymfile.swift +2 -2
  58. data/fastlane/swift/GymfileProtocol.swift +11 -3
  59. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  60. data/fastlane/swift/MainProcess.swift +1 -1
  61. data/fastlane/swift/Matchfile.swift +2 -2
  62. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  63. data/fastlane/swift/Plugins.swift +1 -1
  64. data/fastlane/swift/Precheckfile.swift +2 -2
  65. data/fastlane/swift/PrecheckfileProtocol.swift +6 -2
  66. data/fastlane/swift/RubyCommand.swift +1 -1
  67. data/fastlane/swift/RubyCommandable.swift +1 -1
  68. data/fastlane/swift/Runner.swift +2 -2
  69. data/fastlane/swift/RunnerArgument.swift +1 -1
  70. data/fastlane/swift/Scanfile.swift +2 -2
  71. data/fastlane/swift/ScanfileProtocol.swift +14 -2
  72. data/fastlane/swift/Screengrabfile.swift +2 -2
  73. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  74. data/fastlane/swift/Snapshotfile.swift +2 -2
  75. data/fastlane/swift/SnapshotfileProtocol.swift +15 -3
  76. data/fastlane/swift/SocketClient.swift +1 -1
  77. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  78. data/fastlane/swift/SocketResponse.swift +1 -1
  79. data/fastlane/swift/formatting/Brewfile.lock.json +20 -14
  80. data/fastlane/swift/main.swift +1 -1
  81. data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -9
  82. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +1 -1
  83. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +23 -0
  84. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +9 -5
  85. data/fastlane_core/lib/fastlane_core/helper.rb +28 -7
  86. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +41 -16
  87. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -4
  88. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -1
  89. data/fastlane_core/lib/fastlane_core/project.rb +41 -14
  90. data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +2 -2
  91. data/frameit/lib/frameit/device_types.rb +7 -1
  92. data/gym/lib/gym/error_handler.rb +8 -0
  93. data/gym/lib/gym/generators/build_command_generator.rb +3 -1
  94. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +2 -2
  95. data/gym/lib/gym/options.rb +12 -2
  96. data/match/lib/match/encryption/openssl.rb +4 -2
  97. data/match/lib/match/nuke.rb +5 -0
  98. data/match/lib/match/options.rb +2 -2
  99. data/match/lib/match/storage/git_storage.rb +14 -10
  100. data/pilot/lib/pilot/options.rb +2 -2
  101. data/precheck/lib/precheck/options.rb +8 -3
  102. data/precheck/lib/precheck/rule_processor.rb +1 -1
  103. data/precheck/lib/precheck/runner.rb +1 -1
  104. data/scan/lib/scan/options.rb +15 -0
  105. data/scan/lib/scan/runner.rb +6 -1
  106. data/scan/lib/scan/slack_poster.rb +4 -1
  107. data/scan/lib/scan/test_command_generator.rb +3 -1
  108. data/screengrab/lib/screengrab/android_environment.rb +2 -2
  109. data/screengrab/lib/screengrab/runner.rb +2 -0
  110. data/sigh/lib/sigh/options.rb +2 -2
  111. data/sigh/lib/sigh/runner.rb +1 -1
  112. data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
  113. data/snapshot/lib/snapshot/options.rb +17 -2
  114. data/snapshot/lib/snapshot/update.rb +1 -1
  115. data/spaceship/README.md +2 -2
  116. data/spaceship/lib/spaceship/client.rb +14 -1
  117. data/spaceship/lib/spaceship/connect_api/api_client.rb +17 -2
  118. data/spaceship/lib/spaceship/connect_api/models/app.rb +6 -0
  119. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +7 -1
  120. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +9 -0
  121. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +24 -0
  122. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +26 -4
  123. data/spaceship/lib/spaceship/connect_api/models/device.rb +26 -0
  124. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +53 -0
  125. data/spaceship/lib/spaceship/connect_api/response.rb +3 -1
  126. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
  127. data/spaceship/lib/spaceship/connect_api/token.rb +1 -1
  128. data/spaceship/lib/spaceship/playground.rb +2 -2
  129. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  130. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +1 -0
  131. data/spaceship/lib/spaceship/upgrade_2fa_later_client.rb +91 -0
  132. metadata +51 -21
  133. data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
  134. data/spaceship/lib/spaceship/connect_api/models/.app_data_usage_data_protection.rb.swp +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77bbcab6a1ba00a457477ca27ddaca5f81485448e5022897e9c7ef43ff566991
4
- data.tar.gz: 188796684ccb2fed018b9e4ada265a176aa074d09812592ce24d22c69fc48b7b
3
+ metadata.gz: 68170ec370531b330f2955c2d41ba3034cee82eed1684062f7850fb4cb684848
4
+ data.tar.gz: 46be2e9005002001ecad77101f3ef29fb3b8ce693f240be32a40476a21949ba7
5
5
  SHA512:
6
- metadata.gz: 298f64e50908a6b7e40faa8e160d5e8b064054c2622bcaec9008f0aa861de6022187e0968a4398af07940d0f6383fbbfcb49cdc9136dab6cf6995f497f4d5440
7
- data.tar.gz: 98361a556a41a534a68eddad93af5418be1bdcc8ae7b41b69308d109c37582896336ee5ff0e4ce791696320eacd7c21fc757125ef1bf8cfa7e945231ad279b87
6
+ metadata.gz: 819474aabb8daecf3543a068641d84ef7cefb77626660027e8bd3bc98701d5983b8a05a7a892f54015cfc4537d7ae930a8b1f3aa5eb860420dcc4d574b599281
7
+ data.tar.gz: 19916ecfea7aef5c4371bd6ae6f420c6694e197eca113b2db73180deb9f4ceec84baa652586dab4d8633d40ead0f6c100e50a23480fa75b499a4c2d3ec425821
data/README.md CHANGED
@@ -34,38 +34,56 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
34
34
  <!-- This table is regenerated and resorted on each release -->
35
35
  <table id='team'>
36
36
  <tr>
37
- <td id='aaron-brager'>
38
- <a href='https://github.com/getaaron'>
39
- <img src='https://github.com/getaaron.png?size=140'>
37
+ <td id='kohki-miki'>
38
+ <a href='https://github.com/giginet'>
39
+ <img src='https://github.com/giginet.png?size=140'>
40
40
  </a>
41
- <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
41
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
42
42
  </td>
43
- <td id='helmut-januschka'>
44
- <a href='https://github.com/hjanuschka'>
45
- <img src='https://github.com/hjanuschka.png?size=140'>
43
+ <td id='max-ott'>
44
+ <a href='https://github.com/max-ott'>
45
+ <img src='https://github.com/max-ott.png?size=140'>
46
46
  </a>
47
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
47
+ <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
48
48
  </td>
49
+ <td id='matthew-ellis'>
50
+ <a href='https://github.com/matthewellis'>
51
+ <img src='https://github.com/matthewellis.png?size=140'>
52
+ </a>
53
+ <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
54
+ </td>
55
+ <td id='stefan-natchev'>
56
+ <a href='https://github.com/snatchev'>
57
+ <img src='https://github.com/snatchev.png?size=140'>
58
+ </a>
59
+ <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
60
+ </td>
61
+ <td id='josh-holtz'>
62
+ <a href='https://github.com/joshdholtz'>
63
+ <img src='https://github.com/joshdholtz.png?size=140'>
64
+ </a>
65
+ <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
66
+ </td>
67
+ </tr>
68
+ <tr>
49
69
  <td id='maksym-grebenets'>
50
70
  <a href='https://github.com/mgrebenets'>
51
71
  <img src='https://github.com/mgrebenets.png?size=140'>
52
72
  </a>
53
73
  <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
54
74
  </td>
75
+ <td id='felix-krause'>
76
+ <a href='https://github.com/KrauseFx'>
77
+ <img src='https://github.com/KrauseFx.png?size=140'>
78
+ </a>
79
+ <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
80
+ </td>
55
81
  <td id='danielle-tomlinson'>
56
82
  <a href='https://github.com/endocrimes'>
57
83
  <img src='https://github.com/endocrimes.png?size=140'>
58
84
  </a>
59
85
  <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
60
86
  </td>
61
- <td id='max-ott'>
62
- <a href='https://github.com/max-ott'>
63
- <img src='https://github.com/max-ott.png?size=140'>
64
- </a>
65
- <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
66
- </td>
67
- </tr>
68
- <tr>
69
87
  <td id='andrew-mcburney'>
70
88
  <a href='https://github.com/armcburney'>
71
89
  <img src='https://github.com/armcburney.png?size=140'>
@@ -78,31 +96,45 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
78
96
  </a>
79
97
  <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
80
98
  </td>
99
+ </tr>
100
+ <tr>
101
+ <td id='iulian-onofrei'>
102
+ <a href='https://github.com/revolter'>
103
+ <img src='https://github.com/revolter.png?size=140'>
104
+ </a>
105
+ <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
106
+ </td>
107
+ <td id='jimmy-dee'>
108
+ <a href='https://github.com/jdee'>
109
+ <img src='https://github.com/jdee.png?size=140'>
110
+ </a>
111
+ <h4 align='center'>Jimmy Dee</h4>
112
+ </td>
81
113
  <td id='joshua-liebowitz'>
82
114
  <a href='https://github.com/taquitos'>
83
115
  <img src='https://github.com/taquitos.png?size=140'>
84
116
  </a>
85
117
  <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
86
118
  </td>
87
- <td id='fumiya-nakamura'>
88
- <a href='https://github.com/nafu'>
89
- <img src='https://github.com/nafu.png?size=140'>
119
+ <td id='aaron-brager'>
120
+ <a href='https://github.com/getaaron'>
121
+ <img src='https://github.com/getaaron.png?size=140'>
90
122
  </a>
91
- <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
123
+ <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
92
124
  </td>
93
- <td id='matthew-ellis'>
94
- <a href='https://github.com/matthewellis'>
95
- <img src='https://github.com/matthewellis.png?size=140'>
125
+ <td id='daniel-jankowski'>
126
+ <a href='https://github.com/mollyIV'>
127
+ <img src='https://github.com/mollyIV.png?size=140'>
96
128
  </a>
97
- <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
129
+ <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
98
130
  </td>
99
131
  </tr>
100
132
  <tr>
101
- <td id='stefan-natchev'>
102
- <a href='https://github.com/snatchev'>
103
- <img src='https://github.com/snatchev.png?size=140'>
133
+ <td id='fumiya-nakamura'>
134
+ <a href='https://github.com/nafu'>
135
+ <img src='https://github.com/nafu.png?size=140'>
104
136
  </a>
105
- <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
137
+ <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
106
138
  </td>
107
139
  <td id='luka-mirosevic'>
108
140
  <a href='https://github.com/lmirosevic'>
@@ -110,70 +142,38 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
110
142
  </a>
111
143
  <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
112
144
  </td>
113
- <td id='felix-krause'>
114
- <a href='https://github.com/KrauseFx'>
115
- <img src='https://github.com/KrauseFx.png?size=140'>
116
- </a>
117
- <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
118
- </td>
119
- <td id='iulian-onofrei'>
120
- <a href='https://github.com/revolter'>
121
- <img src='https://github.com/revolter.png?size=140'>
122
- </a>
123
- <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
124
- </td>
125
- <td id='olivier-halligon'>
126
- <a href='https://github.com/AliSoftware'>
127
- <img src='https://github.com/AliSoftware.png?size=140'>
128
- </a>
129
- <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
130
- </td>
131
- </tr>
132
- <tr>
133
- <td id='daniel-jankowski'>
134
- <a href='https://github.com/mollyIV'>
135
- <img src='https://github.com/mollyIV.png?size=140'>
136
- </a>
137
- <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
138
- </td>
139
- <td id='manu-wallner'>
140
- <a href='https://github.com/milch'>
141
- <img src='https://github.com/milch.png?size=140'>
142
- </a>
143
- <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
144
- </td>
145
145
  <td id='jorge-revuelta-h'>
146
146
  <a href='https://github.com/minuscorp'>
147
147
  <img src='https://github.com/minuscorp.png?size=140'>
148
148
  </a>
149
149
  <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
150
150
  </td>
151
- <td id='kohki-miki'>
152
- <a href='https://github.com/giginet'>
153
- <img src='https://github.com/giginet.png?size=140'>
151
+ <td id='manu-wallner'>
152
+ <a href='https://github.com/milch'>
153
+ <img src='https://github.com/milch.png?size=140'>
154
154
  </a>
155
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
155
+ <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
156
156
  </td>
157
- <td id='jimmy-dee'>
158
- <a href='https://github.com/jdee'>
159
- <img src='https://github.com/jdee.png?size=140'>
157
+ <td id='helmut-januschka'>
158
+ <a href='https://github.com/hjanuschka'>
159
+ <img src='https://github.com/hjanuschka.png?size=140'>
160
160
  </a>
161
- <h4 align='center'>Jimmy Dee</h4>
161
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
162
162
  </td>
163
163
  </tr>
164
164
  <tr>
165
+ <td id='olivier-halligon'>
166
+ <a href='https://github.com/AliSoftware'>
167
+ <img src='https://github.com/AliSoftware.png?size=140'>
168
+ </a>
169
+ <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
170
+ </td>
165
171
  <td id='jan-piotrowski'>
166
172
  <a href='https://github.com/janpio'>
167
173
  <img src='https://github.com/janpio.png?size=140'>
168
174
  </a>
169
175
  <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
170
176
  </td>
171
- <td id='josh-holtz'>
172
- <a href='https://github.com/joshdholtz'>
173
- <img src='https://github.com/joshdholtz.png?size=140'>
174
- </a>
175
- <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
176
- </td>
177
177
  </table>
178
178
 
179
179
  Special thanks to all [contributors](https://github.com/fastlane/fastlane/graphs/contributors) for extending and improving _fastlane_.
@@ -38,7 +38,7 @@ module Cert
38
38
 
39
39
  # App Store Connect API
40
40
  FastlaneCore::ConfigItem.new(key: :api_key_path,
41
- env_name: "DELIVER_API_KEY_PATH",
41
+ env_names: ["CERT_API_KEY_PATH", "DELIVER_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
42
42
  description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
43
43
  optional: true,
44
44
  conflicting_options: [:api_key],
@@ -46,7 +46,7 @@ module Cert
46
46
  UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
47
47
  end),
48
48
  FastlaneCore::ConfigItem.new(key: :api_key,
49
- env_name: "DELIVER_API_KEY",
49
+ env_names: ["CERT_API_KEY", "DELIVER_API_KEY", "APP_STORE_CONNECT_API_KEY"],
50
50
  description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
51
51
  type: Hash,
52
52
  optional: true,
@@ -82,15 +82,12 @@ module Deliver
82
82
  # @param path (String) path to the screenshot file
83
83
  # @param language (String) Language of this screenshot (e.g. English)
84
84
  # @param screen_size (Deliver::AppScreenshot::ScreenSize) the screen size, which
85
- # will automatically be calculated when you don't set it.
85
+ # will automatically be calculated when you don't set it. (Deprecated)
86
86
  def initialize(path, language, screen_size = nil)
87
+ UI.deprecated('`screen_size` for Deliver::AppScreenshot.new is deprecated in favor of the default behavior to calculate size automatically. Passed value is no longer validated.') if screen_size
87
88
  self.path = path
88
89
  self.language = language
89
- screen_size ||= self.class.calculate_screen_size(path)
90
-
91
- self.screen_size = screen_size
92
-
93
- UI.error("Looks like the screenshot given (#{path}) does not match the requirements of #{screen_size}") unless self.is_valid?
90
+ self.screen_size = screen_size || self.class.calculate_screen_size(path)
94
91
  end
95
92
 
96
93
  # The iTC API requires a different notation for the device
@@ -161,6 +158,7 @@ module Deliver
161
158
 
162
159
  # Validates the given screenshots (size and format)
163
160
  def is_valid?
161
+ UI.deprecated('Deliver::AppScreenshot#is_valid? is deprecated in favor of Deliver::AppScreenshotValidator')
164
162
  return false unless ["png", "PNG", "jpg", "JPG", "jpeg", "JPEG"].include?(self.path.split(".").last)
165
163
 
166
164
  return self.screen_size == self.class.calculate_screen_size(self.path)
@@ -350,7 +348,7 @@ module Deliver
350
348
  end
351
349
  end
352
350
 
353
- UI.user_error!("Unsupported screen size #{size} for path '#{path}'")
351
+ nil
354
352
  end
355
353
  end
356
354
 
@@ -0,0 +1,108 @@
1
+ require 'fastimage'
2
+
3
+ module Deliver
4
+ class AppScreenshotValidator
5
+ # A simple structure that holds error information as well as formatted error messages consistently
6
+ # Set `to_skip` to `true` when just needing to skip uploading rather than causing a crash.
7
+ class ValidationError
8
+ # Constants that can be given to `type` param
9
+ INVALID_SCREEN_SIZE = 'Invalid screen size'.freeze
10
+ UNACCEPTABLE_DEVICE = 'Not an accepted App Store Connect device'.freeze
11
+ INVALID_FILE_EXTENSION = 'Invalid file extension'.freeze
12
+ FILE_EXTENSION_MISMATCH = 'File extension mismatches its image format'.freeze
13
+
14
+ attr_reader :type, :path, :debug_info, :to_skip
15
+
16
+ def initialize(type: nil, path: nil, debug_info: nil, to_skip: false)
17
+ @type = type
18
+ @path = path
19
+ @debug_info = debug_info
20
+ @to_skip = to_skip
21
+ end
22
+
23
+ def to_s
24
+ "#{to_skip ? '🏃 Skipping' : '🚫 Error'}: #{path} - #{type} (#{debug_info})"
25
+ end
26
+
27
+ def inspect
28
+ "\"#{type}\""
29
+ end
30
+ end
31
+
32
+ # Access each array by symbol returned from FastImage.type
33
+ ALLOWED_SCREENSHOT_FILE_EXTENSION = { png: ['png', 'PNG'], jpeg: ['jpg', 'JPG', 'jpeg', 'JPEG'] }.freeze
34
+
35
+ APP_SCREENSHOT_SPEC_URL = 'https://help.apple.com/app-store-connect/#/devd274dd925'.freeze
36
+
37
+ # Validate a screenshot and inform an error message via `errors` parameter. `errors` is mutated
38
+ # to append the messages and each message should contain the corresponding path to let users know which file is throwing the error.
39
+ #
40
+ # @param screenshot [AppScreenshot]
41
+ # @param errors [Array<Deliver::AppScreenshotValidator::ValidationError>] Pass an array object to add validation errors when detecting errors.
42
+ # This will be mutated to add more error objects as validation detects errors.
43
+ # @return [Boolean] true if given screenshot is valid
44
+ def self.validate(screenshot, errors)
45
+ # Given screenshot will be diagnosed and errors found are accumulated
46
+ errors_found = []
47
+
48
+ validate_screen_size(screenshot, errors_found)
49
+ validate_device_type(screenshot, errors_found)
50
+ validate_file_extension_and_format(screenshot, errors_found)
51
+
52
+ # Merge errors found into given errors array
53
+ errors_found.each { |error| errors.push(error) }
54
+ errors_found.empty?
55
+ end
56
+
57
+ def self.validate_screen_size(screenshot, errors_found)
58
+ if screenshot.screen_size.nil?
59
+ errors_found << ValidationError.new(type: ValidationError::INVALID_SCREEN_SIZE,
60
+ path: screenshot.path,
61
+ debug_info: "Actual size is #{get_formatted_size(screenshot)}. See the specifications to fix #{APP_SCREENSHOT_SPEC_URL}")
62
+ end
63
+ end
64
+
65
+ # Checking if the device type exists in spaceship
66
+ # Ex: iPhone 6.1 inch isn't supported in App Store Connect but need
67
+ # to have it in there for frameit support
68
+ def self.validate_device_type(screenshot, errors_found)
69
+ if !screenshot.screen_size.nil? && screenshot.device_type.nil?
70
+ errors_found << ValidationError.new(type: ValidationError::UNACCEPTABLE_DEVICE,
71
+ path: screenshot.path,
72
+ debug_info: "Screen size #{screenshot.screen_size} is not accepted. See the specifications to fix #{APP_SCREENSHOT_SPEC_URL}",
73
+ to_skip: true)
74
+ end
75
+ end
76
+
77
+ def self.validate_file_extension_and_format(screenshot, errors_found)
78
+ extension = File.extname(screenshot.path).delete('.')
79
+ valid_file_extensions = ALLOWED_SCREENSHOT_FILE_EXTENSION.values.flatten
80
+ is_valid_extension = valid_file_extensions.include?(extension)
81
+
82
+ unless is_valid_extension
83
+ errors_found << ValidationError.new(type: ValidationError::INVALID_FILE_EXTENSION,
84
+ path: screenshot.path,
85
+ debug_info: "Only #{valid_file_extensions.join(', ')} are allowed")
86
+ end
87
+
88
+ format = FastImage.type(screenshot.path)
89
+ is_extension_matched = ALLOWED_SCREENSHOT_FILE_EXTENSION[format] &&
90
+ ALLOWED_SCREENSHOT_FILE_EXTENSION[format].include?(extension)
91
+
92
+ # This error only appears when file extension is valid
93
+ if is_valid_extension && !is_extension_matched
94
+ expected_extension = ALLOWED_SCREENSHOT_FILE_EXTENSION[format].first
95
+ expected_filename = File.basename(screenshot.path, File.extname(screenshot.path)) + ".#{expected_extension}"
96
+ errors_found << ValidationError.new(type: ValidationError::FILE_EXTENSION_MISMATCH,
97
+ path: screenshot.path,
98
+ debug_info: %(Actual format is "#{format}". Rename the filename to "#{expected_filename}".))
99
+ end
100
+ end
101
+
102
+ def self.get_formatted_size(screenshot)
103
+ size = FastImage.size(screenshot.path)
104
+ return size.join('x') if size
105
+ nil
106
+ end
107
+ end
108
+ end
@@ -177,7 +177,7 @@ module Deliver
177
177
  end
178
178
  end
179
179
 
180
- Deliver::Setup.new.generate_metadata_files(app, v, path)
180
+ Deliver::Setup.new.generate_metadata_files(app, v, path, options)
181
181
  end
182
182
  end
183
183
 
@@ -1,8 +1,6 @@
1
- require 'fastlane_core/languages'
2
- require 'spaceship/tunes/tunes'
3
-
4
1
  require_relative 'module'
5
2
  require_relative 'app_screenshot'
3
+ require_relative 'app_screenshot_validator'
6
4
  require_relative 'upload_metadata'
7
5
  require_relative 'languages'
8
6
 
@@ -80,7 +78,7 @@ module Deliver
80
78
  end
81
79
  end
82
80
 
83
- # Returns the list of valid app screenshot
81
+ # Returns the list of valid app screenshot. When detecting invalid screenshots, this will cause an error.
84
82
  #
85
83
  # @param root [String] A directory path
86
84
  # @param ignore_validation [String] Set false not to raise the error when finding invalid folder name
@@ -100,36 +98,22 @@ module Deliver
100
98
  end
101
99
 
102
100
  errors = []
103
- valid_screenshots = screenshots.select { |screenshot| validate_screenshot(screenshot, errors) }
101
+ valid_screenshots = screenshots.select { |screenshot| Deliver::AppScreenshotValidator.validate(screenshot, errors) }
104
102
 
105
- unless errors.empty?
106
- UI.important("Unaccepted device screenshots are detected! 🚫 Screenshot file will be skipped. 🏃")
107
- errors.each { |error| UI.important(error) }
108
- end
103
+ errors_to_skip, errors_to_crash = errors.partition(&:to_skip)
109
104
 
110
- valid_screenshots
111
- end
105
+ unless errors_to_skip.empty?
106
+ UI.important("🏃 Screenshots to be skipped are detected!")
107
+ errors_to_skip.each { |error| UI.message(error) }
108
+ end
112
109
 
113
- # Validate a screenshot and inform an error message via `errors` parameters. `errors` is mutated
114
- # to append the messages and each message should contain the corresponding path to let users know which file gets the error.
115
- #
116
- # @param screenshot [AppScreenshot]
117
- # @param errors [Array<String>] Pass an array object to add error messages when finding an error
118
- # @return [Boolean] true if given screenshot is valid
119
- def self.validate_screenshot(screenshot, errors)
120
- # Given screenshot will be diagnosed and errors found are accumulated
121
- errors_found = []
122
-
123
- # Checking if the device type exists in spaceship
124
- # Ex: iPhone 6.1 inch isn't supported in App Store Connect but need
125
- # to have it in there for frameit support
126
- if screenshot.device_type.nil?
127
- errors_found << "🏃 Skipping screenshot file: #{screenshot.path} - Not an accepted App Store Connect device..."
110
+ unless errors_to_crash.empty?
111
+ UI.important("🚫 Invalid screenshots were detected! Here are the reasons:")
112
+ errors_to_crash.each { |error| UI.error(error) }
113
+ UI.user_error!("Canceled uploading screenshots. Please check the error messages above and fix the screenshots.")
128
114
  end
129
115
 
130
- # Merge errors found into given errors array
131
- errors_found.each { |error| errors.push(error) }
132
- errors_found.empty?
116
+ valid_screenshots
133
117
  end
134
118
 
135
119
  # Returns the list of language folders