fastlane 2.219.0 → 2.221.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +86 -86
  3. data/bin/console +11 -0
  4. data/bin/match_file +60 -0
  5. data/deliver/lib/deliver/download_screenshots.rb +2 -1
  6. data/deliver/lib/deliver/generate_summary.rb +1 -1
  7. data/deliver/lib/deliver/options.rb +14 -0
  8. data/deliver/lib/deliver/runner.rb +4 -4
  9. data/deliver/lib/deliver/submit_for_review.rb +2 -2
  10. data/deliver/lib/deliver/upload_metadata.rb +43 -28
  11. data/deliver/lib/deliver/upload_screenshots.rb +15 -8
  12. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +2 -1
  13. data/fastlane/lib/fastlane/actions/appetize.rb +4 -0
  14. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +6 -2
  15. data/fastlane/lib/fastlane/actions/git_add.rb +17 -2
  16. data/fastlane/lib/fastlane/actions/mailgun.rb +30 -8
  17. data/fastlane/lib/fastlane/actions/onesignal.rb +14 -2
  18. data/fastlane/lib/fastlane/actions/spm.rb +7 -0
  19. data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +2 -1
  20. data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +4 -2
  21. data/fastlane/lib/fastlane/commands_generator.rb +9 -0
  22. data/fastlane/lib/fastlane/console.rb +24 -0
  23. data/fastlane/lib/fastlane/helper/sh_helper.rb +1 -1
  24. data/fastlane/lib/fastlane/lane_manager_base.rb +16 -8
  25. data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +2 -1
  26. data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +2 -1
  27. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +2 -1
  28. data/fastlane/lib/fastlane/runner.rb +2 -2
  29. data/fastlane/lib/fastlane/version.rb +2 -1
  30. data/fastlane/swift/Deliverfile.swift +1 -1
  31. data/fastlane/swift/DeliverfileProtocol.swift +9 -1
  32. data/fastlane/swift/Fastlane.swift +48 -11
  33. data/fastlane/swift/Gymfile.swift +1 -1
  34. data/fastlane/swift/GymfileProtocol.swift +1 -1
  35. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  36. data/fastlane/swift/Matchfile.swift +1 -1
  37. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  38. data/fastlane/swift/OptionalConfigValue.swift +2 -2
  39. data/fastlane/swift/Precheckfile.swift +1 -1
  40. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  41. data/fastlane/swift/Scanfile.swift +1 -1
  42. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  43. data/fastlane/swift/Screengrabfile.swift +1 -1
  44. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  45. data/fastlane/swift/Snapshotfile.swift +1 -1
  46. data/fastlane/swift/SnapshotfileProtocol.swift +3 -3
  47. data/fastlane/swift/formatting/Brewfile.lock.json +19 -19
  48. data/fastlane_core/lib/fastlane_core/cert_checker.rb +11 -8
  49. data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
  50. data/fastlane_core/lib/fastlane_core/helper.rb +0 -15
  51. data/fastlane_core/lib/fastlane_core/print_table.rb +16 -0
  52. data/fastlane_core/lib/fastlane_core/project.rb +5 -0
  53. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +0 -4
  54. data/fastlane_core/lib/fastlane_core/ui/help_formatter.rb +1 -5
  55. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +2 -0
  56. data/frameit/lib/frameit/device_types.rb +4 -0
  57. data/frameit/lib/frameit/editor.rb +20 -0
  58. data/gym/lib/gym/detect_values.rb +2 -0
  59. data/gym/lib/gym/module.rb +2 -2
  60. data/match/lib/assets/READMETemplate.md +3 -5
  61. data/match/lib/match/encryption/encryption.rb +154 -0
  62. data/match/lib/match/encryption/openssl.rb +7 -38
  63. data/match/lib/match/encryption.rb +1 -0
  64. data/match/lib/match/runner.rb +44 -6
  65. data/match/lib/match/storage/git_storage.rb +4 -3
  66. data/match/lib/match/storage/interface.rb +9 -5
  67. data/pilot/lib/pilot/build_manager.rb +14 -6
  68. data/pilot/lib/pilot/manager.rb +2 -2
  69. data/pilot/lib/pilot/options.rb +1 -1
  70. data/snapshot/lib/snapshot/options.rb +2 -2
  71. data/snapshot/lib/snapshot/setup.rb +1 -1
  72. data/spaceship/lib/spaceship/connect_api/api_client.rb +2 -2
  73. data/spaceship/lib/spaceship/connect_api/models/app.rb +28 -33
  74. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +17 -0
  75. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +44 -9
  76. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +30 -2
  77. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -2
  78. data/spaceship/lib/spaceship/connect_api/models/device.rb +11 -6
  79. data/spaceship/lib/spaceship/connect_api/models/profile.rb +8 -1
  80. data/spaceship/lib/spaceship/connect_api/provisioning/client.rb +1 -1
  81. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +31 -22
  82. data/spaceship/lib/spaceship/connect_api/testflight/client.rb +1 -1
  83. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +47 -43
  84. data/spaceship/lib/spaceship/connect_api/token.rb +9 -3
  85. data/spaceship/lib/spaceship/connect_api/tunes/client.rb +1 -1
  86. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +96 -90
  87. data/spaceship/lib/spaceship/connect_api/users/client.rb +1 -1
  88. data/spaceship/lib/spaceship/connect_api/users/users.rb +15 -11
  89. data/spaceship/lib/spaceship/connect_api.rb +5 -2
  90. data/spaceship/lib/spaceship/portal/certificate.rb +2 -2
  91. data/spaceship/lib/spaceship/portal/provisioning_profile.rb +8 -1
  92. data/spaceship/lib/spaceship/stats_middleware.rb +2 -2
  93. data/trainer/lib/trainer/xcresult.rb +6 -10
  94. metadata +50 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc5ecf6d8cf5ad100811fa9a386cf6bdc02d8e4054663e2c3a59d94624a7cda8
4
- data.tar.gz: 4bf38a96eba5cf4cb1918155136ead760e2462e8b2bdbd19bf2f7f29afbb39a3
3
+ metadata.gz: acc49f980e34ecc25b6072476316fec87d28cc297821ba0a97456186f7464d28
4
+ data.tar.gz: f9d8e7d4752ea516634aace406c63f972cf162d7162dc9967480f0582e9c4866
5
5
  SHA512:
6
- metadata.gz: 67749a0ada8ac8654b5d3b42221e41562249a014435e9f0bf8354e441370b072e34a25e422d40c81266a1395969d56c8898e6e0492d7d17b82e2c98864d97791
7
- data.tar.gz: 7e9d404f597ad89a09df94ca1c51b4f1bf6a894493cf66c6efb69eefd93bce34e429407d80cdb289a2170b70f9619ef4f8f77af1065c78aa3ba6a6602540b034
6
+ metadata.gz: 4412e52410d0082b59032b34e38c62e90d4a26ad6c9fdd86169b6546b1ade46e4536f90d9eb39afed28f766ac31713cf5577cf2af3ef90bde818ffb49ca0ee7d
7
+ data.tar.gz: 228d527f5c0956e4f84ab797a12ace580d52e2632a957a829e0b2996012caf55998221441a0b9c8d2d25ccacc992a682ce22e36eb40cb98748be70fb3242a3c0
data/README.md CHANGED
@@ -35,23 +35,43 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
35
35
  <!-- This table is regenerated and resorted on each release -->
36
36
  <table id='team'>
37
37
  <tr>
38
- <td id='manu-wallner'>
39
- <a href='https://github.com/milch'>
40
- <img src='https://github.com/milch.png' width='140px;'>
41
- </a>
42
- <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
43
- </td>
44
38
  <td id='joshua-liebowitz'>
45
39
  <a href='https://github.com/taquitos'>
46
40
  <img src='https://github.com/taquitos.png' width='140px;'>
47
41
  </a>
48
42
  <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
49
43
  </td>
50
- <td id='danielle-tomlinson'>
51
- <a href='https://github.com/endocrimes'>
52
- <img src='https://github.com/endocrimes.png' width='140px;'>
44
+ <td id='iulian-onofrei'>
45
+ <a href='https://github.com/revolter'>
46
+ <img src='https://github.com/revolter.png' width='140px;'>
53
47
  </a>
54
- <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
48
+ <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
49
+ </td>
50
+ <td id='maksym-grebenets'>
51
+ <a href='https://github.com/mgrebenets'>
52
+ <img src='https://github.com/mgrebenets.png' width='140px;'>
53
+ </a>
54
+ <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
55
+ </td>
56
+ <td id='roger-oba'>
57
+ <a href='https://github.com/rogerluan'>
58
+ <img src='https://github.com/rogerluan.png' width='140px;'>
59
+ </a>
60
+ <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
61
+ </td>
62
+ <td id='jan-piotrowski'>
63
+ <a href='https://github.com/janpio'>
64
+ <img src='https://github.com/janpio.png' width='140px;'>
65
+ </a>
66
+ <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td id='jimmy-dee'>
71
+ <a href='https://github.com/jdee'>
72
+ <img src='https://github.com/jdee.png' width='140px;'>
73
+ </a>
74
+ <h4 align='center'>Jimmy Dee</h4>
55
75
  </td>
56
76
  <td id='satoshi-namai'>
57
77
  <a href='https://github.com/ainame'>
@@ -59,11 +79,23 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
59
79
  </a>
60
80
  <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
61
81
  </td>
62
- <td id='felix-krause'>
63
- <a href='https://github.com/KrauseFx'>
64
- <img src='https://github.com/KrauseFx.png' width='140px;'>
82
+ <td id='manu-wallner'>
83
+ <a href='https://github.com/milch'>
84
+ <img src='https://github.com/milch.png' width='140px;'>
65
85
  </a>
66
- <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
86
+ <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
87
+ </td>
88
+ <td id='jorge-revuelta-h'>
89
+ <a href='https://github.com/minuscorp'>
90
+ <img src='https://github.com/minuscorp.png' width='140px;'>
91
+ </a>
92
+ <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
93
+ </td>
94
+ <td id='fumiya-nakamura'>
95
+ <a href='https://github.com/nafu'>
96
+ <img src='https://github.com/nafu.png' width='140px;'>
97
+ </a>
98
+ <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
67
99
  </td>
68
100
  </tr>
69
101
  <tr>
@@ -73,18 +105,32 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
73
105
  </a>
74
106
  <h4 align='center'>Łukasz Grabowski</h4>
75
107
  </td>
76
- <td id='maksym-grebenets'>
77
- <a href='https://github.com/mgrebenets'>
78
- <img src='https://github.com/mgrebenets.png' width='140px;'>
108
+ <td id='matthew-ellis'>
109
+ <a href='https://github.com/matthewellis'>
110
+ <img src='https://github.com/matthewellis.png' width='140px;'>
79
111
  </a>
80
- <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
112
+ <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
81
113
  </td>
82
- <td id='fumiya-nakamura'>
83
- <a href='https://github.com/nafu'>
84
- <img src='https://github.com/nafu.png' width='140px;'>
114
+ <td id='olivier-halligon'>
115
+ <a href='https://github.com/AliSoftware'>
116
+ <img src='https://github.com/AliSoftware.png' width='140px;'>
85
117
  </a>
86
- <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
118
+ <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
119
+ </td>
120
+ <td id='aaron-brager'>
121
+ <a href='https://github.com/getaaron'>
122
+ <img src='https://github.com/getaaron.png' width='140px;'>
123
+ </a>
124
+ <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
125
+ </td>
126
+ <td id='helmut-januschka'>
127
+ <a href='https://github.com/hjanuschka'>
128
+ <img src='https://github.com/hjanuschka.png' width='140px;'>
129
+ </a>
130
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
87
131
  </td>
132
+ </tr>
133
+ <tr>
88
134
  <td id='jérôme-lacoste'>
89
135
  <a href='https://github.com/lacostej'>
90
136
  <img src='https://github.com/lacostej.png' width='140px;'>
@@ -97,45 +143,31 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
97
143
  </a>
98
144
  <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
99
145
  </td>
100
- </tr>
101
- <tr>
102
- <td id='helmut-januschka'>
103
- <a href='https://github.com/hjanuschka'>
104
- <img src='https://github.com/hjanuschka.png' width='140px;'>
105
- </a>
106
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
107
- </td>
108
- <td id='manish-rathi'>
109
- <a href='https://github.com/crazymanish'>
110
- <img src='https://github.com/crazymanish.png' width='140px;'>
111
- </a>
112
- <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
113
- </td>
114
146
  <td id='max-ott'>
115
147
  <a href='https://github.com/max-ott'>
116
148
  <img src='https://github.com/max-ott.png' width='140px;'>
117
149
  </a>
118
150
  <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
119
151
  </td>
120
- <td id='jimmy-dee'>
121
- <a href='https://github.com/jdee'>
122
- <img src='https://github.com/jdee.png' width='140px;'>
152
+ <td id='manish-rathi'>
153
+ <a href='https://github.com/crazymanish'>
154
+ <img src='https://github.com/crazymanish.png' width='140px;'>
123
155
  </a>
124
- <h4 align='center'>Jimmy Dee</h4>
156
+ <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
125
157
  </td>
126
- <td id='roger-oba'>
127
- <a href='https://github.com/rogerluan'>
128
- <img src='https://github.com/rogerluan.png' width='140px;'>
158
+ <td id='kohki-miki'>
159
+ <a href='https://github.com/giginet'>
160
+ <img src='https://github.com/giginet.png' width='140px;'>
129
161
  </a>
130
- <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
162
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
131
163
  </td>
132
164
  </tr>
133
165
  <tr>
134
- <td id='iulian-onofrei'>
135
- <a href='https://github.com/revolter'>
136
- <img src='https://github.com/revolter.png' width='140px;'>
166
+ <td id='danielle-tomlinson'>
167
+ <a href='https://github.com/endocrimes'>
168
+ <img src='https://github.com/endocrimes.png' width='140px;'>
137
169
  </a>
138
- <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
170
+ <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
139
171
  </td>
140
172
  <td id='josh-holtz'>
141
173
  <a href='https://github.com/joshdholtz'>
@@ -143,6 +175,12 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
143
175
  </a>
144
176
  <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
145
177
  </td>
178
+ <td id='felix-krause'>
179
+ <a href='https://github.com/KrauseFx'>
180
+ <img src='https://github.com/KrauseFx.png' width='140px;'>
181
+ </a>
182
+ <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
183
+ </td>
146
184
  <td id='daniel-jankowski'>
147
185
  <a href='https://github.com/mollyIV'>
148
186
  <img src='https://github.com/mollyIV.png' width='140px;'>
@@ -155,12 +193,6 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
155
193
  </a>
156
194
  <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
157
195
  </td>
158
- <td id='jan-piotrowski'>
159
- <a href='https://github.com/janpio'>
160
- <img src='https://github.com/janpio.png' width='140px;'>
161
- </a>
162
- <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
163
- </td>
164
196
  </tr>
165
197
  <tr>
166
198
  <td id='luka-mirosevic'>
@@ -169,38 +201,6 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
169
201
  </a>
170
202
  <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
171
203
  </td>
172
- <td id='kohki-miki'>
173
- <a href='https://github.com/giginet'>
174
- <img src='https://github.com/giginet.png' width='140px;'>
175
- </a>
176
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
177
- </td>
178
- <td id='aaron-brager'>
179
- <a href='https://github.com/getaaron'>
180
- <img src='https://github.com/getaaron.png' width='140px;'>
181
- </a>
182
- <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
183
- </td>
184
- <td id='olivier-halligon'>
185
- <a href='https://github.com/AliSoftware'>
186
- <img src='https://github.com/AliSoftware.png' width='140px;'>
187
- </a>
188
- <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
189
- </td>
190
- <td id='jorge-revuelta-h'>
191
- <a href='https://github.com/minuscorp'>
192
- <img src='https://github.com/minuscorp.png' width='140px;'>
193
- </a>
194
- <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
195
- </td>
196
- </tr>
197
- <tr>
198
- <td id='matthew-ellis'>
199
- <a href='https://github.com/matthewellis'>
200
- <img src='https://github.com/matthewellis.png' width='140px;'>
201
- </a>
202
- <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
203
- </td>
204
204
  </table>
205
205
 
206
206
  Special thanks to all [contributors](https://github.com/fastlane/fastlane/graphs/contributors) for extending and improving _fastlane_.
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fastlane"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ require "irb"
11
+ IRB.start(__FILE__)
data/bin/match_file ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ require 'match'
3
+
4
+ # CLI to encrypt/decrypt files using fastlane match encryption layer
5
+
6
+ def usage
7
+ puts("USAGE: [encrypt|decrypt] input_path [output_path]")
8
+ exit(-1)
9
+ end
10
+
11
+ if ARGV.count < 2 || ARGV.count > 3
12
+ usage
13
+ end
14
+
15
+ method_name = ARGV.shift
16
+ unless ['encrypt', 'decrypt'].include?(method_name)
17
+ usage
18
+ end
19
+
20
+ input_file = ARGV.shift
21
+
22
+ if ARGV.count > 0
23
+ output_file = ARGV.shift
24
+ else
25
+ output_file = input_file
26
+ end
27
+
28
+ def ask_password(msg)
29
+ ask(msg) do |q|
30
+ q.whitespace = :chomp
31
+ q.echo = "*"
32
+ end
33
+ end
34
+
35
+ def ask_password_twice
36
+ password = ask_password("Enter the password: ")
37
+ return "" if password.empty? || password == "\u0003" # CTRL-C char
38
+ other = ask_password("Enter the password again: ")
39
+ if other == password
40
+ return password
41
+ else
42
+ return nil
43
+ end
44
+ end
45
+
46
+ # read the password
47
+ password = nil
48
+ loop do
49
+ password = ask_password_twice
50
+ break unless password.nil?
51
+ end
52
+
53
+ exit if password.empty?
54
+
55
+ begin
56
+ Match::Encryption::MatchFileEncryption.new.send(method_name, file_path: input_file, password: password, output_path: output_file)
57
+ rescue => e
58
+ puts("ERROR #{method_name}ing. [#{e}]. Check your password")
59
+ usage
60
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative 'module'
2
2
  require 'spaceship'
3
+ require 'open-uri'
3
4
 
4
5
  module Deliver
5
6
  class DownloadScreenshots
@@ -67,7 +68,7 @@ module Deliver
67
68
  end
68
69
 
69
70
  path = File.join(containing_folder, file_name)
70
- File.binwrite(path, FastlaneCore::Helper.open_uri(url).read)
71
+ File.binwrite(path, URI.open(url).read)
71
72
  end
72
73
  end
73
74
  end
@@ -6,7 +6,7 @@ module Deliver
6
6
  class GenerateSummary
7
7
  def run(options)
8
8
  screenshots = UploadScreenshots.new.collect_screenshots(options)
9
- UploadMetadata.new.load_from_filesystem(options)
9
+ UploadMetadata.new(options).load_from_filesystem
10
10
  HtmlGenerator.new.render(options, screenshots, '.')
11
11
  end
12
12
  end
@@ -162,6 +162,11 @@ module Deliver
162
162
  description: "Clear all previously uploaded screenshots before uploading the new ones",
163
163
  type: Boolean,
164
164
  default_value: false),
165
+ FastlaneCore::ConfigItem.new(key: :screenshot_processing_timeout,
166
+ env_name: "DELIVER_SCREENSHOT_PROCESSING_TIMEOUT",
167
+ description: "Timeout in seconds to wait before considering screenshot processing as failed, used to handle cases where uploads to the App Store are stuck in processing",
168
+ type: Integer,
169
+ default_value: 3600),
165
170
  FastlaneCore::ConfigItem.new(key: :sync_screenshots,
166
171
  env_name: "DELIVER_SYNC_SCREENSHOTS",
167
172
  description: "Sync screenshots with local ones. This is currently beta option so set true to 'FASTLANE_ENABLE_BETA_DELIVER_SYNC_SCREENSHOTS' environment variable as well",
@@ -182,6 +187,15 @@ module Deliver
182
187
  description: "Rejects the previously submitted build if it's in a state where it's possible",
183
188
  type: Boolean,
184
189
  default_value: false),
190
+ FastlaneCore::ConfigItem.new(key: :version_check_wait_retry_limit,
191
+ env_name: "DELIVER_VERSION_CHECK_WAIT_RETRY_LIMIT",
192
+ description: "After submitting a new version, App Store Connect takes some time to recognize the new version and we must wait until it's available before attempting to upload metadata for it. There is a mechanism that will check if it's available and retry with an exponential backoff if it's not available yet. " \
193
+ "This option specifies how many times we should retry before giving up. Setting this to a value below 5 is not recommended and will likely cause failures. Increase this parameter when Apple servers seem to be degraded or slow",
194
+ type: Integer,
195
+ default_value: 7,
196
+ verify_block: proc do |value|
197
+ UI.user_error!("'#{value}' needs to be greater than 0") if value <= 0
198
+ end),
185
199
 
186
200
  # release
187
201
  FastlaneCore::ConfigItem.new(key: :automatic_release,
@@ -135,21 +135,21 @@ module Deliver
135
135
 
136
136
  # Upload all metadata, screenshots, pricing information, etc. to App Store Connect
137
137
  def upload_metadata
138
- upload_metadata = UploadMetadata.new
138
+ upload_metadata = UploadMetadata.new(options)
139
139
  upload_screenshots = UploadScreenshots.new
140
140
 
141
141
  # First, collect all the things for the HTML Report
142
142
  screenshots = upload_screenshots.collect_screenshots(options)
143
- upload_metadata.load_from_filesystem(options)
143
+ upload_metadata.load_from_filesystem
144
144
 
145
145
  # Assign "default" values to all languages
146
- upload_metadata.assign_defaults(options)
146
+ upload_metadata.assign_defaults
147
147
 
148
148
  # Validate
149
149
  validate_html(screenshots)
150
150
 
151
151
  # Commit
152
- upload_metadata.upload(options)
152
+ upload_metadata.upload
153
153
 
154
154
  if options[:sync_screenshots]
155
155
  sync_screenshots = SyncScreenshots.new(app: Deliver.cache[:app], platform: Spaceship::ConnectAPI::Platform.map(options[:platform]))
@@ -51,11 +51,11 @@ module Deliver
51
51
  10.times do
52
52
  version_with_latest_info = Spaceship::ConnectAPI::AppStoreVersion.get(app_store_version_id: version.id)
53
53
 
54
- if version_with_latest_info.app_store_state == Spaceship::ConnectAPI::AppStoreVersion::AppStoreState::READY_FOR_REVIEW
54
+ if version_with_latest_info.app_version_state == Spaceship::ConnectAPI::AppStoreVersion::AppVersionState::READY_FOR_REVIEW
55
55
  break
56
56
  end
57
57
 
58
- UI.message("Waiting for the state of the version to become #{Spaceship::ConnectAPI::AppStoreVersion::AppStoreState::READY_FOR_REVIEW}...")
58
+ UI.message("Waiting for the state of the version to become #{Spaceship::ConnectAPI::AppStoreVersion::AppVersionState::READY_FOR_REVIEW}...")
59
59
 
60
60
  sleep(15)
61
61
  end
@@ -78,19 +78,25 @@ module Deliver
78
78
 
79
79
  require_relative 'loader'
80
80
 
81
+ attr_accessor :options
82
+
83
+ def initialize(options)
84
+ self.options = options
85
+ end
86
+
81
87
  # Make sure to call `load_from_filesystem` before calling upload
82
- def upload(options)
88
+ def upload
83
89
  return if options[:skip_metadata]
84
90
 
85
91
  app = Deliver.cache[:app]
86
92
 
87
93
  platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
88
94
 
89
- enabled_languages = detect_languages(options)
95
+ enabled_languages = detect_languages
90
96
 
91
- app_store_version_localizations = verify_available_version_languages!(options, app, enabled_languages) unless options[:edit_live]
97
+ app_store_version_localizations = verify_available_version_languages!(app, enabled_languages) unless options[:edit_live]
92
98
  app_info = fetch_edit_app_info(app)
93
- app_info_localizations = verify_available_info_languages!(options, app, app_info, enabled_languages) unless options[:edit_live] || !updating_localized_app_info?(options, app, app_info)
99
+ app_info_localizations = verify_available_info_languages!(app, app_info, enabled_languages) unless options[:edit_live] || !updating_localized_app_info?(app, app_info)
94
100
 
95
101
  if options[:edit_live]
96
102
  # not all values are editable when using live_version
@@ -342,9 +348,9 @@ module Deliver
342
348
  end
343
349
  end
344
350
 
345
- set_review_information(version, options)
346
- set_review_attachment_file(version, options)
347
- set_app_rating(app_info, options)
351
+ review_information(version)
352
+ review_attachment_file(version)
353
+ app_rating(app_info)
348
354
  end
349
355
 
350
356
  # rubocop:enable Metrics/PerceivedComplexity
@@ -360,12 +366,12 @@ module Deliver
360
366
  end
361
367
 
362
368
  # If the user is using the 'default' language, then assign values where they are needed
363
- def assign_defaults(options)
369
+ def assign_defaults
364
370
  # Normalizes languages keys from symbols to strings
365
- normalize_language_keys(options)
371
+ normalize_language_keys
366
372
 
367
373
  # Build a complete list of the required languages
368
- enabled_languages = detect_languages(options)
374
+ enabled_languages = detect_languages
369
375
 
370
376
  # Get all languages used in existing settings
371
377
  (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|
@@ -402,7 +408,7 @@ module Deliver
402
408
  end
403
409
  end
404
410
 
405
- def detect_languages(options)
411
+ def detect_languages
406
412
  # Build a complete list of the required languages
407
413
  enabled_languages = options[:languages] || []
408
414
 
@@ -427,40 +433,49 @@ module Deliver
427
433
  .uniq
428
434
  end
429
435
 
430
- def fetch_edit_app_store_version(app, platform, wait_time: 10)
431
- retry_if_nil("Cannot find edit app store version", wait_time: wait_time) do
436
+ def fetch_edit_app_store_version(app, platform)
437
+ retry_if_nil("Cannot find edit app store version") do
432
438
  app.get_edit_app_store_version(platform: platform)
433
439
  end
434
440
  end
435
441
 
436
- def fetch_edit_app_info(app, wait_time: 10)
437
- retry_if_nil("Cannot find edit app info", wait_time: wait_time) do
442
+ def fetch_edit_app_info(app)
443
+ retry_if_nil("Cannot find edit app info") do
438
444
  app.fetch_edit_app_info
439
445
  end
440
446
  end
441
447
 
442
- def fetch_live_app_info(app, wait_time: 10)
443
- retry_if_nil("Cannot find live app info", wait_time: wait_time) do
448
+ def fetch_live_app_info(app)
449
+ retry_if_nil("Cannot find live app info") do
444
450
  app.fetch_live_app_info
445
451
  end
446
452
  end
447
453
 
448
- def retry_if_nil(message, tries: 5, wait_time: 10)
454
+ # Retries a block of code if the return value is nil, with an exponential backoff.
455
+ def retry_if_nil(message)
456
+ tries = options[:version_check_wait_retry_limit]
457
+ wait_time = 10
449
458
  loop do
450
459
  tries -= 1
451
460
 
452
461
  value = yield
453
462
  return value if value
454
463
 
455
- UI.message("#{message}... Retrying after #{wait_time} seconds (remaining: #{tries})")
456
- sleep(wait_time)
464
+ # Calculate sleep time to be the lesser of the exponential backoff or 5 minutes.
465
+ # This prevents problems with CI's console output timeouts (of usually 10 minutes), and also
466
+ # speeds up the retry time for the user, as waiting longer than 5 minutes is a too long wait for a retry.
467
+ sleep_time = [wait_time * 2, 5 * 60].min
468
+ UI.message("#{message}... Retrying after #{sleep_time} seconds (remaining: #{tries})")
469
+ Kernel.sleep(sleep_time)
457
470
 
458
471
  return nil if tries.zero?
472
+
473
+ wait_time *= 2 # Double the wait time for the next iteration
459
474
  end
460
475
  end
461
476
 
462
477
  # Checking if the metadata to update includes localised App Info
463
- def updating_localized_app_info?(options, app, app_info)
478
+ def updating_localized_app_info?(app, app_info)
464
479
  app_info ||= fetch_live_app_info(app)
465
480
  unless app_info
466
481
  UI.important("Can't find edit or live App info. Skipping upload.")
@@ -499,7 +514,7 @@ module Deliver
499
514
  end
500
515
 
501
516
  # Finding languages to enable
502
- def verify_available_info_languages!(options, app, app_info, languages)
517
+ def verify_available_info_languages!(app, app_info, languages)
503
518
  unless app_info
504
519
  UI.user_error!("Cannot update languages - could not find an editable 'App Info'. Verify that your app is in one of the editable states in App Store Connect")
505
520
  return
@@ -531,7 +546,7 @@ module Deliver
531
546
  end
532
547
 
533
548
  # Finding languages to enable
534
- def verify_available_version_languages!(options, app, languages)
549
+ def verify_available_version_languages!(app, languages)
535
550
  platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
536
551
  version = fetch_edit_app_store_version(app, platform)
537
552
 
@@ -566,7 +581,7 @@ module Deliver
566
581
  end
567
582
 
568
583
  # Loads the metadata files and stores them into the options object
569
- def load_from_filesystem(options)
584
+ def load_from_filesystem
570
585
  return if options[:skip_metadata]
571
586
 
572
587
  # Load localised data
@@ -623,7 +638,7 @@ module Deliver
623
638
  private
624
639
 
625
640
  # Normalizes languages keys from symbols to strings
626
- def normalize_language_keys(options)
641
+ def normalize_language_keys
627
642
  (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|
628
643
  current = options[key]
629
644
  next unless current && current.kind_of?(Hash)
@@ -636,7 +651,7 @@ module Deliver
636
651
  options
637
652
  end
638
653
 
639
- def set_review_information(version, options)
654
+ def review_information(version)
640
655
  info = options[:app_review_information]
641
656
  return if info.nil? || info.empty?
642
657
 
@@ -669,7 +684,7 @@ module Deliver
669
684
  end
670
685
  end
671
686
 
672
- def set_review_attachment_file(version, options)
687
+ def review_attachment_file(version)
673
688
  app_store_review_detail = version.fetch_app_store_review_detail
674
689
  app_store_review_attachments = app_store_review_detail.app_store_review_attachments || []
675
690
 
@@ -687,7 +702,7 @@ module Deliver
687
702
  end
688
703
  end
689
704
 
690
- def set_app_rating(app_info, options)
705
+ def app_rating(app_info)
691
706
  return unless options[:app_rating_config_path]
692
707
 
693
708
  require 'json'