fastlane 2.218.0 → 2.220.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +88 -88
  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 +23 -15
  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/portal_cache.rb +2 -2
  59. data/match/lib/match/profile_includes.rb +2 -2
  60. data/match/lib/match/runner.rb +63 -21
  61. data/match/lib/match/storage/git_storage.rb +4 -3
  62. data/match/lib/match/storage/interface.rb +9 -5
  63. data/pilot/lib/pilot/build_manager.rb +5 -2
  64. data/pilot/lib/pilot/manager.rb +2 -2
  65. data/pilot/lib/pilot/options.rb +1 -1
  66. data/scan/lib/scan/detect_values.rb +1 -1
  67. data/sigh/lib/sigh/options.rb +8 -8
  68. data/sigh/lib/sigh/runner.rb +1 -1
  69. data/snapshot/lib/snapshot/options.rb +2 -2
  70. data/snapshot/lib/snapshot/setup.rb +1 -1
  71. data/spaceship/lib/spaceship/connect_api/api_client.rb +1 -1
  72. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +17 -0
  73. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +44 -9
  74. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +30 -2
  75. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -2
  76. data/spaceship/lib/spaceship/connect_api/models/device.rb +11 -6
  77. data/spaceship/lib/spaceship/connect_api/models/profile.rb +8 -1
  78. data/spaceship/lib/spaceship/connect_api/token.rb +2 -1
  79. data/spaceship/lib/spaceship/connect_api.rb +5 -2
  80. data/spaceship/lib/spaceship/portal/certificate.rb +2 -2
  81. data/spaceship/lib/spaceship/portal/provisioning_profile.rb +8 -1
  82. data/trainer/lib/trainer/xcresult.rb +6 -10
  83. metadata +64 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 207ef9c2fe4564f7949fc47ec3693583185a7cf46cdeebcab96485d4b0a9ffa1
4
- data.tar.gz: 80053bd7ef7de964bf4b3ddeeab4698b149cf8bc2cccbe1355d5f8d49de541b2
3
+ metadata.gz: eec1401cd6a8a8a9e9c48fed9969a6ab44348fa672c2b75464b3265000dab288
4
+ data.tar.gz: 1c7bc580641838525e4705a83633da89a38f225dfaea07ba9ee1ee2f54e8676c
5
5
  SHA512:
6
- metadata.gz: a9ea4c0b0093fcceed9e353ece98359675754b8ab17b7e2b2a8f3efd6da34f6ad012e7fb2aca9ff33c08022195e5fd271db52db6d51ca3dbbb6472bec76e95eb
7
- data.tar.gz: edb1ba5f075dce4d8a43af1e12ef886f0c572f416255818f1878c5ea14cd93c5d67105882fc999a7d794f2ad1ab1e0a8293c35c028e72fa9254b9d28924074bf
6
+ metadata.gz: 3d88cbca7c40d2882d7442db21b0725b2da0e641f267f0c581cd2c7344a5e220a46cdd84eae861609d0ed9940226953cb6a03094d6b0019eaca578e7fb6872ae
7
+ data.tar.gz: 830456faecb0a07cfda4f48d7e5bb6ea0fa558553a43ae59f18a2ae702062d6202d31f2285dc4bea2310bceb890cfde6fc848ebcfeb0dbc71eb4911938a018e7
data/README.md CHANGED
@@ -35,11 +35,17 @@ 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='roger-oba'>
39
- <a href='https://github.com/rogerluan'>
40
- <img src='https://github.com/rogerluan.png' width='140px;'>
38
+ <td id='iulian-onofrei'>
39
+ <a href='https://github.com/revolter'>
40
+ <img src='https://github.com/revolter.png' width='140px;'>
41
41
  </a>
42
- <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
42
+ <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
43
+ </td>
44
+ <td id='manu-wallner'>
45
+ <a href='https://github.com/milch'>
46
+ <img src='https://github.com/milch.png' width='140px;'>
47
+ </a>
48
+ <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
43
49
  </td>
44
50
  <td id='fumiya-nakamura'>
45
51
  <a href='https://github.com/nafu'>
@@ -47,17 +53,11 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
47
53
  </a>
48
54
  <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
49
55
  </td>
50
- <td id='danielle-tomlinson'>
51
- <a href='https://github.com/endocrimes'>
52
- <img src='https://github.com/endocrimes.png' width='140px;'>
53
- </a>
54
- <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
55
- </td>
56
- <td id='max-ott'>
57
- <a href='https://github.com/max-ott'>
58
- <img src='https://github.com/max-ott.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/ott_max'>Max Ott</a></h4>
60
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
61
61
  </td>
62
62
  <td id='jorge-revuelta-h'>
63
63
  <a href='https://github.com/minuscorp'>
@@ -67,29 +67,17 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
67
67
  </td>
68
68
  </tr>
69
69
  <tr>
70
- <td id='maksym-grebenets'>
71
- <a href='https://github.com/mgrebenets'>
72
- <img src='https://github.com/mgrebenets.png' width='140px;'>
73
- </a>
74
- <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
75
- </td>
76
- <td id='satoshi-namai'>
77
- <a href='https://github.com/ainame'>
78
- <img src='https://github.com/ainame.png' width='140px;'>
79
- </a>
80
- <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
81
- </td>
82
- <td id='matthew-ellis'>
83
- <a href='https://github.com/matthewellis'>
84
- <img src='https://github.com/matthewellis.png' width='140px;'>
70
+ <td id='jan-piotrowski'>
71
+ <a href='https://github.com/janpio'>
72
+ <img src='https://github.com/janpio.png' width='140px;'>
85
73
  </a>
86
- <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
74
+ <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
87
75
  </td>
88
- <td id='manu-wallner'>
89
- <a href='https://github.com/milch'>
90
- <img src='https://github.com/milch.png' width='140px;'>
76
+ <td id='daniel-jankowski'>
77
+ <a href='https://github.com/mollyIV'>
78
+ <img src='https://github.com/mollyIV.png' width='140px;'>
91
79
  </a>
92
- <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
80
+ <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
93
81
  </td>
94
82
  <td id='łukasz-grabowski'>
95
83
  <a href='https://github.com/lucgrabowski'>
@@ -97,6 +85,18 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
97
85
  </a>
98
86
  <h4 align='center'>Łukasz Grabowski</h4>
99
87
  </td>
88
+ <td id='maksym-grebenets'>
89
+ <a href='https://github.com/mgrebenets'>
90
+ <img src='https://github.com/mgrebenets.png' width='140px;'>
91
+ </a>
92
+ <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
93
+ </td>
94
+ <td id='stefan-natchev'>
95
+ <a href='https://github.com/snatchev'>
96
+ <img src='https://github.com/snatchev.png' width='140px;'>
97
+ </a>
98
+ <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
99
+ </td>
100
100
  </tr>
101
101
  <tr>
102
102
  <td id='josh-holtz'>
@@ -105,61 +105,61 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
105
105
  </a>
106
106
  <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
107
107
  </td>
108
- <td id='kohki-miki'>
109
- <a href='https://github.com/giginet'>
110
- <img src='https://github.com/giginet.png' width='140px;'>
111
- </a>
112
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
113
- </td>
114
- <td id='olivier-halligon'>
115
- <a href='https://github.com/AliSoftware'>
116
- <img src='https://github.com/AliSoftware.png' width='140px;'>
117
- </a>
118
- <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
119
- </td>
120
108
  <td id='manish-rathi'>
121
109
  <a href='https://github.com/crazymanish'>
122
110
  <img src='https://github.com/crazymanish.png' width='140px;'>
123
111
  </a>
124
112
  <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
125
113
  </td>
126
- <td id='andrew-mcburney'>
127
- <a href='https://github.com/armcburney'>
128
- <img src='https://github.com/armcburney.png' width='140px;'>
129
- </a>
130
- <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
131
- </td>
132
- </tr>
133
- <tr>
134
- <td id='helmut-januschka'>
135
- <a href='https://github.com/hjanuschka'>
136
- <img src='https://github.com/hjanuschka.png' width='140px;'>
137
- </a>
138
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
139
- </td>
140
114
  <td id='felix-krause'>
141
115
  <a href='https://github.com/KrauseFx'>
142
116
  <img src='https://github.com/KrauseFx.png' width='140px;'>
143
117
  </a>
144
118
  <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
145
119
  </td>
146
- <td id='jérôme-lacoste'>
147
- <a href='https://github.com/lacostej'>
148
- <img src='https://github.com/lacostej.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;'>
149
123
  </a>
150
- <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
124
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
151
125
  </td>
126
+ <td id='joshua-liebowitz'>
127
+ <a href='https://github.com/taquitos'>
128
+ <img src='https://github.com/taquitos.png' width='140px;'>
129
+ </a>
130
+ <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
131
+ </td>
132
+ </tr>
133
+ <tr>
152
134
  <td id='aaron-brager'>
153
135
  <a href='https://github.com/getaaron'>
154
136
  <img src='https://github.com/getaaron.png' width='140px;'>
155
137
  </a>
156
138
  <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
157
139
  </td>
158
- <td id='joshua-liebowitz'>
159
- <a href='https://github.com/taquitos'>
160
- <img src='https://github.com/taquitos.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;'>
161
143
  </a>
162
- <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
144
+ <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
145
+ </td>
146
+ <td id='luka-mirosevic'>
147
+ <a href='https://github.com/lmirosevic'>
148
+ <img src='https://github.com/lmirosevic.png' width='140px;'>
149
+ </a>
150
+ <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
151
+ </td>
152
+ <td id='matthew-ellis'>
153
+ <a href='https://github.com/matthewellis'>
154
+ <img src='https://github.com/matthewellis.png' width='140px;'>
155
+ </a>
156
+ <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
157
+ </td>
158
+ <td id='satoshi-namai'>
159
+ <a href='https://github.com/ainame'>
160
+ <img src='https://github.com/ainame.png' width='140px;'>
161
+ </a>
162
+ <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
163
163
  </td>
164
164
  </tr>
165
165
  <tr>
@@ -169,37 +169,37 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
169
169
  </a>
170
170
  <h4 align='center'>Jimmy Dee</h4>
171
171
  </td>
172
- <td id='iulian-onofrei'>
173
- <a href='https://github.com/revolter'>
174
- <img src='https://github.com/revolter.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/Revolt666'>Iulian Onofrei</a></h4>
176
+ <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
177
177
  </td>
178
- <td id='stefan-natchev'>
179
- <a href='https://github.com/snatchev'>
180
- <img src='https://github.com/snatchev.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/snatchev'>Stefan Natchev</a></h4>
182
+ <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
183
183
  </td>
184
- <td id='jan-piotrowski'>
185
- <a href='https://github.com/janpio'>
186
- <img src='https://github.com/janpio.png' width='140px;'>
184
+ <td id='olivier-halligon'>
185
+ <a href='https://github.com/AliSoftware'>
186
+ <img src='https://github.com/AliSoftware.png' width='140px;'>
187
187
  </a>
188
- <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
188
+ <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
189
189
  </td>
190
- <td id='daniel-jankowski'>
191
- <a href='https://github.com/mollyIV'>
192
- <img src='https://github.com/mollyIV.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/mollyIV'>Daniel Jankowski</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='luka-mirosevic'>
199
- <a href='https://github.com/lmirosevic'>
200
- <img src='https://github.com/lmirosevic.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/lmirosevic'>Luka Mirosevic</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'