fastlane 2.219.0 → 2.220.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 (78) 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/upload_metadata.rb +43 -28
  10. data/deliver/lib/deliver/upload_screenshots.rb +15 -8
  11. data/fastlane/lib/fastlane/actions/appetize.rb +4 -0
  12. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +6 -2
  13. data/fastlane/lib/fastlane/actions/git_add.rb +17 -2
  14. data/fastlane/lib/fastlane/actions/mailgun.rb +30 -8
  15. data/fastlane/lib/fastlane/actions/onesignal.rb +14 -2
  16. data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +2 -1
  17. data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +4 -2
  18. data/fastlane/lib/fastlane/commands_generator.rb +9 -0
  19. data/fastlane/lib/fastlane/console.rb +24 -0
  20. data/fastlane/lib/fastlane/helper/sh_helper.rb +1 -1
  21. data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +2 -1
  22. data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +2 -1
  23. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +2 -1
  24. data/fastlane/lib/fastlane/version.rb +2 -1
  25. data/fastlane/swift/Deliverfile.swift +1 -1
  26. data/fastlane/swift/DeliverfileProtocol.swift +9 -1
  27. data/fastlane/swift/Fastlane.swift +41 -8
  28. data/fastlane/swift/Gymfile.swift +1 -1
  29. data/fastlane/swift/GymfileProtocol.swift +1 -1
  30. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  31. data/fastlane/swift/Matchfile.swift +1 -1
  32. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  33. data/fastlane/swift/OptionalConfigValue.swift +2 -2
  34. data/fastlane/swift/Precheckfile.swift +1 -1
  35. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  36. data/fastlane/swift/Scanfile.swift +1 -1
  37. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  38. data/fastlane/swift/Screengrabfile.swift +1 -1
  39. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  40. data/fastlane/swift/Snapshotfile.swift +1 -1
  41. data/fastlane/swift/SnapshotfileProtocol.swift +3 -3
  42. data/fastlane/swift/formatting/Brewfile.lock.json +17 -17
  43. data/fastlane_core/lib/fastlane_core/cert_checker.rb +11 -8
  44. data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
  45. data/fastlane_core/lib/fastlane_core/helper.rb +0 -15
  46. data/fastlane_core/lib/fastlane_core/print_table.rb +16 -0
  47. data/fastlane_core/lib/fastlane_core/project.rb +5 -0
  48. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +0 -4
  49. data/fastlane_core/lib/fastlane_core/ui/help_formatter.rb +1 -5
  50. data/frameit/lib/frameit/device_types.rb +4 -0
  51. data/frameit/lib/frameit/editor.rb +20 -0
  52. data/gym/lib/gym/detect_values.rb +2 -0
  53. data/gym/lib/gym/module.rb +2 -2
  54. data/match/lib/assets/READMETemplate.md +3 -5
  55. data/match/lib/match/encryption/encryption.rb +154 -0
  56. data/match/lib/match/encryption/openssl.rb +7 -38
  57. data/match/lib/match/encryption.rb +1 -0
  58. data/match/lib/match/runner.rb +45 -6
  59. data/match/lib/match/storage/git_storage.rb +4 -3
  60. data/match/lib/match/storage/interface.rb +9 -5
  61. data/pilot/lib/pilot/build_manager.rb +5 -2
  62. data/pilot/lib/pilot/manager.rb +2 -2
  63. data/pilot/lib/pilot/options.rb +1 -1
  64. data/snapshot/lib/snapshot/options.rb +2 -2
  65. data/snapshot/lib/snapshot/setup.rb +1 -1
  66. data/spaceship/lib/spaceship/connect_api/api_client.rb +1 -1
  67. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +17 -0
  68. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +44 -9
  69. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +30 -2
  70. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -2
  71. data/spaceship/lib/spaceship/connect_api/models/device.rb +11 -6
  72. data/spaceship/lib/spaceship/connect_api/models/profile.rb +8 -1
  73. data/spaceship/lib/spaceship/connect_api/token.rb +2 -1
  74. data/spaceship/lib/spaceship/connect_api.rb +5 -2
  75. data/spaceship/lib/spaceship/portal/certificate.rb +2 -2
  76. data/spaceship/lib/spaceship/portal/provisioning_profile.rb +8 -1
  77. data/trainer/lib/trainer/xcresult.rb +6 -10
  78. metadata +46 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc5ecf6d8cf5ad100811fa9a386cf6bdc02d8e4054663e2c3a59d94624a7cda8
4
- data.tar.gz: 4bf38a96eba5cf4cb1918155136ead760e2462e8b2bdbd19bf2f7f29afbb39a3
3
+ metadata.gz: eec1401cd6a8a8a9e9c48fed9969a6ab44348fa672c2b75464b3265000dab288
4
+ data.tar.gz: 1c7bc580641838525e4705a83633da89a38f225dfaea07ba9ee1ee2f54e8676c
5
5
  SHA512:
6
- metadata.gz: 67749a0ada8ac8654b5d3b42221e41562249a014435e9f0bf8354e441370b072e34a25e422d40c81266a1395969d56c8898e6e0492d7d17b82e2c98864d97791
7
- data.tar.gz: 7e9d404f597ad89a09df94ca1c51b4f1bf6a894493cf66c6efb69eefd93bce34e429407d80cdb289a2170b70f9619ef4f8f77af1065c78aa3ba6a6602540b034
6
+ metadata.gz: 3d88cbca7c40d2882d7442db21b0725b2da0e641f267f0c581cd2c7344a5e220a46cdd84eae861609d0ed9940226953cb6a03094d6b0019eaca578e7fb6872ae
7
+ data.tar.gz: 830456faecb0a07cfda4f48d7e5bb6ea0fa558553a43ae59f18a2ae702062d6202d31f2285dc4bea2310bceb890cfde6fc848ebcfeb0dbc71eb4911938a018e7
data/README.md CHANGED
@@ -35,38 +35,50 @@ 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='iulian-onofrei'>
39
+ <a href='https://github.com/revolter'>
40
+ <img src='https://github.com/revolter.png' width='140px;'>
41
+ </a>
42
+ <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
43
+ </td>
38
44
  <td id='manu-wallner'>
39
45
  <a href='https://github.com/milch'>
40
46
  <img src='https://github.com/milch.png' width='140px;'>
41
47
  </a>
42
48
  <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
43
49
  </td>
44
- <td id='joshua-liebowitz'>
45
- <a href='https://github.com/taquitos'>
46
- <img src='https://github.com/taquitos.png' width='140px;'>
47
- </a>
48
- <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
49
- </td>
50
- <td id='danielle-tomlinson'>
51
- <a href='https://github.com/endocrimes'>
52
- <img src='https://github.com/endocrimes.png' width='140px;'>
50
+ <td id='fumiya-nakamura'>
51
+ <a href='https://github.com/nafu'>
52
+ <img src='https://github.com/nafu.png' width='140px;'>
53
53
  </a>
54
- <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
54
+ <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
55
55
  </td>
56
- <td id='satoshi-namai'>
57
- <a href='https://github.com/ainame'>
58
- <img src='https://github.com/ainame.png' width='140px;'>
56
+ <td id='helmut-januschka'>
57
+ <a href='https://github.com/hjanuschka'>
58
+ <img src='https://github.com/hjanuschka.png' width='140px;'>
59
59
  </a>
60
- <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
60
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
61
61
  </td>
62
- <td id='felix-krause'>
63
- <a href='https://github.com/KrauseFx'>
64
- <img src='https://github.com/KrauseFx.png' width='140px;'>
62
+ <td id='jorge-revuelta-h'>
63
+ <a href='https://github.com/minuscorp'>
64
+ <img src='https://github.com/minuscorp.png' width='140px;'>
65
65
  </a>
66
- <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
66
+ <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
67
67
  </td>
68
68
  </tr>
69
69
  <tr>
70
+ <td id='jan-piotrowski'>
71
+ <a href='https://github.com/janpio'>
72
+ <img src='https://github.com/janpio.png' width='140px;'>
73
+ </a>
74
+ <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
75
+ </td>
76
+ <td id='daniel-jankowski'>
77
+ <a href='https://github.com/mollyIV'>
78
+ <img src='https://github.com/mollyIV.png' width='140px;'>
79
+ </a>
80
+ <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
81
+ </td>
70
82
  <td id='łukasz-grabowski'>
71
83
  <a href='https://github.com/lucgrabowski'>
72
84
  <img src='https://github.com/lucgrabowski.png' width='140px;'>
@@ -79,18 +91,6 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
79
91
  </a>
80
92
  <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
81
93
  </td>
82
- <td id='fumiya-nakamura'>
83
- <a href='https://github.com/nafu'>
84
- <img src='https://github.com/nafu.png' width='140px;'>
85
- </a>
86
- <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
87
- </td>
88
- <td id='jérôme-lacoste'>
89
- <a href='https://github.com/lacostej'>
90
- <img src='https://github.com/lacostej.png' width='140px;'>
91
- </a>
92
- <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
93
- </td>
94
94
  <td id='stefan-natchev'>
95
95
  <a href='https://github.com/snatchev'>
96
96
  <img src='https://github.com/snatchev.png' width='140px;'>
@@ -99,11 +99,11 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
99
99
  </td>
100
100
  </tr>
101
101
  <tr>
102
- <td id='helmut-januschka'>
103
- <a href='https://github.com/hjanuschka'>
104
- <img src='https://github.com/hjanuschka.png' width='140px;'>
102
+ <td id='josh-holtz'>
103
+ <a href='https://github.com/joshdholtz'>
104
+ <img src='https://github.com/joshdholtz.png' width='140px;'>
105
105
  </a>
106
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
106
+ <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
107
107
  </td>
108
108
  <td id='manish-rathi'>
109
109
  <a href='https://github.com/crazymanish'>
@@ -111,75 +111,75 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
111
111
  </a>
112
112
  <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
113
113
  </td>
114
- <td id='max-ott'>
115
- <a href='https://github.com/max-ott'>
116
- <img src='https://github.com/max-ott.png' width='140px;'>
114
+ <td id='felix-krause'>
115
+ <a href='https://github.com/KrauseFx'>
116
+ <img src='https://github.com/KrauseFx.png' width='140px;'>
117
117
  </a>
118
- <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
118
+ <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
119
119
  </td>
120
- <td id='jimmy-dee'>
121
- <a href='https://github.com/jdee'>
122
- <img src='https://github.com/jdee.png' width='140px;'>
120
+ <td id='kohki-miki'>
121
+ <a href='https://github.com/giginet'>
122
+ <img src='https://github.com/giginet.png' width='140px;'>
123
123
  </a>
124
- <h4 align='center'>Jimmy Dee</h4>
124
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
125
125
  </td>
126
- <td id='roger-oba'>
127
- <a href='https://github.com/rogerluan'>
128
- <img src='https://github.com/rogerluan.png' width='140px;'>
126
+ <td id='joshua-liebowitz'>
127
+ <a href='https://github.com/taquitos'>
128
+ <img src='https://github.com/taquitos.png' width='140px;'>
129
129
  </a>
130
- <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
130
+ <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
131
131
  </td>
132
132
  </tr>
133
133
  <tr>
134
- <td id='iulian-onofrei'>
135
- <a href='https://github.com/revolter'>
136
- <img src='https://github.com/revolter.png' width='140px;'>
134
+ <td id='aaron-brager'>
135
+ <a href='https://github.com/getaaron'>
136
+ <img src='https://github.com/getaaron.png' width='140px;'>
137
137
  </a>
138
- <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
138
+ <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
139
139
  </td>
140
- <td id='josh-holtz'>
141
- <a href='https://github.com/joshdholtz'>
142
- <img src='https://github.com/joshdholtz.png' width='140px;'>
140
+ <td id='roger-oba'>
141
+ <a href='https://github.com/rogerluan'>
142
+ <img src='https://github.com/rogerluan.png' width='140px;'>
143
143
  </a>
144
- <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
144
+ <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
145
145
  </td>
146
- <td id='daniel-jankowski'>
147
- <a href='https://github.com/mollyIV'>
148
- <img src='https://github.com/mollyIV.png' width='140px;'>
146
+ <td id='luka-mirosevic'>
147
+ <a href='https://github.com/lmirosevic'>
148
+ <img src='https://github.com/lmirosevic.png' width='140px;'>
149
149
  </a>
150
- <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
150
+ <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
151
151
  </td>
152
- <td id='andrew-mcburney'>
153
- <a href='https://github.com/armcburney'>
154
- <img src='https://github.com/armcburney.png' width='140px;'>
152
+ <td id='matthew-ellis'>
153
+ <a href='https://github.com/matthewellis'>
154
+ <img src='https://github.com/matthewellis.png' width='140px;'>
155
155
  </a>
156
- <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
156
+ <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
157
157
  </td>
158
- <td id='jan-piotrowski'>
159
- <a href='https://github.com/janpio'>
160
- <img src='https://github.com/janpio.png' width='140px;'>
158
+ <td id='satoshi-namai'>
159
+ <a href='https://github.com/ainame'>
160
+ <img src='https://github.com/ainame.png' width='140px;'>
161
161
  </a>
162
- <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
162
+ <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
163
163
  </td>
164
164
  </tr>
165
165
  <tr>
166
- <td id='luka-mirosevic'>
167
- <a href='https://github.com/lmirosevic'>
168
- <img src='https://github.com/lmirosevic.png' width='140px;'>
166
+ <td id='jimmy-dee'>
167
+ <a href='https://github.com/jdee'>
168
+ <img src='https://github.com/jdee.png' width='140px;'>
169
169
  </a>
170
- <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
170
+ <h4 align='center'>Jimmy Dee</h4>
171
171
  </td>
172
- <td id='kohki-miki'>
173
- <a href='https://github.com/giginet'>
174
- <img src='https://github.com/giginet.png' width='140px;'>
172
+ <td id='max-ott'>
173
+ <a href='https://github.com/max-ott'>
174
+ <img src='https://github.com/max-ott.png' width='140px;'>
175
175
  </a>
176
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
176
+ <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
177
177
  </td>
178
- <td id='aaron-brager'>
179
- <a href='https://github.com/getaaron'>
180
- <img src='https://github.com/getaaron.png' width='140px;'>
178
+ <td id='jérôme-lacoste'>
179
+ <a href='https://github.com/lacostej'>
180
+ <img src='https://github.com/lacostej.png' width='140px;'>
181
181
  </a>
182
- <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
182
+ <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
183
183
  </td>
184
184
  <td id='olivier-halligon'>
185
185
  <a href='https://github.com/AliSoftware'>
@@ -187,19 +187,19 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
187
187
  </a>
188
188
  <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
189
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;'>
190
+ <td id='danielle-tomlinson'>
191
+ <a href='https://github.com/endocrimes'>
192
+ <img src='https://github.com/endocrimes.png' width='140px;'>
193
193
  </a>
194
- <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
194
+ <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
195
195
  </td>
196
196
  </tr>
197
197
  <tr>
198
- <td id='matthew-ellis'>
199
- <a href='https://github.com/matthewellis'>
200
- <img src='https://github.com/matthewellis.png' width='140px;'>
198
+ <td id='andrew-mcburney'>
199
+ <a href='https://github.com/armcburney'>
200
+ <img src='https://github.com/armcburney.png' width='140px;'>
201
201
  </a>
202
- <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
202
+ <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
203
203
  </td>
204
204
  </table>
205
205
 
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]))
@@ -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'