class Deliver::Runner

Attributes

options[RW]

Public Class Methods

new(options, skip_auto_detection = {}) click to toggle source
# File deliver/lib/deliver/runner.rb, line 20
def initialize(options, skip_auto_detection = {})
  self.options = options

  login

  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

Public Instance Methods

login() click to toggle source
# File deliver/lib/deliver/runner.rb, line 29
def login
  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.login(options[:username], nil, use_portal: false, use_tunes: true)
    UI.message("Login successful")
  end
end
precheck_app() click to toggle source

Make sure we pass precheck before uploading

# File deliver/lib/deliver/runner.rb, line 69
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_possible() click to toggle source
# File deliver/lib/deliver/runner.rb, line 197
def reject_version_if_possible
  app = Deliver.cache[:app]
  platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
  if app.reject_version_if_possible!(platform: platform)
    UI.success("Successfully rejected previous version!")
  end
end
run() click to toggle source
# File deliver/lib/deliver/runner.rb, line 48
def run
  verify_version if options[:app_version].to_s.length > 0 && !options[:skip_app_version_update]

  # Rejecting before upload meta
  # Screenshots can not be update/deleted if in waiting for review
  reject_version_if_possible if options[:reject_if_possible]

  upload_metadata

  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_review() click to toggle source
# File deliver/lib/deliver/runner.rb, line 205
def submit_for_review
  SubmitForReview.new.submit!(options)
end
upload_binary() click to toggle source

Upload the binary to App Store Connect

# File deliver/lib/deliver/runner.rb, line 159
def upload_binary
  UI.message("Uploading binary to App Store Connect")

  upload_ipa = options[:ipa]
  upload_pkg = options[:pkg]

  # 2020-01-27
  # Only verify platform if if both ipa and pkg exists (for backwards support)
  if upload_ipa && upload_pkg
    upload_ipa = ["ios", "appletvos"].include?(options[:platform])
    upload_pkg = options[:platform] == "osx"
  end

  if upload_ipa
    package_path = FastlaneCore::IpaUploadPackageBuilder.new.generate(
      app_id: Deliver.cache[:app].id,
      ipa_path: options[:ipa],
      package_path: "/tmp",
      platform: options[:platform]
    )
  elsif upload_pkg
    package_path = FastlaneCore::PkgUploadPackageBuilder.new.generate(
      app_id: Deliver.cache[:app].id,
      pkg_path: options[:pkg],
      package_path: "/tmp",
      platform: options[:platform]
    )
  end

  transporter = transporter_for_selected_team
  result = transporter.upload(package_path: package_path)

  unless result
    transporter_errors = transporter.displayable_errors
    UI.user_error!("Error uploading ipa file: \n #{transporter_errors}")
  end
end
upload_metadata() click to toggle source

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

# File deliver/lib/deliver/runner.rb, line 131
def upload_metadata
  upload_metadata = UploadMetadata.new
  upload_screenshots = UploadScreenshots.new

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

  # Assign "default" values to all languages
  upload_metadata.assign_defaults(options)

  # Validate
  validate_html(screenshots)

  # Commit
  upload_metadata.upload(options)

  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_version() click to toggle source

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

# File deliver/lib/deliver/runner.rb, line 114
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

Private Instance Methods

transporter_for_selected_team() click to toggle source

If App Store Connect API token, use token. If itc_provider was explicitly specified, use it. If there are multiple teams, infer the provider from the selected team name. If there are fewer than two teams, don't infer the provider.

# File deliver/lib/deliver/runner.rb, line 215
def transporter_for_selected_team
  # Use JWT auth
  api_token = Spaceship::ConnectAPI.token
  unless api_token.nil?
    api_token.refresh! if api_token.expired?
    return FastlaneCore::ItunesTransporter.new(nil, nil, false, nil, api_token.text)
  end

  tunes_client = Spaceship::ConnectAPI.client.tunes_client

  generic_transporter = FastlaneCore::ItunesTransporter.new(options[:username], nil, false, options[:itc_provider])
  return generic_transporter unless options[:itc_provider].nil? && tunes_client.teams.count > 1

  begin
    team = tunes_client.teams.find { |t| t['contentProvider']['contentProviderId'].to_s == tunes_client.team_id }
    name = team['contentProvider']['name']
    provider_id = generic_transporter.provider_ids[name]
    UI.verbose("Inferred provider id #{provider_id} for team #{name}.")
    return FastlaneCore::ItunesTransporter.new(options[:username], nil, false, provider_id)
  rescue => ex
    UI.verbose("Couldn't infer a provider short name for team with id #{tunes_client.team_id} automatically: #{ex}. Proceeding without provider short name.")
    return generic_transporter
  end
end
validate_html(screenshots) click to toggle source
# File deliver/lib/deliver/runner.rb, line 240
def validate_html(screenshots)
  return if options[:force]
  return if options[:skip_metadata] && options[:skip_screenshots]
  HtmlGenerator.new.run(options, screenshots)
end