Class: Fastlane::Actions::BuildAppAction

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

Direct Known Subclasses

BuildIosAppAction, BuildMacAppAction, 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


121
122
123
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 121

def self.author
  "KrauseFx"
end

.available_optionsObject


125
126
127
128
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 125

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

.categoryObject


153
154
155
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 153

def self.category
  :building
end

.descriptionObject

rubocop:enable Metrics/PerceivedComplexity


100
101
102
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 100

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

.detailsObject


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

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

.example_codeObject


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 134

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) ⇒ Boolean

Returns:


130
131
132
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 130

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

.outputObject


108
109
110
111
112
113
114
115
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 108

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_valueObject


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

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

.run(values) ⇒ Object


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
87
88
89
90
91
92
93
94
95
96
97
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 11

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_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_warningObject


157
158
159
160
161
162
# File 'fastlane/lib/fastlane/actions/build_app.rb', line 157

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