Class: Testflight::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/testflight/builder.rb

Constant Summary collapse

XCODE_BUILDER =
"/usr/bin/xcodebuild"
XCODE_PACKAGER =
"/usr/bin/xcrun"
TESTFLIGHT_ENDPOINT =
"http://testflightapp.com/api/builds.json"

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Builder

Returns a new instance of Builder.



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
# File 'lib/testflight/builder.rb', line 33

def initialize(opts = {})
  t0 = Time.now

  if Testflight::Config.commit_changes?
    commit_changes(opts)
  end
  
  if Testflight::Config.tag_build?
    tag_build(opts)
  end

  if Testflight::Config.workspace?
    build_workspace(opts)
    package_workspace(opts)
    package_workspace_dSYM(opts)
  else
    clean_project(opts)
    build_project(opts)
    package_project(opts)
    package_project_dSYM(opts)
  end

  upload_to_testflightapp(opts)
  
  append_log_entry(opts)

  if Testflight::Config.increment_bundle?
    increment_bundle_version(opts)
    if Testflight::Config.commit_changes?
      commit_changes(opts.merge(:message => "Incrementing build number to #{Testflight::Config.project_version}"))
    end
  end

  t1 = Time.now

  puts("\n\nBuild took #{t1-t0} seconds.")
end

Instance Method Details

#append_log_entry(opts) ⇒ Object

FlightLog Support



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/testflight/builder.rb', line 186

def append_log_entry(opts)
  lines = []
  lines << "#{Testflight::Config.application_name} #{Testflight::Config.project_version}"
  lines << "Deplyed On: #{Time.now}"
  lines << "Distributed To: #{opts[:teams].join(", ")}"
  lines << "Notified By Email: #{opts[:notify]}"
  lines << "Notes: #{opts[:message]}"
  lines << "---------------------------------------------------------------------------"

  log = "FLIGHTLOG"
  tmp = log + "~"

  File.open(tmp, "w") do |newfile|
    lines.each do |line|
      newfile.puts(line)
    end

    if File.exist?(log)
      File.open(log, "r+") do |oldfile|
        oldfile.each_line do |line| 
          newfile.puts(line) 
        end
      end
    end
  end

  File.delete(log) if File.exist?(log)
  File.rename(tmp, log)
end

#build_project(opts = {}) ⇒ Object



92
93
94
95
96
97
98
99
100
# File 'lib/testflight/builder.rb', line 92

def build_project(opts = {})
  cmd = "#{XCODE_BUILDER} -project '#{Testflight::Config.application_name}.xcodeproj' "
  cmd << "-arch #{Testflight::Config.architecture} "
  cmd << "-target '#{Testflight::Config.application_name}' "
  cmd << "-configuration '#{Testflight::Config.configuration}' "
  cmd << "-sdk '#{Testflight::Config.sdk}' "
  cmd << "build VALID_ARCHS='#{Testflight::Config.architecture}' "
  execute(cmd, opts)
end

#build_workspace(opts = {}) ⇒ Object

Building Project



75
76
77
78
79
80
81
82
83
# File 'lib/testflight/builder.rb', line 75

def build_workspace(opts = {})
  cmd = "#{XCODE_BUILDER} -workspace '#{Testflight::Config.workspace_name}' "
  cmd << "-scheme '#{Testflight::Config.application_name}' "
  cmd << "-sdk '#{Testflight::Config.sdk_version}' "
  cmd << "-configuration '#{Testflight::Config.configuration}' "
  cmd << "-arch '#{Testflight::Config.architecture}' "
  cmd << "CONFIGURATION_BUILD_DIR='#{Testflight::Config.build_dir}' "
  execute(cmd, opts)
end

#clean_project(opts = {}) ⇒ Object



85
86
87
88
89
90
# File 'lib/testflight/builder.rb', line 85

def clean_project(opts = {})
  cmd = "#{XCODE_BUILDER} -project '#{Testflight::Config.application_name}.xcodeproj' "
  cmd << "-configuration '#{Testflight::Config.configuration}' "
  cmd << "-alltargets clean "
  execute(cmd, opts)
end

#commit_changes(opts = {}) ⇒ Object

Git Support



172
173
174
175
176
177
# File 'lib/testflight/builder.rb', line 172

def commit_changes(opts = {})
  execute("git add .", opts.merge(:ignore_result => true))
  execute("git add . --update", opts.merge(:ignore_result => true))
  execute("git commit -m '#{opts[:message]}'", opts.merge(:ignore_result => true))
  execute("git push", opts.merge(:ignore_result => true))
end

#execute(cmd, opts = {}) ⇒ Object

Command Support



219
220
221
222
223
224
225
226
227
228
229
# File 'lib/testflight/builder.rb', line 219

def execute(cmd, opts = {})
  puts("\r\n$ " + cmd)
  return if opts[:cold]

  result = system(cmd)
  return if opts[:ignore_result]

  unless result
    raise "Build failed"
  end
end

#increment_bundle_version(opts = {}) ⇒ Object

Project Versioning



154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/testflight/builder.rb', line 154

def increment_bundle_version(opts = {})
  # Check if build numbers are numeric
  build_number = Testflight::Config.build_number.to_i 
  build_number += 1

  puts("\r\nIncrementing build number to #{build_number}...")

  return if opts[:cold]
  Testflight::Config.project_info["CFBundleVersion"] = build_number.to_s
  
  File.open(Testflight::Config.project_info_path, "w") do |f| 
    f.write(Testflight::Config.project_info.to_plist) 
  end
end

#package_project(opts = {}) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/testflight/builder.rb', line 120

def package_project(opts = {})
  cmd = "#{XCODE_PACKAGER} -sdk iphoneos PackageApplication "
  cmd << "-v '#{Testflight::Config.release_dir}/#{Testflight::Config.application_name}.app' "
  cmd << "-o '#{Testflight::Config.distribution_file}' "
  cmd << "--sign '#{Testflight::Config.developer_name}' "
  cmd << "--embed '#{Testflight::Config.provisioning_dir}/#{Testflight::Config.ad_hoc_provisioning_name}'"
  execute(cmd, opts)
end

#package_project_dSYM(opts = {}) ⇒ Object



129
130
131
132
# File 'lib/testflight/builder.rb', line 129

def package_project_dSYM(opts = {})
  cmd = "zip -r '#{Testflight::Config.distribution_dsym_file}' '#{Testflight::Config.release_dir}/#{Testflight::Config.build_name}.app.dSYM'"
  execute(cmd, opts)
end

#package_workspace(opts = {}) ⇒ Object

Packaging Project



106
107
108
109
110
111
112
113
# File 'lib/testflight/builder.rb', line 106

def package_workspace(opts = {})
  cmd = "#{XCODE_PACKAGER} -sdk iphoneos PackageApplication "
  cmd << "-v '#{Testflight::Config.build_dir}/#{Testflight::Config.build_name}.app' "
  cmd << "-o '#{Testflight::Config.distribution_file}' "
  cmd << "--sign '#{Testflight::Config.developer_name}' "
  cmd << "--embed '#{Testflight::Config.provisioning_dir}/#{Testflight::Config.ad_hoc_provisioning_name}'"
  execute(cmd, opts)
end

#package_workspace_dSYM(opts = {}) ⇒ Object



115
116
117
118
# File 'lib/testflight/builder.rb', line 115

def package_workspace_dSYM(opts = {})
  cmd = "zip -r '#{Testflight::Config.distribution_dsym_file}' '#{Testflight::Config.build_dir}/#{Testflight::Config.build_name}.app.dSYM'"
  execute(cmd, opts)
end

#tag_build(opts = {}) ⇒ Object



179
180
181
# File 'lib/testflight/builder.rb', line 179

def tag_build(opts = {})
  execute("git tag -a #{Testflight::Config.project_version_short} -m 'Release #{Testflight::Config.project_version}'", opts.merge(:ignore_result => true))
end

#upload_to_testflightapp(opts = {}) ⇒ Object

Uploading Project



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/testflight/builder.rb', line 138

def upload_to_testflightapp(opts = {})
  cmd = "curl #{TESTFLIGHT_ENDPOINT} "
  cmd << "-F file=@#{Testflight::Config.distribution_file} "
  cmd << "-F dsym=@#{Testflight::Config.distribution_dsym_file} "
  cmd << "-F api_token=#{Testflight::Config.api_token} "
  cmd << "-F team_token=#{Testflight::Config.team_token} "
  cmd << "-F notify=#{opts[:notify]} "
  cmd << "-F distribution_lists=#{opts[:teams].join(",")} "
  cmd << "-F notes='#{opts[:message]}'"
  execute(cmd, opts)
end