betabuilder 0.1.2 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.md +16 -0
- data/README.md +45 -10
- data/lib/beta_builder.rb +27 -74
- data/lib/beta_builder/deployment_strategies.rb +38 -0
- data/lib/beta_builder/deployment_strategies/testflight.rb +60 -0
- data/lib/beta_builder/deployment_strategies/web.rb +91 -0
- metadata +43 -7
data/CHANGES.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
## 0.2.1
|
2
|
+
* Allow the namespace of generated tasks to be customised
|
3
|
+
|
4
|
+
## 0.2
|
5
|
+
* Introduced deployment strategies, allowing custom deployment methods
|
6
|
+
* Added support for deploying beta releases to TestFlightApp.com
|
7
|
+
|
8
|
+
## 0.1.2
|
9
|
+
|
10
|
+
* Allow custom hosts when using the SCP deployment task (simonjefford)
|
11
|
+
|
12
|
+
## 0.1.1
|
13
|
+
* Fixed missing dependency
|
14
|
+
|
15
|
+
## 0.1
|
16
|
+
* Initial Release
|
data/README.md
CHANGED
@@ -33,30 +33,65 @@ Because BetaBuilder is a Rake task library, you do not need to define any tasks
|
|
33
33
|
|
34
34
|
# the Xcode configuration profile
|
35
35
|
config.configuration = "Adhoc"
|
36
|
-
|
37
|
-
# where the distribution files will be uploaded to
|
38
|
-
config.deploy_to = "http://yourwebsite.com/betas/"
|
39
36
|
end
|
40
37
|
|
41
38
|
Now, if you run `rake -T` in Terminal.app in the root of your project, the available tasks will be printed with a brief description of each one:
|
42
39
|
|
43
40
|
rake beta:build # Build the beta release of the app
|
44
|
-
rake beta:deploy # Deploy the beta to your server
|
45
41
|
rake beta:package # Package the beta release as an IPA file
|
46
42
|
|
47
|
-
To deploy
|
43
|
+
To deploy your beta to your testers, some additional configuration is needed (see the next section).
|
48
44
|
|
49
|
-
Most of the time, you'll not need to run the `beta:build` task directly; it will be run automatically as a dependency of `beta:package`. Upon running this task, your ad-hoc build will be packaged into an IPA file and will be saved in
|
45
|
+
Most of the time, you'll not need to run the `beta:build` task directly; it will be run automatically as a dependency of `beta:package`. Upon running this task, your ad-hoc build will be packaged into an IPA file and will be saved in `${PROJECT_ROOT}/pkg/dist`, along with a HTML index file and the manifest file needed for over-the-air installation.
|
50
46
|
|
51
47
|
If you are not using the automatic deployment task, you will need to upload the contents of the pkg/dist directory to your server.
|
52
48
|
|
53
|
-
|
49
|
+
To use a namespace other than "beta" for the generated tasks, simply pass in your chosen namespace to BetaBuilder::Tasks.new:
|
54
50
|
|
55
|
-
BetaBuilder
|
51
|
+
BetaBuilder::Tasks.new(:my_custom_namespace) do |config|
|
52
|
+
end
|
53
|
+
|
54
|
+
This lets you set up different sets of BetaBuilder tasks for different configurations in the same Rakefile (e.g. a production and staging build).
|
55
|
+
|
56
|
+
## Automatic deployment with deployment strategies
|
57
|
+
|
58
|
+
BetaBuilder allows you to deploy your built package using it's extensible deployment strategy system; the gem currently comes with support for simple web-based deployment or uploading to [TestFlightApp.com](http://www.testflightapp.com). Eventually, you will be able to write your own custom deployment strategies if neither of these are suitable for your needs.
|
59
|
+
|
60
|
+
### Deploying your app with TestFlight
|
56
61
|
|
57
|
-
|
62
|
+
By far the easiest way to get your beta release into the hands of your testers is using the excellent [TestFlight service](http://testflightapp.com/), although at the time of writing it is still in private beta. You can use TestFlight to manage your beta testers and notify them of new releases instantly.
|
63
|
+
|
64
|
+
TestFlight provides an upload API and betabuilder uses that to provide a `:testflight` upload strategy. This strategy requires two pieces of information: your TestFlight API token and your team token:
|
65
|
+
|
66
|
+
config.deploy_using(:testflight) do |tf|
|
67
|
+
tf.api_token = "YOUR_API_TOKEN"
|
68
|
+
tf.team_token = "YOUR_TEAM_TOKEN"
|
69
|
+
end
|
70
|
+
|
71
|
+
Now, instead of using the `beta:package` task, you can run the `beta:deploy` task instead. This task will run the package task as a dependency and upload the generated IPA file to TestFlight.
|
72
|
+
|
73
|
+
You will be prompted to enter the release notes for the build; TestFlight requires these to inform your testers of what has changed in this build. Alternatively, if you have a way of generating the release notes automatically (for instance, using a CHANGELOG file or a git log command), you can specify a block that will be called at runtime - you can do whatever you want in this block, as long as you return a string which will be used as the release notes, e.g.
|
74
|
+
|
75
|
+
config.deploy_using(:testflight) do |tf|
|
76
|
+
...
|
77
|
+
tf.generate_release_notes do
|
78
|
+
# return release notes here
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
### Deploying to your own server
|
83
|
+
|
84
|
+
BetaBuilder also comes with a rather rudimentary web-based deployment task that uses SCP, so you will need SSH access to your server and appropriate permissions to use it. This works in the same way as the original iOS-BetaBuilder GUI app by generating a HTML template and manifest file that can be uploaded to a directly on your server. It includes links to install the app automatically on the device or download the IPA file.
|
85
|
+
|
86
|
+
You will to configure betabuilder to use the `web` deployment strategy with some additional configuration:
|
87
|
+
|
88
|
+
config.deploy_using(:web) do |web|
|
89
|
+
web.deploy_to = "http://beta.myserver.co.uk/myapp"
|
90
|
+
web.remote_host = "myserver.com"
|
91
|
+
web.remote_directory = "/remote/path/to/deployment/directory"
|
92
|
+
end
|
58
93
|
|
59
|
-
|
94
|
+
The `deploy_to` setting specifies the URL that your app will be published to. The `remote_host` setting is the SSH host that will be used to copy the files to your server using SCP. Finally, the `remote_directory` setting is the path to the location to your server that files will be uploaded to. You will need to configure any virtual hosts on your server to make this work.
|
60
95
|
|
61
96
|
## License
|
62
97
|
|
data/lib/beta_builder.rb
CHANGED
@@ -3,16 +3,18 @@ require 'ostruct'
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'cfpropertylist'
|
5
5
|
require 'beta_builder/archived_build'
|
6
|
+
require 'beta_builder/deployment_strategies'
|
6
7
|
|
7
8
|
module BetaBuilder
|
8
9
|
class Tasks < ::Rake::TaskLib
|
9
|
-
def initialize(&block)
|
10
|
+
def initialize(namespace = :beta, &block)
|
10
11
|
@configuration = Configuration.new(
|
11
12
|
:configuration => "Adhoc",
|
12
13
|
:build_dir => "build",
|
13
14
|
:auto_archive => false,
|
14
15
|
:archive_path => File.expand_path("~/Library/MobileDevice/Archived Applications/")
|
15
16
|
)
|
17
|
+
@namespace = namespace
|
16
18
|
yield @configuration if block_given?
|
17
19
|
define
|
18
20
|
end
|
@@ -38,23 +40,28 @@ module BetaBuilder
|
|
38
40
|
"#{built_app_path}.dSYM"
|
39
41
|
end
|
40
42
|
|
41
|
-
def
|
42
|
-
File.join(
|
43
|
+
def dist_path
|
44
|
+
File.join("pkg/dist")
|
43
45
|
end
|
44
46
|
|
45
|
-
def
|
46
|
-
File.join(
|
47
|
+
def ipa_path
|
48
|
+
File.join(dist_path, ipa_name)
|
47
49
|
end
|
48
50
|
|
49
|
-
def
|
50
|
-
|
51
|
+
def deploy_using(strategy_name, &block)
|
52
|
+
if DeploymentStrategies.valid_strategy?(strategy_name.to_sym)
|
53
|
+
self.deployment_strategy = DeploymentStrategies.build(strategy_name, self)
|
54
|
+
self.deployment_strategy.configure(&block)
|
55
|
+
else
|
56
|
+
raise "Unknown deployment strategy '#{strategy_name}'."
|
57
|
+
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
|
54
61
|
private
|
55
62
|
|
56
63
|
def define
|
57
|
-
namespace
|
64
|
+
namespace(@namespace) do
|
58
65
|
desc "Build the beta release of the app"
|
59
66
|
task :build => :clean do
|
60
67
|
system("xcodebuild #{@configuration.build_arguments} build")
|
@@ -78,74 +85,20 @@ module BetaBuilder
|
|
78
85
|
end
|
79
86
|
FileUtils.mkdir('pkg/dist')
|
80
87
|
FileUtils.mv("pkg/#{@configuration.ipa_name}", "pkg/dist")
|
81
|
-
plist = CFPropertyList::List.new(:file => "pkg/Payload/#{@configuration.app_name}/Info.plist")
|
82
|
-
plist_data = CFPropertyList.native_types(plist.value)
|
83
|
-
File.open("pkg/dist/manifest.plist", "w") do |io|
|
84
|
-
io << %{
|
85
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
86
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
87
|
-
<plist version="1.0">
|
88
|
-
<dict>
|
89
|
-
<key>items</key>
|
90
|
-
<array>
|
91
|
-
<dict>
|
92
|
-
<key>assets</key>
|
93
|
-
<array>
|
94
|
-
<dict>
|
95
|
-
<key>kind</key>
|
96
|
-
<string>software-package</string>
|
97
|
-
<key>url</key>
|
98
|
-
<string>#{@configuration.deployment_url}</string>
|
99
|
-
</dict>
|
100
|
-
</array>
|
101
|
-
<key>metadata</key>
|
102
|
-
<dict>
|
103
|
-
<key>bundle-identifier</key>
|
104
|
-
<string>#{plist_data['CFBundleIdentifier']}</string>
|
105
|
-
<key>bundle-version</key>
|
106
|
-
<string>#{plist_data['CFBundleVersion']}</string>
|
107
|
-
<key>kind</key>
|
108
|
-
<string>software</string>
|
109
|
-
<key>title</key>
|
110
|
-
<string>#{plist_data['CFBundleDisplayName']}</string>
|
111
|
-
</dict>
|
112
|
-
</dict>
|
113
|
-
</array>
|
114
|
-
</dict>
|
115
|
-
</plist>
|
116
|
-
}
|
117
|
-
end
|
118
|
-
File.open("pkg/dist/index.html", "w") do |io|
|
119
|
-
io << %{
|
120
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
121
|
-
<html xmlns="http://www.w3.org/1999/xhtml">
|
122
|
-
<head>
|
123
|
-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
124
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
125
|
-
<title>Beta Download</title>
|
126
|
-
<style type="text/css">
|
127
|
-
body {background:#fff;margin:0;padding:0;font-family:arial,helvetica,sans-serif;text-align:center;padding:10px;color:#333;font-size:16px;}
|
128
|
-
#container {width:300px;margin:0 auto;}
|
129
|
-
h1 {margin:0;padding:0;font-size:14px;}
|
130
|
-
p {font-size:13px;}
|
131
|
-
.link {background:#ecf5ff;border-top:1px solid #fff;border:1px solid #dfebf8;margin-top:.5em;padding:.3em;}
|
132
|
-
.link a {text-decoration:none;font-size:15px;display:block;color:#069;}
|
133
|
-
</style>
|
134
|
-
</head>
|
135
|
-
<body>
|
136
|
-
<div id="container">
|
137
|
-
<div class="link"><a href="itms-services://?action=download-manifest&url=#{@configuration.manifest_url}">Tap Here to Install<br />#{@configuration.target}<br />On Your Device</a></div>
|
138
|
-
<p><strong>Link didn't work?</strong><br />
|
139
|
-
Make sure you're visiting this page on your device, not your computer.</p>
|
140
|
-
</body>
|
141
|
-
</html>
|
142
|
-
}
|
143
|
-
end
|
144
88
|
end
|
145
89
|
|
146
|
-
|
147
|
-
|
148
|
-
|
90
|
+
if @configuration.deployment_strategy
|
91
|
+
desc "Deploy the beta to your server"
|
92
|
+
task :deploy => :package do
|
93
|
+
@configuration.deployment_strategy.prepare
|
94
|
+
@configuration.deployment_strategy.deploy
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Deploy the last build"
|
98
|
+
task :redeploy do
|
99
|
+
@configuration.deployment_strategy.prepare
|
100
|
+
@configuration.deployment_strategy.deploy
|
101
|
+
end
|
149
102
|
end
|
150
103
|
|
151
104
|
desc "Build and archive the app"
|
@@ -0,0 +1,38 @@
|
|
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
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def self.strategies
|
31
|
+
{:web => Web, :testflight => TestFlight}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'beta_builder/deployment_strategies/web'
|
37
|
+
require 'beta_builder/deployment_strategies/testflight'
|
38
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module BetaBuilder
|
5
|
+
module DeploymentStrategies
|
6
|
+
class TestFlight < Strategy
|
7
|
+
ENDPOINT = "http://testflightapp.com/api/builds.json"
|
8
|
+
|
9
|
+
def extended_configuration_for_strategy
|
10
|
+
proc do
|
11
|
+
def generate_release_notes(&block)
|
12
|
+
self.release_notes = yield if block_given?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def deploy
|
18
|
+
payload = {
|
19
|
+
:api_token => @configuration.api_token,
|
20
|
+
:team_token => @configuration.team_token,
|
21
|
+
:file => File.new(@configuration.ipa_path, 'rb'),
|
22
|
+
:notes => get_notes,
|
23
|
+
:notify => false
|
24
|
+
}
|
25
|
+
puts "Uploading build to TestFlight..."
|
26
|
+
|
27
|
+
begin
|
28
|
+
response = RestClient.post(ENDPOINT, payload, :accept => :json)
|
29
|
+
rescue => e
|
30
|
+
response = e.response
|
31
|
+
end
|
32
|
+
|
33
|
+
if response.code == 200
|
34
|
+
puts "Upload complete."
|
35
|
+
else
|
36
|
+
puts "Upload failed. (#{response})"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def get_notes
|
43
|
+
@configuration.release_notes || get_notes_using_prompt
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_notes_using_prompt
|
47
|
+
puts "Enter the release notes for this build (hit enter twice when done):\n"
|
48
|
+
gets_until_match(/\n{2}$/).strip
|
49
|
+
end
|
50
|
+
|
51
|
+
def gets_until_match(pattern, string = "")
|
52
|
+
if (string += STDIN.gets) =~ pattern
|
53
|
+
string
|
54
|
+
else
|
55
|
+
gets_until_match(pattern, string)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,91 @@
|
|
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, target.downcase, ipa_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def manifest_url
|
11
|
+
File.join(deploy_to, target.downcase, "manifest.plist")
|
12
|
+
end
|
13
|
+
|
14
|
+
def remote_installation_path
|
15
|
+
File.join(remote_directory, target.downcase)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def prepare
|
21
|
+
plist = CFPropertyList::List.new(:file => "pkg/Payload/#{@configuration.app_name}/Info.plist")
|
22
|
+
plist_data = CFPropertyList.native_types(plist.value)
|
23
|
+
File.open("pkg/dist/manifest.plist", "w") do |io|
|
24
|
+
io << %{
|
25
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
26
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
27
|
+
<plist version="1.0">
|
28
|
+
<dict>
|
29
|
+
<key>items</key>
|
30
|
+
<array>
|
31
|
+
<dict>
|
32
|
+
<key>assets</key>
|
33
|
+
<array>
|
34
|
+
<dict>
|
35
|
+
<key>kind</key>
|
36
|
+
<string>software-package</string>
|
37
|
+
<key>url</key>
|
38
|
+
<string>#{@configuration.deployment_url}</string>
|
39
|
+
</dict>
|
40
|
+
</array>
|
41
|
+
<key>metadata</key>
|
42
|
+
<dict>
|
43
|
+
<key>bundle-identifier</key>
|
44
|
+
<string>#{plist_data['CFBundleIdentifier']}</string>
|
45
|
+
<key>bundle-version</key>
|
46
|
+
<string>#{plist_data['CFBundleVersion']}</string>
|
47
|
+
<key>kind</key>
|
48
|
+
<string>software</string>
|
49
|
+
<key>title</key>
|
50
|
+
<string>#{plist_data['CFBundleDisplayName']}</string>
|
51
|
+
</dict>
|
52
|
+
</dict>
|
53
|
+
</array>
|
54
|
+
</dict>
|
55
|
+
</plist>
|
56
|
+
}
|
57
|
+
end
|
58
|
+
File.open("pkg/dist/index.html", "w") do |io|
|
59
|
+
io << %{
|
60
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
61
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
62
|
+
<head>
|
63
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
64
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
65
|
+
<title>Beta Download</title>
|
66
|
+
<style type="text/css">
|
67
|
+
body {background:#fff;margin:0;padding:0;font-family:arial,helvetica,sans-serif;text-align:center;padding:10px;color:#333;font-size:16px;}
|
68
|
+
#container {width:300px;margin:0 auto;}
|
69
|
+
h1 {margin:0;padding:0;font-size:14px;}
|
70
|
+
p {font-size:13px;}
|
71
|
+
.link {background:#ecf5ff;border-top:1px solid #fff;border:1px solid #dfebf8;margin-top:.5em;padding:.3em;}
|
72
|
+
.link a {text-decoration:none;font-size:15px;display:block;color:#069;}
|
73
|
+
</style>
|
74
|
+
</head>
|
75
|
+
<body>
|
76
|
+
<div id="container">
|
77
|
+
<div class="link"><a href="itms-services://?action=download-manifest&url=#{@configuration.manifest_url}">Tap Here to Install<br />#{@configuration.target}<br />On Your Device</a></div>
|
78
|
+
<p><strong>Link didn't work?</strong><br />
|
79
|
+
Make sure you're visiting this page on your device, not your computer.</p>
|
80
|
+
</body>
|
81
|
+
</html>
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def deploy
|
87
|
+
system("scp pkg/dist/* #{@configuration.remote_host}:#{@configuration.remote_installation_path}")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: betabuilder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 21
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 1
|
9
8
|
- 2
|
10
|
-
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Luke Redpath
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-20 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -50,6 +50,38 @@ dependencies:
|
|
50
50
|
version: 2.3.1
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rest-client
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 13
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 6
|
65
|
+
- 1
|
66
|
+
version: 1.6.1
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: json
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 11
|
78
|
+
segments:
|
79
|
+
- 1
|
80
|
+
- 4
|
81
|
+
- 6
|
82
|
+
version: 1.4.6
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: *id004
|
53
85
|
description:
|
54
86
|
email: luke@lukeredpath.co.uk
|
55
87
|
executables: []
|
@@ -59,12 +91,16 @@ extensions: []
|
|
59
91
|
extra_rdoc_files:
|
60
92
|
- README.md
|
61
93
|
files:
|
94
|
+
- CHANGES.md
|
62
95
|
- LICENSE
|
63
96
|
- README.md
|
64
97
|
- lib/beta_builder/archived_build.rb
|
98
|
+
- lib/beta_builder/deployment_strategies/testflight.rb
|
99
|
+
- lib/beta_builder/deployment_strategies/web.rb
|
100
|
+
- lib/beta_builder/deployment_strategies.rb
|
65
101
|
- lib/beta_builder.rb
|
66
102
|
- lib/betabuilder.rb
|
67
|
-
has_rdoc:
|
103
|
+
has_rdoc: true
|
68
104
|
homepage: http://github.com/lukeredpath/betabuilder
|
69
105
|
licenses: []
|
70
106
|
|
@@ -95,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
131
|
requirements: []
|
96
132
|
|
97
133
|
rubyforge_project:
|
98
|
-
rubygems_version: 1.
|
134
|
+
rubygems_version: 1.4.1
|
99
135
|
signing_key:
|
100
136
|
specification_version: 3
|
101
137
|
summary: A set of Rake tasks and utilities for managing iOS ad-hoc builds
|