Class: Deliver::Runner

Inherits:
Object
  • Object
show all
Defined in:
deliver/lib/deliver/runner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options, skip_auto_detection = {}) ⇒ Runner

Returns a new instance of Runner.



20
21
22
23
24
25
26
27
# File 'deliver/lib/deliver/runner.rb', line 20

def initialize(options, skip_auto_detection = {})
  self.options = options

  

  Deliver::DetectValues.new.run!(self.options, skip_auto_detection)
  FastlaneCore::PrintTable.print_values(config: options, hide_keys: [:app], mask_keys: ['app_review_information.demo_password'], title: "deliver #{Fastlane::VERSION} Summary")
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



18
19
20
# File 'deliver/lib/deliver/runner.rb', line 18

def options
  @options
end

Instance Method Details

#loginObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'deliver/lib/deliver/runner.rb', line 29

def 
  if (api_token = Spaceship::ConnectAPI::Token.from(hash: options[:api_key], filepath: options[:api_key_path]))
    UI.message("Creating authorization token for App Store Connect API")
    Spaceship::ConnectAPI.token = api_token
  elsif !Spaceship::ConnectAPI.token.nil?
    UI.message("Using existing authorization token for App Store Connect API")
  else
    # Username is now optional since addition of App Store Connect API Key
    # Force asking for username to prompt user if not already set
    options.fetch(:username, force_ask: true)

    # Team selection passed though FASTLANE_TEAM_ID and FASTLANE_TEAM_NAME environment variables
    # Prompts select team if multiple teams and none specified
    UI.message("Login to App Store Connect (#{options[:username]})")
    Spaceship::ConnectAPI.(options[:username], nil, use_portal: false, use_tunes: true)
    UI.message("Login successful")
  end
end

#precheck_appObject

Make sure we pass precheck before uploading



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'deliver/lib/deliver/runner.rb', line 75

def precheck_app
  return true unless options[:run_precheck_before_submit]
  UI.message("Running precheck before submitting to review, if you'd like to disable this check you can set run_precheck_before_submit to false")

  if options[:submit_for_review]
    UI.message("Making sure we pass precheck 👮‍♀️ 👮 before we submit  🛫")
  else
    UI.message("Running precheck 👮‍♀️ 👮")
  end

  precheck_options = {
    default_rule_level: options[:precheck_default_rule_level],
    include_in_app_purchases: options[:precheck_include_in_app_purchases],
    app_identifier: options[:app_identifier]
  }

  if options[:api_key] || options[:api_key_path]
    if options[:precheck_include_in_app_purchases]
      UI.user_error!("Precheck cannot check In-app purchases with the App Store Connect API Key (yet). Exclude In-app purchases from precheck, disable the precheck step in your build step, or use Apple ID login")
    end

    precheck_options[:api_key] = options[:api_key]
    precheck_options[:api_key_path] = options[:api_key_path]
  else
    precheck_options[:username] = options[:username]
    precheck_options[:platform] = options[:platform]
  end

  precheck_config = FastlaneCore::Configuration.create(Precheck::Options.available_options, precheck_options)
  Precheck.config = precheck_config

  precheck_success = true
  begin
    precheck_success = Precheck::Runner.new.run
  rescue => ex
    UI.error("fastlane precheck just tried to inspect your app's metadata for App Store guideline violations and ran into a problem. We're not sure what the problem was, but precheck failed to finished. You can run it in verbose mode if you want to see the whole error. We'll have a fix out soon 🚀")
    UI.verbose(ex.inspect)
    UI.verbose(ex.backtrace.join("\n"))
  end

  return precheck_success
end

#reject_version_if_possibleObject



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'deliver/lib/deliver/runner.rb', line 239

def reject_version_if_possible
  app = Deliver.cache[:app]
  platform = Spaceship::ConnectAPI::Platform.map(options[:platform])

  submission = app.get_in_progress_review_submission(platform: platform)
  if submission
    submission.cancel_submission
    UI.message("Review submission cancellation has been requested")

    # An app version won't get removed from review instantly
    # Polling until there is no longer an in-progress version
    loop do
      break if app.get_in_progress_review_submission(platform: platform).nil?
      UI.message("Waiting for cancellation to take effect...")
      sleep(15)
    end

    UI.success("Successfully cancelled previous submission!")
  end
end

#runObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'deliver/lib/deliver/runner.rb', line 48

def run
  if options[:verify_only]
    UI.important("Verify flag is set, only package validation will take place and no submission will be made")
    verify_binary
    return
  end

  verify_version if options[:app_version].to_s.length > 0 && !options[:skip_app_version_update]

  # Rejecting before upload meta
  # Screenshots cannot be updated or deleted if the app is in the "waiting for review" state
  reject_version_if_possible if options[:reject_if_possible]

  

  has_binary = (options[:ipa] || options[:pkg])
  if !options[:skip_binary_upload] && !options[:build_number] && has_binary
    upload_binary
  end

  UI.success("Finished the upload to App Store Connect") unless options[:skip_binary_upload]

  precheck_success = precheck_app
  submit_for_review if options[:submit_for_review] && precheck_success
end

#submit_for_reviewObject



260
261
262
# File 'deliver/lib/deliver/runner.rb', line 260

def submit_for_review
  SubmitForReview.new.submit!(options)
end

#upload_binaryObject

Upload the binary to App Store Connect



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'deliver/lib/deliver/runner.rb', line 202

def upload_binary
  UI.message("Uploading binary to App Store Connect")

  ipa_path = options[:ipa]
  pkg_path = options[:pkg]

  platform = options[:platform]
  transporter = transporter_for_selected_team

  case platform
  when "ios", "appletvos", "xros"
    package_path = FastlaneCore::IpaUploadPackageBuilder.new.generate(
      app_id: Deliver.cache[:app].id,
      ipa_path: ipa_path,
      package_path: "/tmp",
      platform: platform
    )
    result = transporter.upload(package_path: package_path, asset_path: ipa_path, platform: platform)
  when "osx"
    package_path = FastlaneCore::PkgUploadPackageBuilder.new.generate(
      app_id: Deliver.cache[:app].id,
      pkg_path: pkg_path,
      package_path: "/tmp",
      platform: platform
    )
    result = transporter.upload(package_path: package_path, asset_path: pkg_path, platform: platform)
  else
    UI.user_error!("No suitable file found for upload for platform: #{options[:platform]}")
  end

  unless result
    transporter_errors = transporter.displayable_errors
    file_type = platform == "osx" ? "pkg" : "ipa"
    UI.user_error!("Error uploading #{file_type} file: \n #{transporter_errors}")
  end
end

#upload_metadataObject

Upload all metadata, screenshots, pricing information, etc. to App Store Connect



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'deliver/lib/deliver/runner.rb', line 137

def 
   = UploadMetadata.new(options)
  upload_screenshots = UploadScreenshots.new

  # First, collect all the things for the HTML Report
  screenshots = upload_screenshots.collect_screenshots(options)
  .load_from_filesystem

  # Assign "default" values to all languages
  .assign_defaults

  # Validate
  validate_html(screenshots)

  # Commit
  .upload

  if options[:sync_screenshots]
    sync_screenshots = SyncScreenshots.new(app: Deliver.cache[:app], platform: Spaceship::ConnectAPI::Platform.map(options[:platform]))
    sync_screenshots.sync(screenshots)
  else
    upload_screenshots.upload(options, screenshots)
  end

  UploadPriceTier.new.upload(options)
end

#verify_binaryObject

Verify the binary with App Store Connect



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'deliver/lib/deliver/runner.rb', line 165

def verify_binary
  UI.message("Verifying binary with App Store Connect")

  ipa_path = options[:ipa]
  pkg_path = options[:pkg]

  platform = options[:platform]
  transporter = transporter_for_selected_team

  case platform
  when "ios", "appletvos", "xros"
    package_path = FastlaneCore::IpaUploadPackageBuilder.new.generate(
      app_id: Deliver.cache[:app].id,
      ipa_path: ipa_path,
      package_path: "/tmp",
      platform: platform
    )
    result = transporter.verify(package_path: package_path, asset_path: ipa_path, platform: platform)
  when "osx"
    package_path = FastlaneCore::PkgUploadPackageBuilder.new.generate(
      app_id: Deliver.cache[:app].id,
      pkg_path: pkg_path,
      package_path: "/tmp",
      platform: platform
    )
    result = transporter.verify(package_path: package_path, asset_path: pkg_path, platform: platform)
  else
    UI.user_error!("No suitable file found for verify for platform: #{options[:platform]}")
  end

  unless result
    transporter_errors = transporter.displayable_errors
    UI.user_error!("Error verifying the binary file: \n #{transporter_errors}")
  end
end

#verify_versionObject

Make sure the version on App Store Connect matches the one in the ipa If not, the new version will automatically be created



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'deliver/lib/deliver/runner.rb', line 120

def verify_version
  app_version = options[:app_version]
  UI.message("Making sure the latest version on App Store Connect matches '#{app_version}'...")

  app = Deliver.cache[:app]

  platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
  changed = app.ensure_version!(app_version, platform: platform)

  if changed
    UI.success("Successfully set the version to '#{app_version}'")
  else
    UI.success("'#{app_version}' is the latest version on App Store Connect")
  end
end