fastlane 2.229.0 → 2.230.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +100 -94
  3. data/deliver/lib/assets/summary.html.erb +3 -3
  4. data/deliver/lib/deliver/app_screenshot.rb +215 -347
  5. data/deliver/lib/deliver/app_screenshot_iterator.rb +4 -1
  6. data/deliver/lib/deliver/app_screenshot_validator.rb +5 -21
  7. data/deliver/lib/deliver/loader.rb +2 -9
  8. data/deliver/lib/deliver/upload_metadata.rb +5 -0
  9. data/deliver/lib/deliver/upload_screenshots.rb +4 -2
  10. data/fastlane/lib/fastlane/actions/docs/create_app_online.md +2 -1
  11. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +3 -1
  12. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +34 -6
  13. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +2 -0
  14. data/fastlane/lib/fastlane/actions/install_xcode_plugin.rb +3 -2
  15. data/fastlane/lib/fastlane/actions/modify_services.rb +1 -0
  16. data/fastlane/lib/fastlane/actions/notarize.rb +1 -1
  17. data/fastlane/lib/fastlane/actions/xcov.rb +1 -7
  18. data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +4 -4
  19. data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +20 -20
  20. data/fastlane/lib/fastlane/version.rb +1 -1
  21. data/fastlane/swift/Deliverfile.swift +1 -1
  22. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  23. data/fastlane/swift/Fastlane.swift +85 -13
  24. data/fastlane/swift/Gymfile.swift +1 -1
  25. data/fastlane/swift/GymfileProtocol.swift +9 -1
  26. data/fastlane/swift/Matchfile.swift +1 -1
  27. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  28. data/fastlane/swift/Precheckfile.swift +1 -1
  29. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  30. data/fastlane/swift/Scanfile.swift +1 -1
  31. data/fastlane/swift/ScanfileProtocol.swift +5 -1
  32. data/fastlane/swift/Screengrabfile.swift +1 -1
  33. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  34. data/fastlane/swift/Snapshotfile.swift +1 -1
  35. data/fastlane/swift/SnapshotfileProtocol.swift +5 -1
  36. data/fastlane_core/lib/fastlane_core/fastlane_pty.rb +5 -1
  37. data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +14 -0
  38. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +38 -8
  39. data/fastlane_core/lib/fastlane_core/project.rb +4 -0
  40. data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +7 -1
  41. data/frameit/lib/frameit/device.rb +2 -2
  42. data/frameit/lib/frameit/device_types.rb +108 -70
  43. data/frameit/lib/frameit/template_finder.rb +1 -1
  44. data/gym/lib/gym/module.rb +9 -4
  45. data/gym/lib/gym/options.rb +14 -1
  46. data/gym/lib/gym/runner.rb +38 -3
  47. data/produce/lib/produce/developer_center.rb +1 -0
  48. data/produce/lib/produce/service.rb +6 -1
  49. data/scan/lib/scan/options.rb +5 -0
  50. data/scan/lib/scan/test_command_generator.rb +8 -0
  51. data/sigh/lib/sigh/local_manage.rb +6 -4
  52. data/sigh/lib/sigh/runner.rb +18 -1
  53. data/snapshot/lib/snapshot/options.rb +5 -0
  54. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +62 -8
  55. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +4 -4
  56. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +7 -1
  57. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +16 -16
  58. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +2 -0
  59. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +0 -6
  60. data/spaceship/lib/spaceship/errors.rb +8 -6
  61. data/supply/lib/supply/client.rb +18 -1
  62. metadata +75 -29
  63. data/fastlane/lib/fastlane/core_ext/bundler_monkey_patch.rb +0 -14
  64. data/fastlane/lib/fastlane/plugins/template/.circleci/config.yml +0 -43
  65. data/fastlane/lib/fastlane/plugins/template/.travis.yml +0 -4
@@ -7,81 +7,192 @@ module Deliver
7
7
  # AppScreenshot represents one screenshots for one specific locale and
8
8
  # device type.
9
9
  class AppScreenshot
10
- #
11
- module ScreenSize
12
- # iPhone 4
13
- IOS_35 = "iOS-3.5-in"
14
- # iPhone 5
15
- IOS_40 = "iOS-4-in"
16
- # iPhone 6, 7, & 8
17
- IOS_47 = "iOS-4.7-in"
18
- # iPhone 6 Plus, 7 Plus, & 8 Plus
19
- IOS_55 = "iOS-5.5-in"
20
- # iPhone XS
21
- IOS_58 = "iOS-5.8-in"
22
- # iPhone 14 Pro
23
- IOS_61 = "iOS-6.1-in"
24
- # iPhone 14 Plus, iPhone 13 Pro Max, iPhone 12 Pro Max, iPhone 11 Pro Max, iPhone 11, iPhone XS Max, iPhone XR
25
- IOS_65 = "iOS-6.5-in"
26
- # iPhone 14 Pro Max
27
- IOS_67 = "iOS-6.7-in"
10
+ # Shorthand for DisplayType constants
11
+ DisplayType = Spaceship::ConnectAPI::AppScreenshotSet::DisplayType
28
12
 
29
- # iPad
30
- IOS_IPAD = "iOS-iPad"
31
- # iPad 10.5
32
- IOS_IPAD_10_5 = "iOS-iPad-10.5"
33
- # iPad 11
34
- IOS_IPAD_11 = "iOS-iPad-11"
35
- # iPad Pro
36
- IOS_IPAD_PRO = "iOS-iPad-Pro"
37
- # iPad Pro (12.9-inch) (3rd generation)
38
- IOS_IPAD_PRO_12_9 = "iOS-iPad-Pro-12.9"
13
+ FORMATTED_NAMES = {
14
+ DisplayType::APP_IPHONE_35 => "iPhone 4",
15
+ DisplayType::APP_IPHONE_40 => "iPhone 5",
16
+ DisplayType::APP_IPHONE_47 => "iPhone 6",
17
+ DisplayType::APP_IPHONE_55 => "iPhone 6 Plus",
18
+ DisplayType::APP_IPHONE_58 => "iPhone XS",
19
+ DisplayType::APP_IPHONE_61 => "iPhone 14 Pro",
20
+ DisplayType::APP_IPHONE_65 => "iPhone XS Max",
21
+ DisplayType::APP_IPHONE_67 => "iPhone 14 Pro Max",
22
+ DisplayType::APP_IPAD_97 => "iPad",
23
+ DisplayType::APP_IPAD_105 => "iPad 10.5",
24
+ DisplayType::APP_IPAD_PRO_3GEN_11 => "iPad 11",
25
+ DisplayType::APP_IPAD_PRO_129 => "iPad Pro",
26
+ DisplayType::APP_IPAD_PRO_3GEN_129 => "iPad Pro (12.9-inch) (3rd generation)",
27
+ DisplayType::IMESSAGE_APP_IPHONE_40 => "iPhone 5 (iMessage)",
28
+ DisplayType::IMESSAGE_APP_IPHONE_47 => "iPhone 6 (iMessage)",
29
+ DisplayType::IMESSAGE_APP_IPHONE_55 => "iPhone 6 Plus (iMessage)",
30
+ DisplayType::IMESSAGE_APP_IPHONE_58 => "iPhone XS (iMessage)",
31
+ DisplayType::IMESSAGE_APP_IPHONE_61 => "iPhone 14 Pro (iMessage)",
32
+ DisplayType::IMESSAGE_APP_IPHONE_65 => "iPhone XS Max (iMessage)",
33
+ DisplayType::IMESSAGE_APP_IPHONE_67 => "iPhone 14 Pro Max (iMessage)",
34
+ DisplayType::IMESSAGE_APP_IPAD_97 => "iPad (iMessage)",
35
+ DisplayType::IMESSAGE_APP_IPAD_PRO_129 => "iPad Pro (iMessage)",
36
+ DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_129 => "iPad Pro (12.9-inch) (3rd generation) (iMessage)",
37
+ DisplayType::IMESSAGE_APP_IPAD_105 => "iPad 10.5 (iMessage)",
38
+ DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_11 => "iPad 11 (iMessage)",
39
+ DisplayType::APP_DESKTOP => "Mac",
40
+ DisplayType::APP_WATCH_SERIES_3 => "Watch",
41
+ DisplayType::APP_WATCH_SERIES_4 => "Watch Series4",
42
+ DisplayType::APP_WATCH_SERIES_7 => "Watch Series7",
43
+ DisplayType::APP_WATCH_SERIES_10 => "Watch Series10",
44
+ DisplayType::APP_WATCH_ULTRA => "Watch Ultra",
45
+ DisplayType::APP_APPLE_TV => "Apple TV",
46
+ DisplayType::APP_APPLE_VISION_PRO => "Vision Pro"
47
+ }.freeze
39
48
 
40
- # iPhone 5 iMessage
41
- IOS_40_MESSAGES = "iOS-4-in-messages"
42
- # iPhone 6, 7, & 8 iMessage
43
- IOS_47_MESSAGES = "iOS-4.7-in-messages"
44
- # iPhone 6 Plus, 7 Plus, & 8 Plus iMessage
45
- IOS_55_MESSAGES = "iOS-5.5-in-messages"
46
- # iPhone XS iMessage
47
- IOS_58_MESSAGES = "iOS-5.8-in-messages"
48
- # iPhone 14 Pro iMessage
49
- IOS_61_MESSAGES = "iOS-6.1-in-messages"
50
- # iPhone 14 Plus, iPhone 13 Pro Max, iPhone 12 Pro Max, iPhone 11 Pro Max, iPhone 11, iPhone XS Max, iPhone XR iMessage
51
- IOS_65_MESSAGES = "iOS-6.5-in-messages"
52
- # iPhone 14 Pro Max iMessage
53
- IOS_67_MESSAGES = "iOS-6.7-in-messages"
54
-
55
- # iPad iMessage
56
- IOS_IPAD_MESSAGES = "iOS-iPad-messages"
57
- # iPad 10.5 iMessage
58
- IOS_IPAD_10_5_MESSAGES = "iOS-iPad-10.5-messages"
59
- # iPad 11 iMessage
60
- IOS_IPAD_11_MESSAGES = "iOS-iPad-11-messages"
61
- # iPad Pro iMessage
62
- IOS_IPAD_PRO_MESSAGES = "iOS-iPad-Pro-messages"
63
- # iPad Pro (12.9-inch) (3rd generation) iMessage
64
- IOS_IPAD_PRO_12_9_MESSAGES = "iOS-iPad-Pro-12.9-messages"
65
-
66
- # Apple Watch
67
- IOS_APPLE_WATCH = "iOS-Apple-Watch"
68
- # Apple Watch Series 4
69
- IOS_APPLE_WATCH_SERIES4 = "iOS-Apple-Watch-Series4"
70
- # Apple Watch Series 7
71
- IOS_APPLE_WATCH_SERIES7 = "iOS-Apple-Watch-Series7"
72
- # Apple Watch Ultra
73
- IOS_APPLE_WATCH_ULTRA = "iOS-Apple-Watch-Ultra"
49
+ # reference: https://help.apple.com/app-store-connect/#/devd274dd925
50
+ # Returns a hash mapping DisplayType constants to their supported resolutions.
51
+ DEVICE_RESOLUTIONS = {
52
+ # These are actually 6.9" iPhones
53
+ DisplayType::APP_IPHONE_67 => [
54
+ [1260, 2736],
55
+ [2736, 1260],
56
+ [1290, 2796],
57
+ [2796, 1290],
58
+ [1320, 2868],
59
+ [2868, 1320]
60
+ ],
61
+ DisplayType::APP_IPHONE_65 => [
62
+ [1242, 2688],
63
+ [2688, 1242],
64
+ [1284, 2778],
65
+ [2778, 1284]
66
+ ],
67
+ # These are actually 6.3" iPhones
68
+ DisplayType::APP_IPHONE_61 => [
69
+ [1179, 2556],
70
+ [2556, 1179],
71
+ [1206, 2622],
72
+ [2622, 1206]
73
+ ],
74
+ # These are actually 6.1" iPhones
75
+ DisplayType::APP_IPHONE_58 => [
76
+ [1170, 2532],
77
+ [2532, 1170],
78
+ [1125, 2436],
79
+ [2436, 1125],
80
+ [1080, 2340],
81
+ [2340, 1080]
82
+ ],
83
+ DisplayType::APP_IPHONE_55 => [
84
+ [1242, 2208],
85
+ [2208, 1242]
86
+ ],
87
+ DisplayType::APP_IPHONE_47 => [
88
+ [750, 1334],
89
+ [1334, 750]
90
+ ],
91
+ DisplayType::APP_IPHONE_40 => [
92
+ [640, 1096],
93
+ [640, 1136],
94
+ [1136, 600],
95
+ [1136, 640]
96
+ ],
97
+ DisplayType::APP_IPHONE_35 => [
98
+ [640, 920],
99
+ [640, 960],
100
+ [960, 600],
101
+ [960, 640]
102
+ ],
103
+ DisplayType::APP_IPAD_97 => [
104
+ [1024, 748],
105
+ [1024, 768],
106
+ [2048, 1496],
107
+ [2048, 1536],
108
+ [768, 1004],
109
+ [768, 1024],
110
+ [1536, 2008],
111
+ [1536, 2048]
112
+ ],
113
+ DisplayType::APP_IPAD_105 => [
114
+ [1668, 2224],
115
+ [2224, 1668]
116
+ ],
117
+ DisplayType::APP_IPAD_PRO_3GEN_11 => [
118
+ [1488, 2266],
119
+ [2266, 1488],
120
+ [1668, 2420],
121
+ [2420, 1668],
122
+ [1668, 2388],
123
+ [2388, 1668],
124
+ [1640, 2360],
125
+ [2360, 1640]
126
+ ],
127
+ # These are 12.9" iPads
128
+ DisplayType::APP_IPAD_PRO_129 => [
129
+ [2048, 2732],
130
+ [2732, 2048]
131
+ ],
132
+ # These are actually 13" iPads
133
+ DisplayType::APP_IPAD_PRO_3GEN_129 => [
134
+ [2048, 2732],
135
+ [2732, 2048],
136
+ [2064, 2752],
137
+ [2752, 2064]
138
+ ],
139
+ DisplayType::APP_DESKTOP => [
140
+ [1280, 800],
141
+ [1440, 900],
142
+ [2560, 1600],
143
+ [2880, 1800]
144
+ ],
145
+ DisplayType::APP_WATCH_SERIES_3 => [
146
+ [312, 390]
147
+ ],
148
+ DisplayType::APP_WATCH_SERIES_4 => [
149
+ [368, 448]
150
+ ],
151
+ DisplayType::APP_WATCH_SERIES_7 => [
152
+ [396, 484]
153
+ ],
154
+ DisplayType::APP_WATCH_SERIES_10 => [
155
+ [416, 496]
156
+ ],
157
+ DisplayType::APP_WATCH_ULTRA => [
158
+ [410, 502],
159
+ [422, 514]
160
+ ],
161
+ DisplayType::APP_APPLE_TV => [
162
+ [1920, 1080],
163
+ [3840, 2160]
164
+ ],
165
+ DisplayType::APP_APPLE_VISION_PRO => [
166
+ [3840, 2160]
167
+ ]
168
+ }.freeze
74
169
 
75
- # Apple TV
76
- APPLE_TV = "Apple-TV"
170
+ DEVICE_RESOLUTIONS_MESSAGES = {
171
+ DisplayType::IMESSAGE_APP_IPHONE_40 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_40],
172
+ DisplayType::IMESSAGE_APP_IPHONE_47 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_47],
173
+ DisplayType::IMESSAGE_APP_IPHONE_55 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_55],
174
+ DisplayType::IMESSAGE_APP_IPHONE_58 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_58],
175
+ DisplayType::IMESSAGE_APP_IPHONE_61 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_61],
176
+ DisplayType::IMESSAGE_APP_IPHONE_65 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_65],
177
+ DisplayType::IMESSAGE_APP_IPHONE_67 => DEVICE_RESOLUTIONS[DisplayType::APP_IPHONE_67],
178
+ DisplayType::IMESSAGE_APP_IPAD_97 => DEVICE_RESOLUTIONS[DisplayType::APP_IPAD_97],
179
+ DisplayType::IMESSAGE_APP_IPAD_105 => DEVICE_RESOLUTIONS[DisplayType::APP_IPAD_105],
180
+ DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_11 => DEVICE_RESOLUTIONS[DisplayType::APP_IPAD_PRO_3GEN_11],
181
+ DisplayType::IMESSAGE_APP_IPAD_PRO_129 => DEVICE_RESOLUTIONS[DisplayType::APP_IPAD_PRO_129],
182
+ DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_129 => DEVICE_RESOLUTIONS[DisplayType::APP_IPAD_PRO_3GEN_129]
183
+ }.freeze
77
184
 
78
- # Mac
79
- MAC = "Mac"
80
- end
185
+ # Resolutions that are shared by multiple device types
186
+ CONFLICTING_RESOLUTIONS = [
187
+ # iPad Pro 12.9" (2nd gen) and iPad Pro 13" (3rd+ gen)
188
+ [2048, 2732],
189
+ [2732, 2048],
190
+ # Apple TV and Apple Vision Pro
191
+ [3840, 2160]
192
+ ].freeze
81
193
 
82
- # @return [Deliver::ScreenSize] the screen size (device type)
83
- # specified at {Deliver::ScreenSize}
84
- attr_accessor :screen_size
194
+ # @return [Spaceship::ConnectAPI::AppScreenshotSet::DisplayType] the display type
195
+ attr_accessor :display_type
85
196
 
86
197
  attr_accessor :path
87
198
 
@@ -89,89 +200,15 @@ module Deliver
89
200
 
90
201
  # @param path (String) path to the screenshot file
91
202
  # @param language (String) Language of this screenshot (e.g. English)
92
- # @param screen_size (Deliver::AppScreenshot::ScreenSize) the screen size, which
93
- # will automatically be calculated when you don't set it. (Deprecated)
94
- def initialize(path, language, screen_size = nil)
95
- 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
203
+ def initialize(path, language)
96
204
  self.path = path
97
205
  self.language = language
98
- self.screen_size = screen_size || self.class.calculate_screen_size(path)
99
- end
100
-
101
- # The iTC API requires a different notation for the device
102
- def device_type
103
- matching = {
104
- ScreenSize::IOS_35 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_35,
105
- ScreenSize::IOS_40 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_40,
106
- ScreenSize::IOS_47 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_47, # also 7 & 8
107
- ScreenSize::IOS_55 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_55, # also 7 Plus & 8 Plus
108
- ScreenSize::IOS_58 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_58,
109
- ScreenSize::IOS_61 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_61,
110
- ScreenSize::IOS_65 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_65,
111
- ScreenSize::IOS_67 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_67,
112
- ScreenSize::IOS_IPAD => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_97,
113
- ScreenSize::IOS_IPAD_10_5 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_105,
114
- ScreenSize::IOS_IPAD_11 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_3GEN_11,
115
- ScreenSize::IOS_IPAD_PRO => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_129,
116
- ScreenSize::IOS_IPAD_PRO_12_9 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_3GEN_129,
117
- ScreenSize::IOS_40_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_40,
118
- ScreenSize::IOS_47_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_47, # also 7 & 8
119
- ScreenSize::IOS_55_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_55, # also 7 Plus & 8 Plus
120
- ScreenSize::IOS_58_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_58,
121
- ScreenSize::IOS_61_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_61,
122
- ScreenSize::IOS_65_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_65,
123
- ScreenSize::IOS_67_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_67,
124
- ScreenSize::IOS_IPAD_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_97,
125
- ScreenSize::IOS_IPAD_PRO_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_PRO_129,
126
- ScreenSize::IOS_IPAD_PRO_12_9_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_129,
127
- ScreenSize::IOS_IPAD_10_5_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_105,
128
- ScreenSize::IOS_IPAD_11_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_11,
129
- ScreenSize::MAC => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_DESKTOP,
130
- ScreenSize::IOS_APPLE_WATCH => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_WATCH_SERIES_3,
131
- ScreenSize::IOS_APPLE_WATCH_SERIES4 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_WATCH_SERIES_4,
132
- ScreenSize::IOS_APPLE_WATCH_SERIES7 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_WATCH_SERIES_7,
133
- ScreenSize::IOS_APPLE_WATCH_ULTRA => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_WATCH_ULTRA,
134
- ScreenSize::APPLE_TV => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_APPLE_TV
135
- }
136
- return matching[self.screen_size]
206
+ self.display_type = self.class.calculate_display_type(path)
137
207
  end
138
208
 
139
209
  # Nice name
140
210
  def formatted_name
141
- matching = {
142
- ScreenSize::IOS_35 => "iPhone 4",
143
- ScreenSize::IOS_40 => "iPhone 5",
144
- ScreenSize::IOS_47 => "iPhone 6", # also 7 & 8
145
- ScreenSize::IOS_55 => "iPhone 6 Plus", # also 7 Plus & 8 Plus
146
- ScreenSize::IOS_58 => "iPhone XS",
147
- ScreenSize::IOS_61 => "iPhone 14 Pro",
148
- ScreenSize::IOS_65 => "iPhone XS Max",
149
- ScreenSize::IOS_67 => "iPhone 14 Pro Max",
150
- ScreenSize::IOS_IPAD => "iPad",
151
- ScreenSize::IOS_IPAD_10_5 => "iPad 10.5",
152
- ScreenSize::IOS_IPAD_11 => "iPad 11",
153
- ScreenSize::IOS_IPAD_PRO => "iPad Pro",
154
- ScreenSize::IOS_IPAD_PRO_12_9 => "iPad Pro (12.9-inch) (3rd generation)",
155
- ScreenSize::IOS_40_MESSAGES => "iPhone 5 (iMessage)",
156
- ScreenSize::IOS_47_MESSAGES => "iPhone 6 (iMessage)", # also 7 & 8
157
- ScreenSize::IOS_55_MESSAGES => "iPhone 6 Plus (iMessage)", # also 7 Plus & 8 Plus
158
- ScreenSize::IOS_58_MESSAGES => "iPhone XS (iMessage)",
159
- ScreenSize::IOS_61_MESSAGES => "iPhone 14 Pro (iMessage)",
160
- ScreenSize::IOS_65_MESSAGES => "iPhone XS Max (iMessage)",
161
- ScreenSize::IOS_67_MESSAGES => "iPhone 14 Pro Max (iMessage)",
162
- ScreenSize::IOS_IPAD_MESSAGES => "iPad (iMessage)",
163
- ScreenSize::IOS_IPAD_PRO_MESSAGES => "iPad Pro (iMessage)",
164
- ScreenSize::IOS_IPAD_PRO_12_9_MESSAGES => "iPad Pro (12.9-inch) (3rd generation) (iMessage)",
165
- ScreenSize::IOS_IPAD_10_5_MESSAGES => "iPad 10.5 (iMessage)",
166
- ScreenSize::IOS_IPAD_11_MESSAGES => "iPad 11 (iMessage)",
167
- ScreenSize::MAC => "Mac",
168
- ScreenSize::IOS_APPLE_WATCH => "Watch",
169
- ScreenSize::IOS_APPLE_WATCH_SERIES4 => "Watch Series4",
170
- ScreenSize::IOS_APPLE_WATCH_SERIES7 => "Watch Series7",
171
- ScreenSize::IOS_APPLE_WATCH_ULTRA => "Watch Ultra",
172
- ScreenSize::APPLE_TV => "Apple TV"
173
- }
174
- return matching[self.screen_size]
211
+ return FORMATTED_NAMES[self.display_type]
175
212
  end
176
213
 
177
214
  # Validates the given screenshots (size and format)
@@ -179,219 +216,50 @@ module Deliver
179
216
  UI.deprecated('Deliver::AppScreenshot#is_valid? is deprecated in favor of Deliver::AppScreenshotValidator')
180
217
  return false unless ["png", "PNG", "jpg", "JPG", "jpeg", "JPEG"].include?(self.path.split(".").last)
181
218
 
182
- return self.screen_size == self.class.calculate_screen_size(self.path)
219
+ return self.display_type == self.class.calculate_display_type(self.path)
183
220
  end
184
221
 
185
222
  def is_messages?
186
- return [
187
- ScreenSize::IOS_40_MESSAGES,
188
- ScreenSize::IOS_47_MESSAGES,
189
- ScreenSize::IOS_55_MESSAGES,
190
- ScreenSize::IOS_58_MESSAGES,
191
- ScreenSize::IOS_61_MESSAGES,
192
- ScreenSize::IOS_65_MESSAGES,
193
- ScreenSize::IOS_67_MESSAGES,
194
- ScreenSize::IOS_IPAD_MESSAGES,
195
- ScreenSize::IOS_IPAD_PRO_MESSAGES,
196
- ScreenSize::IOS_IPAD_PRO_12_9_MESSAGES,
197
- ScreenSize::IOS_IPAD_10_5_MESSAGES,
198
- ScreenSize::IOS_IPAD_11_MESSAGES
199
- ].include?(self.screen_size)
223
+ # rubocop:disable Require/MissingRequireStatement
224
+ return DisplayType::ALL_IMESSAGE.include?(self.display_type)
225
+ # rubocop:enable Require/MissingRequireStatement
200
226
  end
201
227
 
202
- def self.device_messages
203
- # This list does not include iPad Pro 12.9-inch (3rd generation)
204
- # because it has same resolution as IOS_IPAD_PRO and will clobber
205
- return {
206
- ScreenSize::IOS_67_MESSAGES => [
207
- [1290, 2796],
208
- [2796, 1290]
209
- ],
210
- ScreenSize::IOS_65_MESSAGES => [
211
- [1242, 2688],
212
- [2688, 1242],
213
- [1284, 2778],
214
- [2778, 1284]
215
- ],
216
- ScreenSize::IOS_61_MESSAGES => [
217
- [1179, 2556],
218
- [2556, 1179]
219
- ],
220
- ScreenSize::IOS_58_MESSAGES => [
221
- [1125, 2436],
222
- [2436, 1125],
223
- [1170, 2532],
224
- [2532, 1170]
225
- ],
226
- ScreenSize::IOS_55_MESSAGES => [
227
- [1242, 2208],
228
- [2208, 1242]
229
- ],
230
- ScreenSize::IOS_47_MESSAGES => [
231
- [750, 1334],
232
- [1334, 750]
233
- ],
234
- ScreenSize::IOS_40_MESSAGES => [
235
- [640, 1096],
236
- [640, 1136],
237
- [1136, 600],
238
- [1136, 640]
239
- ],
240
- ScreenSize::IOS_IPAD_MESSAGES => [
241
- [1024, 748],
242
- [1024, 768],
243
- [2048, 1496],
244
- [2048, 1536],
245
- [768, 1004],
246
- [768, 1024],
247
- [1536, 2008],
248
- [1536, 2048]
249
- ],
250
- ScreenSize::IOS_IPAD_10_5_MESSAGES => [
251
- [1668, 2224],
252
- [2224, 1668]
253
- ],
254
- ScreenSize::IOS_IPAD_11_MESSAGES => [
255
- [1668, 2388],
256
- [2388, 1668]
257
- ],
258
- ScreenSize::IOS_IPAD_PRO_MESSAGES => [
259
- [2732, 2048],
260
- [2048, 2732]
261
- ]
262
- }
263
- end
228
+ def self.calculate_display_type(path)
229
+ size = FastImage.size(path)
230
+ UI.user_error!("Could not find or parse file at path '#{path}'") if size.nil? || size.count == 0
264
231
 
265
- # reference: https://help.apple.com/app-store-connect/#/devd274dd925
266
- def self.devices
267
- # This list does not include iPad Pro 12.9-inch (3rd generation)
268
- # because it has same resolution as IOS_IPAD_PRO and will clobber
269
- return {
270
- ScreenSize::IOS_67 => [
271
- [1290, 2796],
272
- [2796, 1290]
273
- ],
274
- ScreenSize::IOS_65 => [
275
- [1242, 2688],
276
- [2688, 1242],
277
- [1284, 2778],
278
- [2778, 1284]
279
- ],
280
- ScreenSize::IOS_61 => [
281
- [1179, 2556],
282
- [2556, 1179]
283
- ],
284
- ScreenSize::IOS_58 => [
285
- [1125, 2436],
286
- [2436, 1125],
287
- [1170, 2532],
288
- [2532, 1170]
289
- ],
290
- ScreenSize::IOS_55 => [
291
- [1242, 2208],
292
- [2208, 1242]
293
- ],
294
- ScreenSize::IOS_47 => [
295
- [750, 1334],
296
- [1334, 750]
297
- ],
298
- ScreenSize::IOS_40 => [
299
- [640, 1096],
300
- [640, 1136],
301
- [1136, 600],
302
- [1136, 640]
303
- ],
304
- ScreenSize::IOS_35 => [
305
- [640, 920],
306
- [640, 960],
307
- [960, 600],
308
- [960, 640]
309
- ],
310
- ScreenSize::IOS_IPAD => [ # 9.7 inch
311
- [1024, 748],
312
- [1024, 768],
313
- [2048, 1496],
314
- [2048, 1536],
315
- [768, 1004], # portrait without status bar
316
- [768, 1024],
317
- [1536, 2008], # portrait without status bar
318
- [1536, 2048]
319
- ],
320
- ScreenSize::IOS_IPAD_10_5 => [
321
- [1668, 2224],
322
- [2224, 1668]
323
- ],
324
- ScreenSize::IOS_IPAD_11 => [
325
- [1668, 2388],
326
- [2388, 1668]
327
- ],
328
- ScreenSize::IOS_IPAD_PRO => [
329
- [2732, 2048],
330
- [2048, 2732]
331
- ],
332
- ScreenSize::MAC => [
333
- [1280, 800],
334
- [1440, 900],
335
- [2560, 1600],
336
- [2880, 1800]
337
- ],
338
- ScreenSize::IOS_APPLE_WATCH => [
339
- [312, 390]
340
- ],
341
- ScreenSize::IOS_APPLE_WATCH_SERIES4 => [
342
- [368, 448]
343
- ],
344
- ScreenSize::IOS_APPLE_WATCH_SERIES7 => [
345
- [396, 484]
346
- ],
347
- ScreenSize::IOS_APPLE_WATCH_ULTRA => [
348
- [410, 502]
349
- ],
350
- ScreenSize::APPLE_TV => [
351
- [1920, 1080],
352
- [3840, 2160]
353
- ]
354
- }
355
- end
232
+ path_component = Pathname.new(path).each_filename.to_a[-3]
233
+ is_imessage = path_component.eql?("iMessage")
234
+ devices = is_imessage ? DEVICE_RESOLUTIONS_MESSAGES : DEVICE_RESOLUTIONS
356
235
 
357
- def self.resolve_ipadpro_conflict_if_needed(screen_size, filename)
358
- is_3rd_gen = [
359
- "iPad Pro (12.9-inch) (3rd generation)", # Default simulator has this name
360
- "iPad Pro (12.9-inch) (4th generation)", # Default simulator has this name
361
- "iPad Pro (12.9-inch) (5th generation)", # Default simulator has this name
362
- "iPad Pro (12.9-inch) (6th generation)", # Default simulator has this name
363
- "IPAD_PRO_3GEN_129", # Screenshots downloaded from App Store Connect has this name
364
- "ipadPro129" # Legacy: screenshots downloaded from iTunes Connect used to have this name
365
- ].any? { |key| filename.include?(key) }
366
- if is_3rd_gen
367
- if screen_size == ScreenSize::IOS_IPAD_PRO
368
- return ScreenSize::IOS_IPAD_PRO_12_9
369
- elsif screen_size == ScreenSize::IOS_IPAD_PRO_MESSAGES
370
- return ScreenSize::IOS_IPAD_PRO_12_9_MESSAGES
371
- end
372
- end
373
- screen_size
374
- end
236
+ matching_display_type = devices.find { |_display_type, resolutions| resolutions.include?(size) }&.first
375
237
 
376
- def self.calculate_screen_size(path)
377
- size = FastImage.size(path)
238
+ return nil unless matching_display_type
378
239
 
379
- UI.user_error!("Could not find or parse file at path '#{path}'") if size.nil? || size.count == 0
240
+ return matching_display_type unless CONFLICTING_RESOLUTIONS.include?(size)
380
241
 
381
- # iMessage screenshots have same resolution as app screenshots so we need to distinguish them
382
- path_component = Pathname.new(path).each_filename.to_a[-3]
383
- devices = path_component.eql?("iMessage") ? self.device_messages : self.devices
242
+ path_lower = path.downcase
243
+
244
+ case size
245
+ # iPad Pro conflict
246
+ when [2048, 2732], [2732, 2048]
247
+ is_2gen = path_lower.include?("app_ipad_pro_129") ||
248
+ (path_lower.include?("12.9") && path_lower.include?("2nd generation")) # e.g. iPad Pro (12.9-inch) (2nd generation)
384
249
 
385
- devices.each do |screen_size, resolutions|
386
- if resolutions.include?(size)
387
- filename = Pathname.new(path).basename.to_s
388
- return resolve_ipadpro_conflict_if_needed(screen_size, filename)
250
+ # rubocop:disable Require/MissingRequireStatement
251
+ if is_2gen
252
+ return is_imessage ? DisplayType::IMESSAGE_APP_IPAD_PRO_129 : DisplayType::APP_IPAD_PRO_129
253
+ else
254
+ return is_imessage ? DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_129 : DisplayType::APP_IPAD_PRO_3GEN_129
389
255
  end
256
+ # Apple TV vs Vision Pro conflict
257
+ when [3840, 2160]
258
+ return path_lower.include?("vision") ? DisplayType::APP_APPLE_VISION_PRO : DisplayType::APP_APPLE_TV
259
+ # rubocop:enable Require/MissingRequireStatement
260
+ else
261
+ matching_display_type
390
262
  end
391
-
392
- nil
393
263
  end
394
264
  end
395
-
396
- ScreenSize = AppScreenshot::ScreenSize
397
265
  end
@@ -1,3 +1,5 @@
1
+ require_relative 'module'
2
+
1
3
  module Deliver
2
4
  # This is a convenient class that enumerates app store connect's screenshots in various degrees.
3
5
  class AppScreenshotIterator
@@ -77,10 +79,11 @@ module Deliver
77
79
  # iterate over screenshots per localization
78
80
  screenshots_per_language.each do |language, screenshots_for_language|
79
81
  localization = supported_localizations.find { |l| l.locale == language }
80
- screenshots_per_display_type = screenshots_for_language.reject { |screenshot| screenshot.device_type.nil? }.group_by(&:device_type)
82
+ screenshots_per_display_type = screenshots_for_language.reject { |screenshot| screenshot.display_type.nil? }.group_by(&:display_type)
81
83
 
82
84
  screenshots_per_display_type.each do |display_type, screenshots|
83
85
  # create AppScreenshotSet for given display_type if it doesn't exist
86
+ UI.verbose("Setting up screenshot set for #{language}, #{display_type}")
84
87
  app_screenshot_set = (app_screenshot_set_per_locale_and_display_type[language] || {})[display_type]
85
88
  app_screenshot_set ||= localization.create_app_screenshot_set(attributes: { screenshotDisplayType: display_type })
86
89