class Fastlane::Actions::BuildAppAction

Public Class Methods

author() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 127
def self.author
  "KrauseFx"
end
available_options() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 131
def self.available_options
  require 'gym'
  Gym::Options.available_options
end
category() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 159
def self.category
  :building
end
description() click to toggle source

rubocop:enable Metrics/PerceivedComplexity

# File fastlane/lib/fastlane/actions/build_app.rb, line 102
def self.description
  "Easily build and sign your app (via _gym_)"
end
details() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 106
def self.details
  "More information: https://fastlane.tools/gym"
end
example_code() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 140
def self.example_code
  [
    'build_app(scheme: "MyApp", workspace: "MyApp.xcworkspace")',
    'build_app(
      workspace: "MyApp.xcworkspace",
      configuration: "Debug",
      scheme: "MyApp",
      silent: true,
      clean: true,
      output_directory: "path/to/dir", # Destination directory. Defaults to current directory.
      output_name: "my-app.ipa",       # specify the name of the .ipa file to generate (including file extension)
      sdk: "iOS 11.1"                  # use SDK as the name or path of the base SDK when building the project.
    )',
    'gym              # alias for "build_app"',
    'build_ios_app    # alias for "build_app (only iOS options)"',
    'build_mac_app    # alias for "build_app (only macOS options)"'
  ]
end
is_supported?(platform) click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 136
def self.is_supported?(platform)
  [:ios, :mac].include?(platform)
end
output() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 110
def self.output
  [
    ['IPA_OUTPUT_PATH', 'The path to the newly generated ipa file'],
    ['PKG_OUTPUT_PATH', 'The path to the newly generated pkg file'],
    ['DSYM_OUTPUT_PATH', 'The path to the dSYM files'],
    ['XCODEBUILD_ARCHIVE', 'The path to the xcodebuild archive']
  ]
end
return_type() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 123
def self.return_type
  :string
end
return_value() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 119
def self.return_value
  "The absolute path to the generated ipa file"
end
run(values) click to toggle source

rubocop:disable Metrics/PerceivedComplexity

# File fastlane/lib/fastlane/actions/build_app.rb, line 12
def self.run(values)
  require 'gym'

  unless Actions.lane_context[SharedValues::SIGH_PROFILE_TYPE].to_s == "development"
    values[:export_method] ||= Actions.lane_context[SharedValues::SIGH_PROFILE_TYPE]
  end

  if Actions.lane_context[SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING]
    # Since Xcode 9 you need to explicitly provide the provisioning profile per app target
    # If the user is smart and uses match and gym together with fastlane, we can do all
    # the heavy lifting for them
    values[:export_options] ||= {}
    # It's not always a hash, because the user might have passed a string path to a ready plist file
    # If that's the case, we won't set the provisioning profiles
    # see https://github.com/fastlane/fastlane/issues/9490
    if values[:export_options].kind_of?(Hash)
      match_mapping = (Actions.lane_context[SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING] || {}).dup
      existing_mapping = (values[:export_options][:provisioningProfiles] || {}).dup

      # Be smart about how we merge those mappings in case there are conflicts
      mapping_object = Gym::CodeSigningMapping.new
      hash_to_use = mapping_object.merge_profile_mapping(primary_mapping: existing_mapping,
                                                       secondary_mapping: match_mapping,
                                                          export_method: values[:export_method])

      values[:export_options][:provisioningProfiles] = hash_to_use
    else
      self.show_xcode_9_warning
    end
  elsif Actions.lane_context[SharedValues::SIGH_PROFILE_PATHS]
    # Since Xcode 9 you need to explicitly provide the provisioning profile per app target
    # If the user used sigh we can match the profiles from sigh
    values[:export_options] ||= {}
    if values[:export_options].kind_of?(Hash)
      # It's not always a hash, because the user might have passed a string path to a ready plist file
      # If that's the case, we won't set the provisioning profiles
      # see https://github.com/fastlane/fastlane/issues/9684
      values[:export_options][:provisioningProfiles] ||= {}
      Actions.lane_context[SharedValues::SIGH_PROFILE_PATHS].each do |profile_path|
        begin
          profile = FastlaneCore::ProvisioningProfile.parse(profile_path)
          app_id_prefix = profile["ApplicationIdentifierPrefix"].first
          entitlements = profile["Entitlements"]
          bundle_id = (entitlements["application-identifier"] || entitlements["com.apple.application-identifier"]).gsub("#{app_id_prefix}.", "")
          values[:export_options][:provisioningProfiles][bundle_id] = profile["Name"]
        rescue => ex
          UI.error("Couldn't load profile at path: #{profile_path}")
          UI.error(ex)
          UI.verbose(ex.backtrace.join("\n"))
        end
      end
    else
      self.show_xcode_9_warning
    end
  end

  gym_output_path = Gym::Manager.new.work(values)
  if gym_output_path.nil?
    UI.important("No output path received from gym")
    return nil
  end

  absolute_output_path = File.expand_path(gym_output_path)

  # Binary path
  if File.extname(absolute_output_path) == ".ipa"
    absolute_dsym_path = absolute_output_path.gsub(/.ipa$/, ".app.dSYM.zip")

    Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] = absolute_output_path
    ENV[SharedValues::IPA_OUTPUT_PATH.to_s] = absolute_output_path # for deliver
  elsif File.extname(absolute_output_path) == ".pkg"
    absolute_dsym_path = absolute_output_path.gsub(/.pkg$/, ".dSYM.zip")

    Actions.lane_context[SharedValues::PKG_OUTPUT_PATH] = absolute_output_path
    ENV[SharedValues::PKG_OUTPUT_PATH.to_s] = absolute_output_path # for deliver
  end

  # xcarchive path
  Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE] = Gym::BuildCommandGenerator.archive_path

  # dSYM path
  if absolute_dsym_path && File.exist?(absolute_dsym_path)
    Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] = absolute_dsym_path
    ENV[SharedValues::DSYM_OUTPUT_PATH.to_s] = absolute_dsym_path
  end

  return absolute_output_path
end
show_xcode_9_warning() click to toggle source
# File fastlane/lib/fastlane/actions/build_app.rb, line 163
def self.show_xcode_9_warning
  return unless Helper.xcode_at_least?("9.0")
  UI.message("You passed a path to a custom plist file for exporting the binary.")
  UI.message("Make sure to include information about what provisioning profiles to use with Xcode 9")
  UI.message("More information: https://docs.fastlane.tools/codesigning/xcode-project/#xcode-9-and-up")
end