ot-ios-builder 0.7.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.md +82 -0
- data/LICENSE +19 -0
- data/README.md +248 -0
- data/lib/beta_builder.rb +435 -0
- data/lib/beta_builder/archived_build.rb +101 -0
- data/lib/beta_builder/build_output_parser.rb +56 -0
- data/lib/beta_builder/deployment_strategies.rb +39 -0
- data/lib/beta_builder/deployment_strategies/testflight.rb +92 -0
- data/lib/beta_builder/deployment_strategies/web.rb +104 -0
- data/lib/beta_builder/release_strategies.rb +34 -0
- data/lib/beta_builder/release_strategies/git.rb +116 -0
- data/lib/ot-ios-builder.rb +1 -0
- metadata +146 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'uuid'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'cfpropertylist'
|
4
|
+
|
5
|
+
module BetaBuilder
|
6
|
+
def self.archive(configuration)
|
7
|
+
if configuration.xcode4_archive_mode
|
8
|
+
Xcode4ArchivedBuild.new(configuration)
|
9
|
+
else
|
10
|
+
ArchivedBuild.new(configuration)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ArchivedBuild
|
15
|
+
def initialize(configuration)
|
16
|
+
@configuration = configuration
|
17
|
+
@uuid = UUID.generate.upcase
|
18
|
+
end
|
19
|
+
|
20
|
+
def save_to(path)
|
21
|
+
archive_path = File.join(path, "#{@uuid}.apparchive")
|
22
|
+
FileUtils.mkdir(archive_path)
|
23
|
+
FileUtils.cp_r(@configuration.built_app_path, archive_path)
|
24
|
+
FileUtils.cp_r(@configuration.built_app_dsym_path, archive_path)
|
25
|
+
archive_path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Xcode4ArchivedBuild
|
30
|
+
def initialize(configuration)
|
31
|
+
@configuration = configuration
|
32
|
+
end
|
33
|
+
|
34
|
+
def archive_file_name
|
35
|
+
"#{@configuration.archive_name} #{Time.now.strftime('%Y-%m-%d %H.%M')}.xcarchive"
|
36
|
+
end
|
37
|
+
|
38
|
+
def archive_path_within(path)
|
39
|
+
File.join(path, "#{Time.now.strftime('%Y-%m-%d')}", archive_file_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def applications_path
|
43
|
+
File.join("Products", "Applications")
|
44
|
+
end
|
45
|
+
|
46
|
+
def dsyms_path
|
47
|
+
"dSYMs"
|
48
|
+
end
|
49
|
+
|
50
|
+
def plist_info_path
|
51
|
+
File.join(@configuration.built_app_path, "Info.plist")
|
52
|
+
end
|
53
|
+
|
54
|
+
def save_to(path)
|
55
|
+
archive_path = archive_path_within(path)
|
56
|
+
FileUtils.mkdir_p(archive_path)
|
57
|
+
|
58
|
+
application_path = File.join(archive_path, applications_path)
|
59
|
+
FileUtils.mkdir_p(application_path)
|
60
|
+
FileUtils.cp_r(@configuration.built_app_path, application_path)
|
61
|
+
|
62
|
+
dsym_path = File.join(archive_path, dsyms_path)
|
63
|
+
FileUtils.mkdir_p(dsym_path)
|
64
|
+
FileUtils.cp_r(@configuration.built_app_dsym_path, dsym_path)
|
65
|
+
|
66
|
+
write_plist_to(archive_path)
|
67
|
+
archive_path
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def write_plist_to(path)
|
73
|
+
version = metadata["CFBundleShortVersionString"] || metadata["CFBundleVersion"]
|
74
|
+
plist = {
|
75
|
+
"ApplicationProperties" => {
|
76
|
+
"ApplicationPath" => File.join("Applications", @configuration.app_file_name),
|
77
|
+
"CFBundleIdentifier" => metadata["CFBundleIdentifier"],
|
78
|
+
"CFBundleShortVersionString" => version,
|
79
|
+
"IconPaths" => metadata["CFBundleIcons"]["CFBundlePrimaryIcon"]["CFBundleIconFiles"].map { |file| File.join("Applications", @configuration.app_file_name, file) }
|
80
|
+
},
|
81
|
+
"ArchiveVersion" => 1.0,
|
82
|
+
"Comment" => @configuration.release_notes_text,
|
83
|
+
"CreationDate" => Time.now,
|
84
|
+
"Name" => @configuration.archive_name,
|
85
|
+
"SchemeName" => @configuration.scheme
|
86
|
+
}
|
87
|
+
File.open(File.join(path, "Info.plist"), "w") do |io|
|
88
|
+
io.write plist.to_plist(:convert_unknown_to_string => true)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def metadata
|
93
|
+
@metadata ||= load_property_list(plist_info_path)
|
94
|
+
end
|
95
|
+
|
96
|
+
def load_property_list(path)
|
97
|
+
plist = CFPropertyList::List.new(:file => path)
|
98
|
+
CFPropertyList.native_types(plist.value)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module BetaBuilder
|
2
|
+
class BuildOutputParser
|
3
|
+
|
4
|
+
def initialize(output)
|
5
|
+
@output = output
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_output_dir
|
9
|
+
# yes, this is truly horrible, but unless somebody else can find a better way...
|
10
|
+
found = @output.split("\n").grep(/^Validate(.*)\/Xcode\/DerivedData\/(.*)-(.*)/).first
|
11
|
+
if found && found =~ /Validate [\"]?([^\"|$]*)/
|
12
|
+
reference = $1
|
13
|
+
else
|
14
|
+
raise "Cannot parse build_dir from build output."
|
15
|
+
end
|
16
|
+
derived_data_directory = reference.split("/Build/Products/").first
|
17
|
+
"#{derived_data_directory}/Build/Products/"
|
18
|
+
end
|
19
|
+
|
20
|
+
def failed?
|
21
|
+
@output.split("\n").any? {|line| line.include? "** BUILD FAILED **"}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# quick testing
|
27
|
+
if __FILE__ == $0
|
28
|
+
|
29
|
+
require 'test/unit'
|
30
|
+
class BuildOutputTest < Test::Unit::TestCase
|
31
|
+
|
32
|
+
def test_parses_output_with_unquoted_build_path
|
33
|
+
bop = BetaBuilder::BuildOutputParser.new(<<eos)
|
34
|
+
Validate /Users/johnsmith/Library/Developer/Xcode/DerivedData/Application-hegpgdbpjylesafhkxnsymrzjavl/Build/Products/Distribution-iphoneos/Application.app
|
35
|
+
cd /Users/user/app/ios
|
36
|
+
setenv PATH \"/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin\"
|
37
|
+
setenv PRODUCT_TYPE com.apple.product-type.application
|
38
|
+
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/Validation /Users/user/Library/Developer/Xcode/DerivedData/Application-hegpgdbpjylesafhkxnsymrzjavl/Build/Products/Distribution-iphoneos/Application.app
|
39
|
+
eos
|
40
|
+
assert_equal "/Users/johnsmith/Library/Developer/Xcode/DerivedData/Application-hegpgdbpjylesafhkxnsymrzjavl/Build/Products/", bop.build_output_dir
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_parses_output_with_quoted_build_path
|
44
|
+
bop = BetaBuilder::BuildOutputParser.new(<<eos)
|
45
|
+
Validate \"/Users/john smith/Library/Developer/Xcode/DerivedData/Application-hegpgdbpjylesafhkxnsymrzjavl/Build/Products/Distribution-iphoneos/Application.app\"
|
46
|
+
cd /Users/user/app/ios
|
47
|
+
setenv PATH \"/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin\"
|
48
|
+
setenv PRODUCT_TYPE com.apple.product-type.application
|
49
|
+
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/Validation /Users/user/Library/Developer/Xcode/DerivedData/Application-hegpgdbpjylesafhkxnsymrzjavl/Build/Products/Distribution-iphoneos/Application.app
|
50
|
+
eos
|
51
|
+
assert_equal "/Users/john smith/Library/Developer/Xcode/DerivedData/Application-hegpgdbpjylesafhkxnsymrzjavl/Build/Products/", bop.build_output_dir
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module BetaBuilder
|
2
|
+
module DeploymentStrategies
|
3
|
+
def self.valid_strategy?(strategy_name)
|
4
|
+
strategies.keys.include?(strategy_name.to_sym)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.build(strategy_name, configuration)
|
8
|
+
strategies[strategy_name.to_sym].new(configuration)
|
9
|
+
end
|
10
|
+
|
11
|
+
class Strategy
|
12
|
+
def initialize(configuration)
|
13
|
+
@configuration = configuration
|
14
|
+
|
15
|
+
if respond_to?(:extended_configuration_for_strategy)
|
16
|
+
@configuration.instance_eval(&extended_configuration_for_strategy)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure(&block)
|
21
|
+
yield @configuration
|
22
|
+
end
|
23
|
+
|
24
|
+
def prepare
|
25
|
+
puts "Nothing to prepare!" if @configuration.verbose
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.strategies
|
32
|
+
{:web => Web, :testflight => TestFlight}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
require File.dirname(__FILE__) + '/deployment_strategies/web'
|
38
|
+
require File.dirname(__FILE__) + '/deployment_strategies/testflight'
|
39
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module BetaBuilder
|
7
|
+
module DeploymentStrategies
|
8
|
+
class TestFlight < Strategy
|
9
|
+
include Rake::DSL
|
10
|
+
include FileUtils
|
11
|
+
ENDPOINT = "https://testflightapp.com/api/builds.json"
|
12
|
+
|
13
|
+
def extended_configuration_for_strategy
|
14
|
+
proc do
|
15
|
+
def generate_release_notes(&block)
|
16
|
+
self.release_notes = block if block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def deploy
|
22
|
+
release_notes = get_notes
|
23
|
+
payload = {
|
24
|
+
:api_token => @configuration.api_token,
|
25
|
+
:team_token => @configuration.team_token,
|
26
|
+
:file => File.new(@configuration.ipa_path, 'rb'),
|
27
|
+
:notes => release_notes,
|
28
|
+
:distribution_lists => (@configuration.distribution_lists || []).join(","),
|
29
|
+
:notify => @configuration.notify || false,
|
30
|
+
:replace => @configuration.replace || false
|
31
|
+
}
|
32
|
+
if @configuration.verbose
|
33
|
+
puts "ipa path: #{@configuration.ipa_path}"
|
34
|
+
puts "release notes: #{release_notes}"
|
35
|
+
end
|
36
|
+
|
37
|
+
if @configuration.dry_run
|
38
|
+
puts '** Dry Run - No action here! **'
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
42
|
+
print "Uploading build to TestFlight..."
|
43
|
+
|
44
|
+
begin
|
45
|
+
response = RestClient.post(ENDPOINT, payload, :accept => :json)
|
46
|
+
rescue => e
|
47
|
+
response = e.response
|
48
|
+
end
|
49
|
+
|
50
|
+
if (response.code == 201) || (response.code == 200)
|
51
|
+
puts "Done."
|
52
|
+
else
|
53
|
+
puts "Failed."
|
54
|
+
puts "#{response}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def get_notes
|
61
|
+
notes = @configuration.release_notes_text
|
62
|
+
notes || get_notes_using_editor || get_notes_using_prompt
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_notes_using_editor
|
66
|
+
return unless (editor = ENV["EDITOR"])
|
67
|
+
|
68
|
+
dir = Dir.mktmpdir
|
69
|
+
begin
|
70
|
+
filepath = "#{dir}/release_notes"
|
71
|
+
system("#{editor} #{filepath}")
|
72
|
+
@configuration.release_notes = File.read(filepath)
|
73
|
+
ensure
|
74
|
+
rm_rf(dir)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_notes_using_prompt
|
79
|
+
puts "Enter the release notes for this build (hit enter twice when done):\n"
|
80
|
+
@configuration.release_notes = gets_until_match(/\n{2}$/).strip
|
81
|
+
end
|
82
|
+
|
83
|
+
def gets_until_match(pattern, string = "")
|
84
|
+
if (string += STDIN.gets) =~ pattern
|
85
|
+
string
|
86
|
+
else
|
87
|
+
gets_until_match(pattern, string)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module BetaBuilder
|
2
|
+
module DeploymentStrategies
|
3
|
+
class Web < Strategy
|
4
|
+
def extended_configuration_for_strategy
|
5
|
+
proc do
|
6
|
+
def deployment_url
|
7
|
+
File.join(deploy_to, ipa_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def manifest_url
|
11
|
+
File.join(deploy_to, "manifest.plist")
|
12
|
+
end
|
13
|
+
|
14
|
+
def remote_installation_path
|
15
|
+
File.join(remote_directory)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def prepare
|
21
|
+
plist = CFPropertyList::List.new(:file => "#{@configuration.built_app_path}/Info.plist")
|
22
|
+
plist_data = CFPropertyList.native_types(plist.value)
|
23
|
+
File.open("pkg/dist/manifest.plist", "w") do |io|
|
24
|
+
io << %{<?xml version="1.0" encoding="UTF-8"?>
|
25
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
26
|
+
<plist version="1.0">
|
27
|
+
<dict>
|
28
|
+
<key>items</key>
|
29
|
+
<array>
|
30
|
+
<dict>
|
31
|
+
<key>assets</key>
|
32
|
+
<array>
|
33
|
+
<dict>
|
34
|
+
<key>kind</key>
|
35
|
+
<string>software-package</string>
|
36
|
+
<key>url</key>
|
37
|
+
<string>#{@configuration.deployment_url}</string>
|
38
|
+
</dict>
|
39
|
+
</array>
|
40
|
+
<key>metadata</key>
|
41
|
+
<dict>
|
42
|
+
<key>bundle-identifier</key>
|
43
|
+
<string>#{plist_data['CFBundleIdentifier']}</string>
|
44
|
+
<key>bundle-version</key>
|
45
|
+
<string>#{plist_data['CFBundleVersion']}</string>
|
46
|
+
<key>kind</key>
|
47
|
+
<string>software</string>
|
48
|
+
<key>title</key>
|
49
|
+
<string>#{plist_data['CFBundleDisplayName']}</string>
|
50
|
+
</dict>
|
51
|
+
</dict>
|
52
|
+
</array>
|
53
|
+
</dict>
|
54
|
+
</plist>
|
55
|
+
}
|
56
|
+
end
|
57
|
+
File.open("pkg/dist/index.html", "w") do |io|
|
58
|
+
io << %{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
59
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
60
|
+
<head>
|
61
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
62
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
|
63
|
+
<title>Beta Download</title>
|
64
|
+
<style type="text/css">
|
65
|
+
body {background:#fff;margin:0;padding:0;font-family:arial,helvetica,sans-serif;text-align:center;padding:10px;color:#333;font-size:16px;}
|
66
|
+
#container {width:300px;margin:0 auto;}
|
67
|
+
h1 {margin:0;padding:0;font-size:14px;}
|
68
|
+
p {font-size:13px;}
|
69
|
+
.link {background:#ecf5ff;border-top:1px solid #fff;border:1px solid #dfebf8;margin-top:.5em;padding:.3em;}
|
70
|
+
.link a {text-decoration:none;font-size:15px;display:block;color:#069;}
|
71
|
+
</style>
|
72
|
+
</head>
|
73
|
+
<body>
|
74
|
+
<div id="container">
|
75
|
+
<div class="link"><a href="itms-services://?action=download-manifest&url=#{@configuration.manifest_url}">Tap Here to Install<br />#{@configuration.target} #{plist_data['CFBundleVersion']}<br />On Your Device</a></div>
|
76
|
+
<p><strong>Link didn't work?</strong><br />
|
77
|
+
Make sure you're visiting this page on your device, not your computer.</p>
|
78
|
+
</div>
|
79
|
+
</body>
|
80
|
+
</html>
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def deploy
|
86
|
+
cmd = []
|
87
|
+
|
88
|
+
cmd.push "scp"
|
89
|
+
|
90
|
+
if @configuration.remote_port
|
91
|
+
cmd.push "-P #{@configuration.remote_port}"
|
92
|
+
end
|
93
|
+
|
94
|
+
cmd.push "pkg/dist/*"
|
95
|
+
cmd.push "#{@configuration.remote_host}:#{@configuration.remote_installation_path}"
|
96
|
+
|
97
|
+
cmd = cmd.join(" ")
|
98
|
+
|
99
|
+
puts "* Running `#{cmd}`"
|
100
|
+
system(cmd)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module BetaBuilder
|
2
|
+
module ReleaseStrategies
|
3
|
+
def self.valid_strategy?(strategy_name)
|
4
|
+
strategies.keys.include?(strategy_name.to_sym)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.build(strategy_name, configuration)
|
8
|
+
strategies[strategy_name.to_sym].new(configuration)
|
9
|
+
end
|
10
|
+
|
11
|
+
class ReleaseStrategy
|
12
|
+
def initialize(configuration)
|
13
|
+
@configuration = configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
def configure(&block)
|
17
|
+
yield self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def prepare
|
22
|
+
puts "Nothing to prepare!" if @configuration.verbose
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.strategies
|
28
|
+
{:git => Git}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require File.dirname(__FILE__) + '/release_strategies/git'
|
34
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module BetaBuilder
|
2
|
+
module ReleaseStrategies
|
3
|
+
class Git < ReleaseStrategy
|
4
|
+
attr_accessor :branch, :origin, :tag_name
|
5
|
+
|
6
|
+
def prepare
|
7
|
+
|
8
|
+
if @origin == nil then
|
9
|
+
@origin = "origin"
|
10
|
+
end
|
11
|
+
|
12
|
+
if @branch == nil then
|
13
|
+
@branch = "master"
|
14
|
+
end
|
15
|
+
|
16
|
+
if @tag_name == nil then
|
17
|
+
@tag_name = "v#{@configuration.build_number}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def tag_current_version
|
22
|
+
puts "Relasing with Git"
|
23
|
+
print "Tagging version #{@tag_name}"
|
24
|
+
cmd = []
|
25
|
+
|
26
|
+
#first, tag
|
27
|
+
cmd << "git"
|
28
|
+
cmd << "tag"
|
29
|
+
# -f sounds brutal to start with, so let's give it a try without
|
30
|
+
# cmd << "-f"
|
31
|
+
cmd << @tag_name
|
32
|
+
|
33
|
+
cmd << "2>&1 %s git.output" % (@configuration.verbose ? '| tee' : '>')
|
34
|
+
system(cmd.join " ")
|
35
|
+
puts
|
36
|
+
puts "Done"
|
37
|
+
|
38
|
+
# then push tags to the remote server
|
39
|
+
print "Pushing tag to #{@origin} on branch #{@branch}"
|
40
|
+
cmd = []
|
41
|
+
|
42
|
+
cmd << "git"
|
43
|
+
cmd << "push"
|
44
|
+
cmd << "--tags"
|
45
|
+
cmd << @origin
|
46
|
+
cmd << @branch
|
47
|
+
cmd << "2>&1 %s git.output" % (@configuration.verbose ? '| tee' : '>')
|
48
|
+
system(cmd.join " ")
|
49
|
+
|
50
|
+
puts
|
51
|
+
puts "Done"
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def prepare_for_next_pod_release
|
56
|
+
build_number = @configuration.build_number
|
57
|
+
raise "build number cannot be empty on release" unless (build_number != nil) && (!build_number.empty?)
|
58
|
+
|
59
|
+
print "Committing #{@configuration.app_info_plist} and #{@configuration.spec_file} with version #{build_number}"
|
60
|
+
|
61
|
+
stage_files [@configuration.app_info_plist, @configuration.spec_file]
|
62
|
+
commit_and_push_with_message "Preparing for next pod release..."
|
63
|
+
|
64
|
+
puts "Done"
|
65
|
+
end
|
66
|
+
|
67
|
+
def prepare_for_next_release
|
68
|
+
build_number = @configuration.build_number
|
69
|
+
raise "build number cannot be empty on release" unless (build_number != nil) && (!build_number.empty?)
|
70
|
+
|
71
|
+
print "Committing #{@configuration.app_info_plist} with version #{build_number}"
|
72
|
+
|
73
|
+
stage_files [@configuration.app_info_plist]
|
74
|
+
commit_and_push_with_message "Preparing for next release..."
|
75
|
+
|
76
|
+
puts "Done"
|
77
|
+
end
|
78
|
+
|
79
|
+
def stage_files files
|
80
|
+
cmd = []
|
81
|
+
|
82
|
+
cmd << "git"
|
83
|
+
cmd << "add"
|
84
|
+
files.each do |value|
|
85
|
+
cmd << value
|
86
|
+
end
|
87
|
+
system(cmd.join " ")
|
88
|
+
end
|
89
|
+
|
90
|
+
def commit_and_push_with_message message
|
91
|
+
# then commit it
|
92
|
+
cmd = []
|
93
|
+
cmd << "git"
|
94
|
+
cmd << "commit"
|
95
|
+
cmd << "-m"
|
96
|
+
cmd << "'#{message}'"
|
97
|
+
cmd << "2>&1 %s git.output" % (@configuration.verbose ? '| tee' : '>')
|
98
|
+
system(cmd.join " ")
|
99
|
+
puts
|
100
|
+
puts "Done"
|
101
|
+
|
102
|
+
# now, push the updated plist
|
103
|
+
print "Pushing update to #{@origin}/#{@branch}"
|
104
|
+
cmd = []
|
105
|
+
cmd << "git"
|
106
|
+
cmd << "push"
|
107
|
+
cmd << @origin
|
108
|
+
cmd << @branch
|
109
|
+
cmd << "2>&1 %s git.output" % (@configuration.verbose ? '| tee' : '>')
|
110
|
+
|
111
|
+
system(cmd.join " ")
|
112
|
+
puts
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|