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
@@ -55,7 +55,7 @@ module Deliver
55
55
  localizations = version.get_app_store_version_localizations
56
56
  end
57
57
 
58
- upload_screenshots(localizations, screenshots_per_language)
58
+ upload_screenshots(localizations, screenshots_per_language, options[:screenshot_processing_timeout])
59
59
 
60
60
  Helper.show_loading_indicator("Sorting screenshots uploaded...")
61
61
  sort_screenshots(localizations)
@@ -109,7 +109,7 @@ module Deliver
109
109
  end
110
110
  end
111
111
 
112
- def upload_screenshots(localizations, screenshots_per_language, tries: 5)
112
+ def upload_screenshots(localizations, screenshots_per_language, timeout_seconds, tries: 5)
113
113
  tries -= 1
114
114
 
115
115
  # Upload screenshots
@@ -158,15 +158,16 @@ module Deliver
158
158
  UI.verbose('Uploading jobs are completed')
159
159
 
160
160
  Helper.show_loading_indicator("Waiting for all the screenshots to finish being processed...")
161
- states = wait_for_complete(iterator)
161
+ states = wait_for_complete(iterator, timeout_seconds)
162
162
  Helper.hide_loading_indicator
163
- retry_upload_screenshots_if_needed(iterator, states, total_number_of_screenshots, tries, localizations, screenshots_per_language)
163
+ retry_upload_screenshots_if_needed(iterator, states, total_number_of_screenshots, tries, timeout_seconds, localizations, screenshots_per_language)
164
164
 
165
165
  UI.message("Successfully uploaded all screenshots")
166
166
  end
167
167
 
168
168
  # Verify all screenshots have been processed
169
- def wait_for_complete(iterator)
169
+ def wait_for_complete(iterator, timeout_seconds)
170
+ start_time = Time.now
170
171
  loop do
171
172
  states = iterator.each_app_screenshot.map { |_, _, app_screenshot| app_screenshot }.each_with_object({}) do |app_screenshot, hash|
172
173
  state = app_screenshot.asset_delivery_state['state']
@@ -177,16 +178,22 @@ module Deliver
177
178
  is_processing = states.fetch('UPLOAD_COMPLETE', 0) > 0
178
179
  return states unless is_processing
179
180
 
181
+ if Time.now - start_time > timeout_seconds
182
+ UI.important("Screenshot upload reached the timeout limit of #{timeout_seconds} seconds. We'll now retry uploading the screenshots that couldn't be uploaded in time.")
183
+ return states
184
+ end
185
+
180
186
  UI.verbose("There are still incomplete screenshots - #{states}")
181
187
  sleep(5)
182
188
  end
183
189
  end
184
190
 
185
191
  # Verify all screenshots states on App Store Connect are okay
186
- def retry_upload_screenshots_if_needed(iterator, states, number_of_screenshots, tries, localizations, screenshots_per_language)
192
+ def retry_upload_screenshots_if_needed(iterator, states, number_of_screenshots, tries, timeout_seconds, localizations, screenshots_per_language)
187
193
  is_failure = states.fetch("FAILED", 0) > 0
194
+ is_processing = states.fetch('UPLOAD_COMPLETE', 0) > 0
188
195
  is_missing_screenshot = !screenshots_per_language.empty? && !verify_local_screenshots_are_uploaded(iterator, screenshots_per_language)
189
- return unless is_failure || is_missing_screenshot
196
+ return unless is_failure || is_missing_screenshot || is_processing
190
197
 
191
198
  if tries.zero?
192
199
  iterator.each_app_screenshot.select { |_, _, app_screenshot| app_screenshot.error? }.each do |localization, _, app_screenshot|
@@ -200,7 +207,7 @@ module Deliver
200
207
  iterator.each_app_screenshot do |_, _, app_screenshot|
201
208
  app_screenshot.delete! unless app_screenshot.complete?
202
209
  end
203
- upload_screenshots(localizations, screenshots_per_language, tries: tries)
210
+ upload_screenshots(localizations, screenshots_per_language, timeout_seconds, tries: tries)
204
211
  end
205
212
  end
206
213
 
@@ -56,7 +56,8 @@ module Fastlane
56
56
  description: "The key ID"),
57
57
  FastlaneCore::ConfigItem.new(key: :issuer_id,
58
58
  env_name: "APP_STORE_CONNECT_API_KEY_ISSUER_ID",
59
- description: "The issuer ID"),
59
+ description: "The issuer ID. It can be nil if the key is individual API key",
60
+ optional: true),
60
61
  FastlaneCore::ConfigItem.new(key: :key_filepath,
61
62
  env_name: "APP_STORE_CONNECT_API_KEY_KEY_FILEPATH",
62
63
  description: "The path to the key p8 file",
@@ -50,6 +50,10 @@ module Fastlane
50
50
 
51
51
  response = http.request(req)
52
52
 
53
+ unless response.code.to_i.between?(200, 299)
54
+ UI.user_error!("Error uploading to Appetize.io: received HTTP #{response.code} with body #{response.body}")
55
+ end
56
+
53
57
  parse_response(response) # this will raise an exception if something goes wrong
54
58
 
55
59
  UI.message("App URL: #{Actions.lane_context[SharedValues::APPETIZE_APP_URL]}")
@@ -509,12 +509,16 @@ Please be careful when using this option and ensure the certificates and profile
509
509
 
510
510
  ### Manual Decrypt
511
511
 
512
- If you want to manually decrypt a file you can.
512
+ If you want to manually decrypt or encrypt a file, you can use the companion script `match_file`:
513
513
 
514
514
  ```no-highlight
515
- openssl aes-256-cbc -k "<password>" -in "<fileYouWantToDecryptPath>" -out "<decryptedFilePath>" -a -d -md [md5|sha256]
515
+ match_file encrypt "<fileYouWantToEncryptPath>" ["<encryptedFilePath>"]
516
+
517
+ match_file decrypt "<fileYouWantToDecryptPath>" ["<decryptedFilePath>"]
516
518
  ```
517
519
 
520
+ The password will be asked interactively.
521
+
518
522
  _**Note:** You may need to swap double quotes `"` for single quotes `'` if your match password contains an exclamation mark `!`._
519
523
 
520
524
  #### Export Distribution Certificate and Private Key as Single .p12 File
@@ -17,7 +17,16 @@ module Fastlane
17
17
  success_message = "Successfully added all files 💾."
18
18
  end
19
19
 
20
- result = Actions.sh("git add #{paths}", log: FastlaneCore::Globals.verbose?).chomp
20
+ force = params[:force] ? "--force" : nil
21
+
22
+ command = [
23
+ "git",
24
+ "add",
25
+ force,
26
+ paths
27
+ ].compact
28
+
29
+ result = Actions.sh(command.join(" "), log: FastlaneCore::Globals.verbose?).chomp
21
30
  UI.success(success_message)
22
31
  return result
23
32
  end
@@ -47,6 +56,11 @@ module Fastlane
47
56
  type: Boolean,
48
57
  default_value: true,
49
58
  optional: true),
59
+ FastlaneCore::ConfigItem.new(key: :force,
60
+ description: "Allow adding otherwise ignored files",
61
+ type: Boolean,
62
+ default_value: false,
63
+ optional: true),
50
64
  # Deprecated
51
65
  FastlaneCore::ConfigItem.new(key: :pathspec,
52
66
  description: "The pathspec you want to add files from",
@@ -76,7 +90,8 @@ module Fastlane
76
90
  'git_add(path: "./Frameworks/*", shell_escape: false)',
77
91
  'git_add(path: ["*.h", "*.m"], shell_escape: false)',
78
92
  'git_add(path: "./Frameworks/*", shell_escape: false)',
79
- 'git_add(path: "*.txt", shell_escape: false)'
93
+ 'git_add(path: "*.txt", shell_escape: false)',
94
+ 'git_add(path: "./tmp/.keep", force: true)'
80
95
  ]
81
96
  end
82
97
 
@@ -8,8 +8,15 @@ module Fastlane
8
8
  end
9
9
 
10
10
  def self.run(options)
11
- Actions.verify_gem!('rest-client')
12
- require 'rest-client'
11
+ Actions.verify_gem!('faraday')
12
+ Actions.verify_gem!('mime-types')
13
+ require 'faraday'
14
+ begin
15
+ # Use mime/types/columnar if available, for reduced memory usage
16
+ require 'mime/types/columnar'
17
+ rescue LoadError
18
+ require 'mime/types'
19
+ end
13
20
  handle_params_transition(options)
14
21
  mailgunit(options)
15
22
  end
@@ -101,11 +108,15 @@ module Fastlane
101
108
  end
102
109
 
103
110
  def self.handle_params_transition(options)
104
- options[:postmaster] = options[:mailgun_sandbox_postmaster] if options[:mailgun_sandbox_postmaster]
105
- puts("\nUsing :mailgun_sandbox_postmaster is deprecated, please change to :postmaster".yellow) if options[:mailgun_sandbox_postmaster]
111
+ if options[:mailgun_sandbox_postmaster] && !options[:postmaster]
112
+ options[:postmaster] = options[:mailgun_sandbox_postmaster]
113
+ puts("\nUsing :mailgun_sandbox_postmaster is deprecated, please change to :postmaster".yellow)
114
+ end
106
115
 
107
- options[:apikey] = options[:mailgun_apikey] if options[:mailgun_apikey]
108
- puts("\nUsing :mailgun_apikey is deprecated, please change to :apikey".yellow) if options[:mailgun_apikey]
116
+ if options[:mailgun_apikey] && !options[:apikey]
117
+ options[:apikey] = options[:mailgun_apikey]
118
+ puts("\nUsing :mailgun_apikey is deprecated, please change to :apikey".yellow)
119
+ end
109
120
  end
110
121
 
111
122
  def self.mailgunit(options)
@@ -122,14 +133,25 @@ module Fastlane
122
133
 
123
134
  unless options[:attachment].nil?
124
135
  attachment_filenames = [*options[:attachment]]
125
- attachments = attachment_filenames.map { |filename| File.new(filename, 'rb') }
136
+ attachments = attachment_filenames.map { |filename| Faraday::UploadIO.new(filename, mime_for(filename), filename) }
126
137
  params.store(:attachment, attachments)
127
138
  end
128
139
 
129
- RestClient.post("https://api:#{options[:apikey]}@api.mailgun.net/v3/#{sandbox_domain}/messages", params)
140
+ conn = Faraday.new(url: "https://api:#{options[:apikey]}@api.mailgun.net") do |f|
141
+ f.request(:multipart)
142
+ f.request(:url_encoded)
143
+ f.adapter(:net_http)
144
+ end
145
+ response = conn.post("/v3/#{sandbox_domain}/messages", params)
146
+ UI.user_error!("Failed to send message via Mailgun, response: #{response.status}: #{response.body}.") if response.status != 200
130
147
  mail_template(options)
131
148
  end
132
149
 
150
+ def self.mime_for(path)
151
+ mime = MIME::Types.type_for(path)
152
+ mime.empty? ? 'text/plain' : mime[0].content_type
153
+ end
154
+
133
155
  def self.mail_template(options)
134
156
  hash = {
135
157
  author: Actions.git_author_email,
@@ -42,14 +42,19 @@ module Fastlane
42
42
  payload["apns_p12_password"] = apns_p12_password || ""
43
43
  end
44
44
 
45
+ unless params[:fcm_json].nil?
46
+ data = File.read(params[:fcm_json])
47
+ fcm_json = Base64.strict_encode64(data)
48
+ payload["fcm_v1_service_account_json"] = fcm_json
49
+ end
50
+
45
51
  payload["gcm_key"] = android_token unless android_token.nil?
46
52
  payload["android_gcm_sender_id"] = android_gcm_sender_id unless android_gcm_sender_id.nil?
47
53
  payload["organization_id"] = organization_id unless organization_id.nil?
48
54
 
49
55
  # here's the actual lifting - POST or PUT to OneSignal
50
-
51
56
  json_headers = { 'Content-Type' => 'application/json', 'Authorization' => "Basic #{auth_token}" }
52
- url = +'https://onesignal.com/api/v1/apps'
57
+ url = +'https://api.onesignal.com/apps'
53
58
  url << '/' + app_id if is_update
54
59
  uri = URI.parse(url)
55
60
  http = Net::HTTP.new(uri.host, uri.port)
@@ -122,6 +127,11 @@ module Fastlane
122
127
  sensitive: true,
123
128
  optional: true),
124
129
 
130
+ FastlaneCore::ConfigItem.new(key: :fcm_json,
131
+ env_name: "FCM_JSON",
132
+ description: "FCM Service Account JSON File (in .json format)",
133
+ optional: true),
134
+
125
135
  FastlaneCore::ConfigItem.new(key: :apns_p12,
126
136
  env_name: "APNS_P12",
127
137
  description: "APNS P12 File (in .p12 format)",
@@ -169,6 +179,7 @@ module Fastlane
169
179
  app_name: "Name for OneSignal App",
170
180
  android_token: "Your Android GCM key (optional)",
171
181
  android_gcm_sender_id: "Your Android GCM Sender ID (optional)",
182
+ fcm_json: "Path to FCM Service Account JSON File (optional)",
172
183
  apns_p12: "Path to Apple .p12 file (optional)",
173
184
  apns_p12_password: "Password for .p12 file (optional)",
174
185
  apns_env: "production/sandbox (defaults to production)",
@@ -180,6 +191,7 @@ module Fastlane
180
191
  app_name: "New Name for OneSignal App",
181
192
  android_token: "Your Android GCM key (optional)",
182
193
  android_gcm_sender_id: "Your Android GCM Sender ID (optional)",
194
+ fcm_json: "Path to FCM Service Account JSON File (optional)",
183
195
  apns_p12: "Path to Apple .p12 file (optional)",
184
196
  apns_p12_password: "Password for .p12 file (optional)",
185
197
  apns_env: "production/sandbox (defaults to production)",
@@ -11,6 +11,7 @@ module Fastlane
11
11
  cmd << "--configuration #{params[:configuration]}" if params[:configuration]
12
12
  cmd << "--disable-sandbox" if params[:disable_sandbox]
13
13
  cmd << "--verbose" if params[:verbose]
14
+ cmd << "--very-verbose" if params[:very_verbose]
14
15
  if params[:simulator]
15
16
  simulator_platform = simulator_platform(simulator: params[:simulator], simulator_arch: params[:simulator_arch])
16
17
  simulator_sdk = simulator_sdk(simulator: params[:simulator])
@@ -118,6 +119,12 @@ module Fastlane
118
119
  description: "Increase verbosity of informational output",
119
120
  type: Boolean,
120
121
  default_value: false),
122
+ FastlaneCore::ConfigItem.new(key: :very_verbose,
123
+ short_option: "-V",
124
+ env_name: "FL_SPM_VERY_VERBOSE",
125
+ description: "Increase verbosity to include debug output",
126
+ type: Boolean,
127
+ default_value: false),
121
128
  FastlaneCore::ConfigItem.new(key: :simulator,
122
129
  env_name: "FL_SPM_SIMULATOR",
123
130
  description: "Specifies the simulator to pass for Swift Compiler (one of: #{valid_simulators.join(', ')})",
@@ -21,8 +21,9 @@ module Fastlane
21
21
  # download certificate
22
22
  unless File.exist?(params[:certificate]) && File.size(params[:certificate]) > 0
23
23
  UI.message("Downloading root certificate from (#{ROOT_CERTIFICATE_URL}) to path '#{params[:certificate]}'")
24
+ require 'open-uri'
24
25
  File.open(params[:certificate], "w:ASCII-8BIT") do |file|
25
- file.write(FastlaneCore::Helper.open_uri(ROOT_CERTIFICATE_URL, "rb").read)
26
+ file.write(URI.open(ROOT_CERTIFICATE_URL, "rb").read)
26
27
  end
27
28
  end
28
29
 
@@ -7,8 +7,10 @@ module Fastlane
7
7
  UI.important("GitHub: https://github.com/getsentry/fastlane-plugin-sentry")
8
8
  UI.important("Installation: fastlane add_plugin sentry")
9
9
 
10
- Actions.verify_gem!('rest-client')
11
- require 'rest-client'
10
+ UI.user_error!("This plugin is now completely deprecated")
11
+ # the code below doesn't run anymore
12
+ # Actions.verify_gem!('rest-client')
13
+ # require 'rest-client'
12
14
 
13
15
  # Params - API
14
16
  host = params[:api_host]
@@ -249,6 +249,15 @@ module Fastlane
249
249
  end
250
250
  end
251
251
 
252
+ command :console do |c|
253
+ c.syntax = 'fastlane console'
254
+ c.description = 'Opens an interactive developer console'
255
+ c.action do |args, options|
256
+ require 'fastlane/console'
257
+ Fastlane::Console.execute(args, options)
258
+ end
259
+ end
260
+
252
261
  command :enable_auto_complete do |c|
253
262
  c.syntax = 'fastlane enable_auto_complete'
254
263
  c.description = 'Enable tab auto completion'
@@ -0,0 +1,24 @@
1
+ require 'irb'
2
+
3
+ module Fastlane
4
+ # Opens an interactive developer console
5
+ class Console
6
+ def self.execute(args, options)
7
+ ARGV.clear
8
+ IRB.setup(nil)
9
+ @irb = IRB::Irb.new(nil)
10
+ IRB.conf[:MAIN_CONTEXT] = @irb.context
11
+ IRB.conf[:PROMPT][:FASTLANE] = IRB.conf[:PROMPT][:SIMPLE].dup
12
+ IRB.conf[:PROMPT][:FASTLANE][:RETURN] = "%s\n"
13
+ @irb.context.prompt_mode = :FASTLANE
14
+ @irb.context.workspace = IRB::WorkSpace.new(binding)
15
+ trap('INT') do
16
+ @irb.signal_handle
17
+ end
18
+
19
+ UI.message('Welcome to fastlane interactive!')
20
+
21
+ catch(:IRB_EXIT) { @irb.eval_input }
22
+ end
23
+ end
24
+ end
@@ -42,7 +42,7 @@ module Fastlane
42
42
 
43
43
  result = ''
44
44
  exit_status = nil
45
- if Helper.sh_enabled?
45
+ if FastlaneCore::Helper.sh_enabled?
46
46
  # The argument list is passed directly to Open3.popen2e, which
47
47
  # handles the variadic argument list in the same way as Kernel#spawn.
48
48
  # (http://ruby-doc.org/core-2.4.2/Kernel.html#method-i-spawn) or
@@ -78,15 +78,23 @@ module Fastlane
78
78
  end
79
79
 
80
80
  def self.print_error_line(ex)
81
- error_line = ex.backtrace.first
82
- return if error_line.nil?
83
-
84
- error_line = error_line.match("Fastfile:(\\d+):")
85
- return unless error_line
81
+ lines = ex.backtrace_locations&.select { |loc| loc.path == 'Fastfile' }&.map(&:lineno)
82
+ return if lines.nil? || lines.empty?
83
+
84
+ fastfile_content = File.read(FastlaneCore::FastlaneFolder.fastfile_path, encoding: "utf-8")
85
+ if ex.backtrace_locations.first&.path == 'Fastfile'
86
+ # If exception happened directly in the Fastfile itself (e.g. ArgumentError)
87
+ UI.error("Error in your Fastfile at line #{lines.first}")
88
+ UI.content_error(fastfile_content, lines.first)
89
+ lines.shift
90
+ end
86
91
 
87
- line = error_line[1]
88
- UI.error("Error in your Fastfile at line #{line}")
89
- UI.content_error(File.read(FastlaneCore::FastlaneFolder.fastfile_path, encoding: "utf-8"), line)
92
+ unless lines.empty?
93
+ # If exception happened directly in the Fastfile, also print the caller (still from the Fastfile).
94
+ # If exception happened in _fastlane_ internal code, print the line from the Fastfile that called it
95
+ UI.error("Called from Fastfile at line #{lines.first}")
96
+ UI.content_error(fastfile_content, lines.first)
97
+ end
90
98
  end
91
99
  end
92
100
  end
@@ -7,13 +7,14 @@ module Fastlane
7
7
  # Returns an array of FastlanePlugin objects
8
8
  def self.fetch_gems(search_query: nil)
9
9
  require 'json'
10
+ require 'open-uri'
10
11
 
11
12
  page = 1
12
13
  plugins = []
13
14
  loop do
14
15
  url = "https://rubygems.org/api/v1/search.json?query=#{PluginManager.plugin_prefix}&page=#{page}"
15
16
  FastlaneCore::UI.verbose("RubyGems API Request: #{url}")
16
- results = JSON.parse(FastlaneCore::Helper.open_uri(url).read)
17
+ results = JSON.parse(URI.open(url).read)
17
18
  break if results.count == 0
18
19
 
19
20
  plugins += results.collect do |current|
@@ -66,8 +66,9 @@ module Fastlane
66
66
  # Checks if the gem name is still free on RubyGems
67
67
  def gem_name_taken?(name)
68
68
  require 'json'
69
+ require 'open-uri'
69
70
  url = "https://rubygems.org/api/v1/gems/#{name}.json"
70
- response = JSON.parse(FastlaneCore::Helper.open_uri(url).read)
71
+ response = JSON.parse(URI.open(url).read)
71
72
  return !!response['version']
72
73
  rescue
73
74
  false
@@ -156,9 +156,10 @@ module Fastlane
156
156
 
157
157
  def self.fetch_gem_info_from_rubygems(gem_name)
158
158
  require 'json'
159
+ require 'open-uri'
159
160
  url = "https://rubygems.org/api/v1/gems/#{gem_name}.json"
160
161
  begin
161
- JSON.parse(FastlaneCore::Helper.open_uri(url).read)
162
+ JSON.parse(URI.open(url).read)
162
163
  rescue
163
164
  nil
164
165
  end
@@ -40,13 +40,13 @@ module Fastlane
40
40
  return_val = nil
41
41
 
42
42
  path_to_use = FastlaneCore::FastlaneFolder.path || Dir.pwd
43
- parameters ||= {}
43
+ parameters ||= {} # by default no parameters
44
44
  begin
45
45
  Dir.chdir(path_to_use) do # the file is located in the fastlane folder
46
46
  execute_flow_block(before_all_blocks, current_platform, current_lane, parameters)
47
47
  execute_flow_block(before_each_blocks, current_platform, current_lane, parameters)
48
48
 
49
- return_val = lane_obj.call(parameters) # by default no parameters
49
+ return_val = lane_obj.call(parameters)
50
50
 
51
51
  # after blocks are only called if no exception was raised before
52
52
  # Call the platform specific after block and then the general one
@@ -1,5 +1,6 @@
1
1
  module Fastlane
2
- VERSION = '2.219.0'.freeze
2
+ VERSION = '2.221.0'.freeze
3
+ SUMMARY = "The easiest way to build and release mobile apps.".freeze
3
4
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
5
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
6
  RUBOCOP_REQUIREMENT = '1.50.2'.freeze
@@ -17,4 +17,4 @@ public class Deliverfile: DeliverfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.219.0
20
+ // Generated with fastlane 2.221.0
@@ -59,6 +59,9 @@ public protocol DeliverfileProtocol: AnyObject {
59
59
  /// Clear all previously uploaded screenshots before uploading the new ones
60
60
  var overwriteScreenshots: Bool { get }
61
61
 
62
+ /// 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
63
+ var screenshotProcessingTimeout: Int { get }
64
+
62
65
  /// Sync screenshots with local ones. This is currently beta option so set true to 'FASTLANE_ENABLE_BETA_DELIVER_SYNC_SCREENSHOTS' environment variable as well
63
66
  var syncScreenshots: Bool { get }
64
67
 
@@ -71,6 +74,9 @@ public protocol DeliverfileProtocol: AnyObject {
71
74
  /// Rejects the previously submitted build if it's in a state where it's possible
72
75
  var rejectIfPossible: Bool { get }
73
76
 
77
+ /// 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. 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
78
+ var versionCheckWaitRetryLimit: Int { get }
79
+
74
80
  /// Should the app be automatically released once it's approved? (Cannot be used together with `auto_release_date`)
75
81
  var automaticRelease: Bool? { get }
76
82
 
@@ -215,10 +221,12 @@ public extension DeliverfileProtocol {
215
221
  var skipAppVersionUpdate: Bool { return false }
216
222
  var force: Bool { return false }
217
223
  var overwriteScreenshots: Bool { return false }
224
+ var screenshotProcessingTimeout: Int { return 3600 }
218
225
  var syncScreenshots: Bool { return false }
219
226
  var submitForReview: Bool { return false }
220
227
  var verifyOnly: Bool { return false }
221
228
  var rejectIfPossible: Bool { return false }
229
+ var versionCheckWaitRetryLimit: Int { return 7 }
222
230
  var automaticRelease: Bool? { return nil }
223
231
  var autoReleaseDate: Int? { return nil }
224
232
  var phasedRelease: Bool { return false }
@@ -264,4 +272,4 @@ public extension DeliverfileProtocol {
264
272
 
265
273
  // Please don't remove the lines below
266
274
  // They are used to detect outdated files
267
- // FastlaneRunnerAPIVersion [0.9.123]
275
+ // FastlaneRunnerAPIVersion [0.9.125]