Class: Fastlane::Actions::BuildIosAppAction

Inherits:
Fastlane::Action show all
Defined in:
fastlane/lib/fastlane/actions/build_ios_app.rb

Direct Known Subclasses

BuildAppAction, GymAction

Constant Summary

Constants inherited from Fastlane::Action

Fastlane::Action::AVAILABLE_CATEGORIES, Fastlane::Action::RETURN_TYPES

Class Method Summary collapse

Methods inherited from Fastlane::Action

action_name, authors, deprecated_notes, lane_context, method_missing, other_action, return_type, sample_return_value, shell_out_should_use_bundle_exec?, step_text

Class Method Details

.authorObject


108
109
110
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 108

def self.author
  "KrauseFx"
end

.available_optionsObject


112
113
114
115
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 112

def self.available_options
  require 'gym'
  Gym::Options.available_options
end

.categoryObject


139
140
141
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 139

def self.category
  :building
end

.descriptionObject


88
89
90
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 88

def self.description
  "Easily build and sign your app (via _gym_)"
end

.detailsObject


92
93
94
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 92

def self.details
  "More information: https://fastlane.tools/gym"
end

.example_codeObject


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 121

def self.example_code
  [
    'build_ios_app(scheme: "MyApp", workspace: "MyApp.xcworkspace")',
    'build_ios_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_ios_app"',
    'build_app   # alias for "build_ios_app"'
  ]
end

.is_supported?(platform) ⇒ Boolean

Returns:


117
118
119
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 117

def self.is_supported?(platform)
  [:ios, :mac].include?(platform)
end

.outputObject


96
97
98
99
100
101
102
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 96

def self.output
  [
    ['IPA_OUTPUT_PATH', 'The path to the newly generated ipa file'],
    ['DSYM_OUTPUT_PATH', 'The path to the dSYM files'],
    ['XCODEBUILD_ARCHIVE', 'The path to the xcodebuild archive']
  ]
end

.return_valueObject


104
105
106
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 104

def self.return_value
  "The absolute path to the generated ipa file"
end

.run(values) ⇒ Object


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 10

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
          bundle_id = profile["Entitlements"]["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_ipa_path = File.expand_path(gym_output_path)
  absolute_dsym_path = absolute_ipa_path.gsub(".ipa", ".app.dSYM.zip")

  # This might be the mac app path, so we don't want to set it here
  # https://github.com/fastlane/fastlane/issues/5757
  if absolute_ipa_path.include?(".ipa")
    Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] = absolute_ipa_path
    ENV[SharedValues::IPA_OUTPUT_PATH.to_s] = absolute_ipa_path # for deliver
  end

  Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] = absolute_dsym_path if File.exist?(absolute_dsym_path)
  Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE] = Gym::BuildCommandGenerator.archive_path
  ENV[SharedValues::DSYM_OUTPUT_PATH.to_s] = absolute_dsym_path if File.exist?(absolute_dsym_path)

  return absolute_ipa_path
end

.show_xcode_9_warningObject


143
144
145
146
147
148
# File 'fastlane/lib/fastlane/actions/build_ios_app.rb', line 143

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