yolo 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -2
- data/Rakefile +1 -23
- data/lib/yolo/config/config.yml +2 -0
- data/lib/yolo/config/settings.rb +40 -2
- data/lib/yolo/deployment.rb +1 -0
- data/lib/yolo/deployment/base_deployer.rb +3 -2
- data/lib/yolo/deployment/ota.rb +3 -2
- data/lib/yolo/deployment/test_flight.rb +146 -0
- data/lib/yolo/formatters/error_formatter.rb +14 -0
- data/lib/yolo/formatters/progress_formatter.rb +13 -3
- data/lib/yolo/notify/ios/ota_email.rb +5 -1
- data/lib/yolo/tasks/ios/release.rb +13 -8
- data/lib/yolo/tools/ios/release_notes.rb +18 -0
- metadata +5 -3
data/README.md
CHANGED
@@ -24,7 +24,7 @@ It is recommended that you have [rvm](https://rvm.io/) installed and do not inst
|
|
24
24
|
## Getting Started
|
25
25
|
|
26
26
|
* [Quick Start](https://github.com/alexefish/yolo/wiki/Quick-Start)
|
27
|
-
* [Configuration](https://github.
|
27
|
+
* [Configuration](https://github.com/alexefish/yolo/wiki/Configuration)
|
28
28
|
|
29
29
|
## Release Builds
|
30
30
|
|
@@ -34,7 +34,19 @@ It is recommended that you have [rvm](https://rvm.io/) installed and do not inst
|
|
34
34
|
## Running Tests
|
35
35
|
|
36
36
|
* [OCUnit & Kiwi](https://github.com/alexefish/yolo/wiki/OCUnit-&-Kiwi)
|
37
|
-
* [Calabash](https://github.com/alexefish/yolo/wiki/
|
37
|
+
* [Calabash](https://github.com/alexefish/yolo/wiki/Calabashg)
|
38
|
+
|
39
|
+
## Jenkins
|
40
|
+
Running yolo from your Jenkins jobs is very simple, the following plugins are required:
|
41
|
+
|
42
|
+
* [Rake Plugin](http://wiki.jenkins-ci.org/display/JENKINS/Rake+Plugin)
|
43
|
+
* [ruby-runtime](http://jenkins-ci.org/plugin/ruby-runtime/)
|
44
|
+
* [rvm](https://wiki.jenkins-ci.org/display/JENKINS/RVM+Plugin)
|
45
|
+
* [Jenkins Git Plugin](http://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin)
|
46
|
+
|
47
|
+
You can then simply add a rake build step to execute yolo rake tasks, e.g:
|
48
|
+
|
49
|
+
![Jenkins Setup](http://i.imgur.com/7zm05pT.png)
|
38
50
|
|
39
51
|
## License
|
40
52
|
|
data/Rakefile
CHANGED
@@ -5,28 +5,6 @@ namespace :gem do
|
|
5
5
|
desc "Builds and then installs the gem"
|
6
6
|
task :buildinstall do
|
7
7
|
system 'gem build yolo.gemspec'
|
8
|
-
system 'gem install yolo-1.0.
|
8
|
+
system 'gem install yolo-1.0.1.pre.gem'
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
12
|
-
### Sample
|
13
|
-
|
14
|
-
#Yolo::Tasks::Ios::Build.new do |t|
|
15
|
-
# t.workspace = "Honk.xcworkspace"
|
16
|
-
# t.scheme = "Honk"
|
17
|
-
# t.formatter = XcodeBuild::Formatters::ProgressFormatter.new
|
18
|
-
#end
|
19
|
-
#
|
20
|
-
#Yolo::Tasks::Ios::OCUnit.new do |t|
|
21
|
-
# t.workspace = "Honk.xcworkspace"
|
22
|
-
# t.scheme = "HonkTests"
|
23
|
-
# t.test_output = :junit
|
24
|
-
# t.formatter = XcodeBuild::Formatters::ProgressFormatter.new
|
25
|
-
#end
|
26
|
-
#
|
27
|
-
#Yolo::Tasks::Ios::Calabash.new do |t|
|
28
|
-
# t.workspace = "Honk.xcworkspace"
|
29
|
-
# t.scheme = "Honk-cal"
|
30
|
-
# t.format = :junit
|
31
|
-
# t.formatter = XcodeBuild::Formatters::ProgressFormatter.new
|
32
|
-
#end
|
data/lib/yolo/config/config.yml
CHANGED
data/lib/yolo/config/settings.rb
CHANGED
@@ -20,6 +20,7 @@ module Yolo
|
|
20
20
|
@formatter = Yolo::Formatters::ProgressFormatter.new
|
21
21
|
@error = Yolo::Formatters::ErrorFormatter.new
|
22
22
|
check_config
|
23
|
+
update_config
|
23
24
|
@yaml = YAML::load_file yaml_path
|
24
25
|
end
|
25
26
|
|
@@ -50,6 +51,22 @@ module Yolo
|
|
50
51
|
@yaml["deployment"]["url"] if @yaml["deployment"]["url"] and @yaml["deployment"]["url"] != "http://example.com"
|
51
52
|
end
|
52
53
|
|
54
|
+
#
|
55
|
+
# The api token used for deployment
|
56
|
+
#
|
57
|
+
# @return [String] The api token defined in config.yml
|
58
|
+
def api_token
|
59
|
+
@yaml["deployment"]["api_token"] if @yaml["deployment"]["api_token"] and @yaml["deployment"]["api_token"] != "example"
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# The team token used for deployment
|
64
|
+
#
|
65
|
+
# @return [String] The team token defined in config.yml
|
66
|
+
def team_token
|
67
|
+
@yaml["deployment"]["team_token"] if @yaml["deployment"]["team_token"] and @yaml["deployment"]["teamt_oken"] != "example"
|
68
|
+
end
|
69
|
+
|
53
70
|
#
|
54
71
|
# The mail account is the account used when sending SMTP mail
|
55
72
|
#
|
@@ -90,8 +107,6 @@ module Yolo
|
|
90
107
|
@yaml["mail"]["from"] if @yaml["mail"]["from"] and @yaml["mail"]["from"] != "example@example.com"
|
91
108
|
end
|
92
109
|
|
93
|
-
private
|
94
|
-
|
95
110
|
#
|
96
111
|
# Checks for the existance of the config directory in the users home directory and creates it if not present
|
97
112
|
#
|
@@ -103,6 +118,29 @@ module Yolo
|
|
103
118
|
end
|
104
119
|
end
|
105
120
|
|
121
|
+
#
|
122
|
+
# Checks the config file is update to the latest and adds any options that are missing
|
123
|
+
#
|
124
|
+
def update_config
|
125
|
+
if File.directory?(yolo_dir) and File.exist?(yaml_path)
|
126
|
+
@yaml = YAML::load_file yaml_path
|
127
|
+
unless @yaml["deployment"]["api_token"]
|
128
|
+
@yaml["deployment"]["api_token"] = "example"
|
129
|
+
File.open(yaml_path, 'w') {|f|
|
130
|
+
f.write(@yaml.to_yaml)
|
131
|
+
}
|
132
|
+
@formatter.config_updated(yaml_path)
|
133
|
+
end
|
134
|
+
unless @yaml["deployment"]["team_token"]
|
135
|
+
@yaml["deployment"]["team_token"] = "example"
|
136
|
+
File.open(yaml_path, 'w') {|f|
|
137
|
+
f.write(@yaml.to_yaml)
|
138
|
+
}
|
139
|
+
@formatter.config_updated(yaml_path)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
106
144
|
#
|
107
145
|
# The path to the users home directory, same as ~
|
108
146
|
#
|
data/lib/yolo/deployment.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module Yolo
|
1
|
+
opts={}, module Yolo
|
2
2
|
module Deployment
|
3
3
|
|
4
4
|
#
|
@@ -23,9 +23,10 @@ module Yolo
|
|
23
23
|
#
|
24
24
|
# Deploys the package, all deployer subclasses must implement this method
|
25
25
|
# @param package_path [String] A full path to the package to deploy
|
26
|
+
# @param opts [Hash] A hash of deployment options
|
26
27
|
# @param block [Block] Block fired on completing
|
27
28
|
#
|
28
|
-
def deploy(package_path, &block)
|
29
|
+
def deploy(package_path, opts={}, &block)
|
29
30
|
end
|
30
31
|
|
31
32
|
end
|
data/lib/yolo/deployment/ota.rb
CHANGED
@@ -24,9 +24,10 @@ module Yolo
|
|
24
24
|
#
|
25
25
|
# Overides the super deploy method
|
26
26
|
# @param package_path [String] A full path to the package to deploy
|
27
|
+
# @param opts [Hash] A hash of deployment options
|
27
28
|
# @param block [Block] Block fired on completing
|
28
29
|
#
|
29
|
-
def deploy(package_path, &block)
|
30
|
+
def deploy(package_path, opts={}, &block)
|
30
31
|
self.package_path = package_path
|
31
32
|
@complete_block = block
|
32
33
|
|
@@ -54,7 +55,7 @@ module Yolo
|
|
54
55
|
#
|
55
56
|
def upload
|
56
57
|
response = ""
|
57
|
-
IO.popen("curl
|
58
|
+
IO.popen("curl #{self.url} -X POST -# g-F fileContent=@\"#{self.package_path}\" -F params='#{package}'") do |io|
|
58
59
|
begin
|
59
60
|
while line = io.readline
|
60
61
|
begin
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Yolo
|
2
|
+
module Deployment
|
3
|
+
|
4
|
+
#
|
5
|
+
# Deploys IPA's using testflight
|
6
|
+
#
|
7
|
+
# @author [Alex Fish]
|
8
|
+
#
|
9
|
+
class TestFlight < Yolo::Deployment::BaseDeployer
|
10
|
+
|
11
|
+
#
|
12
|
+
# Overides the super deploy method
|
13
|
+
# @param package_path [String] A full path to the package to deploy
|
14
|
+
# @param opts [Hash] A hash of deployment options
|
15
|
+
# @param block [Block] Block fired on completing
|
16
|
+
#
|
17
|
+
def deploy(package_path, opts={}, &block)
|
18
|
+
response = ""
|
19
|
+
@completion_block = block
|
20
|
+
@progress_formatter = Yolo::Formatters::ProgressFormatter.new
|
21
|
+
@progress_formatter.deploying_ipa(package_path)
|
22
|
+
|
23
|
+
IO.popen(curl_string(package_path, opts)) do |io|
|
24
|
+
begin
|
25
|
+
while line = io.readline
|
26
|
+
begin
|
27
|
+
response << line
|
28
|
+
rescue StandardError => e
|
29
|
+
@error_formatter.deploy_failed("ParserError: #{e}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue EOFError
|
33
|
+
#@error_formatter.deploy_failed("ParserError")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
upload_complete(response)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
#
|
42
|
+
# Parses the response json and calls the completion block
|
43
|
+
# @param response [String] The request response
|
44
|
+
#
|
45
|
+
def upload_complete(response)
|
46
|
+
json = nil
|
47
|
+
begin
|
48
|
+
json = JSON.parse(response)
|
49
|
+
rescue JSON::ParserError
|
50
|
+
@error_formatter.deploy_failed("\n ParserError: Deployment server response is not JSON")
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
unless json
|
55
|
+
@error_formatter.deploy_failed("\n ParserError: Deployment server response is not JSON")
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
url = json["install_url"]
|
60
|
+
|
61
|
+
@completion_block.call(url,nil)
|
62
|
+
@progress_formatter.deploy_complete(url,nil)
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Parses the deploy options and returns a string for use in curl
|
67
|
+
# @param opts [Hash] The options hash
|
68
|
+
#
|
69
|
+
# @return [String] A comma seperated string of distribution lists
|
70
|
+
def distribution_lists(opts)
|
71
|
+
@lists = ""
|
72
|
+
if opts[:distribution_lists]
|
73
|
+
@lists = opts[:distribution_lists].join(",")
|
74
|
+
end
|
75
|
+
@lists
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Parses the options and return a notify string for use in curl
|
80
|
+
# @param opts [Hash] The deployment options hash
|
81
|
+
#
|
82
|
+
# @return [String] True or False depending on the options
|
83
|
+
def notify(opts)
|
84
|
+
@notify = false
|
85
|
+
if opts[:notify]
|
86
|
+
@notify = opts[:notify].to_s.capitalize
|
87
|
+
end
|
88
|
+
@notify
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Gets the api token defined in the users config.yml
|
93
|
+
#
|
94
|
+
# @return [String] The deployment API token defined in config.yml
|
95
|
+
def api_token
|
96
|
+
token = Yolo::Config::Settings.instance.api_token
|
97
|
+
unless token
|
98
|
+
@error_formatter.no_api_token
|
99
|
+
token = ""
|
100
|
+
end
|
101
|
+
token
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Gets the team token defined in the users config.yml
|
106
|
+
#
|
107
|
+
# @return [String] The deployment team token defined in config.yml
|
108
|
+
def team_token
|
109
|
+
token = Yolo::Config::Settings.instance.team_token
|
110
|
+
unless token
|
111
|
+
@error_formatter.no_team_token
|
112
|
+
token = ""
|
113
|
+
end
|
114
|
+
token
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Returns a notes string from the Release Notes module, empty if none are set
|
119
|
+
#
|
120
|
+
# @return [String] The release notes
|
121
|
+
def notes
|
122
|
+
notes = Yolo::Tools::Ios::ReleaseNotes.plaintext
|
123
|
+
notes = "No notes provided" unless notes
|
124
|
+
notes
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# Generates the CURL command string for test flight distribution
|
129
|
+
# @param package_path The path to the package
|
130
|
+
# @param opts [Hash] The options array
|
131
|
+
#
|
132
|
+
# @return [String] The CURL command
|
133
|
+
def curl_string(package_path, opts)
|
134
|
+
string = "curl http://testflightapp.com/api/builds.json -X POST -# "
|
135
|
+
string = string + "-F file=@#{package_path} "
|
136
|
+
string = string + "-F api_token='#{api_token}' " if api_token.length > 0
|
137
|
+
string = string + "-F team_token='#{team_token}' " if team_token.length > 0
|
138
|
+
string = string + "-F notes='#{notes}' " if notes.length > 0
|
139
|
+
string = string + "-F notify=#{notify(opts)}" if opts
|
140
|
+
string = string + "-F distribution_lists=#{distribution_lists(opts)}" if opts and distribution_lists(opts).length > 0
|
141
|
+
string
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -46,6 +46,20 @@ module Yolo
|
|
46
46
|
puts red("No deploy url found, please specify one in ~/.yolo/config.yml")
|
47
47
|
end
|
48
48
|
|
49
|
+
#
|
50
|
+
# Outputs a red string stating that no API token is defined
|
51
|
+
#
|
52
|
+
def no_api_token
|
53
|
+
puts red("No API token is defined in config.yml")
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Outputs a red string stating that no team token is defined
|
58
|
+
#
|
59
|
+
def no_team_token
|
60
|
+
puts red("No team token is defined in config.yml")
|
61
|
+
end
|
62
|
+
|
49
63
|
#
|
50
64
|
# Outputs a red string stating that email notification failed because of missing details
|
51
65
|
#
|
@@ -24,6 +24,14 @@ module Yolo
|
|
24
24
|
puts green("Setup complete")
|
25
25
|
end
|
26
26
|
|
27
|
+
#
|
28
|
+
# Outputs a green string stating that the config file was updated
|
29
|
+
# @param config [String] The path to the config file
|
30
|
+
#
|
31
|
+
def config_updated(config)
|
32
|
+
puts green("Config updated at: #{config}")
|
33
|
+
end
|
34
|
+
|
27
35
|
#
|
28
36
|
# Outputs an underlined bold string stating that the ipa is being generated
|
29
37
|
#
|
@@ -139,9 +147,11 @@ module Yolo
|
|
139
147
|
puts green("URL")
|
140
148
|
puts green(url)
|
141
149
|
puts
|
142
|
-
|
143
|
-
|
144
|
-
|
150
|
+
if password
|
151
|
+
puts green("Password")
|
152
|
+
puts green(password)
|
153
|
+
puts
|
154
|
+
end
|
145
155
|
end
|
146
156
|
|
147
157
|
#
|
@@ -39,7 +39,11 @@ MESSAGE_END
|
|
39
39
|
|
40
40
|
content = content.gsub("YOLO.TITLE",opts[:title])
|
41
41
|
content = content.gsub("YOLO.CONTENT",markdown)
|
42
|
-
|
42
|
+
if opts[:ota_password] and opts[:ota_password].length > 0
|
43
|
+
content = content.gsub("YOLO.PASSWORD","<h3>Password</h3><hr><p>#{opts[:ota_password]}</p>")
|
44
|
+
else
|
45
|
+
content = content.gsub("YOLO.PASSWORD","")
|
46
|
+
end
|
43
47
|
content = content.gsub("YOLO.LINK",opts[:ota_url])
|
44
48
|
content
|
45
49
|
end
|
@@ -14,6 +14,8 @@ module Yolo
|
|
14
14
|
attr_accessor :mail_to
|
15
15
|
# The deployment class to use when deploying
|
16
16
|
attr_accessor :deployment
|
17
|
+
# A Hash of additional options
|
18
|
+
attr_accessor :options
|
17
19
|
|
18
20
|
#
|
19
21
|
# Initializes the class with default settings
|
@@ -129,14 +131,17 @@ module Yolo
|
|
129
131
|
return
|
130
132
|
end
|
131
133
|
|
132
|
-
klass.deploy(ipa_path) do |url, password|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
134
|
+
klass.deploy(ipa_path, options) do |url, password|
|
135
|
+
if url
|
136
|
+
mail_options = {
|
137
|
+
:to => self.mail_to,
|
138
|
+
:ota_url => url,
|
139
|
+
:subject => "New #{name} build: #{version}",
|
140
|
+
:title => name
|
141
|
+
}
|
142
|
+
mail_options[:ota_password] = password if password
|
143
|
+
@emailer.send(mail_options)
|
144
|
+
end
|
140
145
|
end
|
141
146
|
end
|
142
147
|
|
@@ -40,6 +40,24 @@ module Yolo
|
|
40
40
|
`open #{directory}/release_notes.md`
|
41
41
|
end
|
42
42
|
|
43
|
+
#
|
44
|
+
# Returns a plaintext string of the release notes file
|
45
|
+
#
|
46
|
+
# @return [String] The release notes as plain text
|
47
|
+
def self.plaintext
|
48
|
+
notes = "#{Dir.pwd}/release_notes.md"
|
49
|
+
unless File.exist?(notes)
|
50
|
+
error_formatter = Yolo::Formatters::ErrorFormatter.new
|
51
|
+
error_formatter.no_notes(notes)
|
52
|
+
return ""
|
53
|
+
end
|
54
|
+
|
55
|
+
file = File.open(notes, "r")
|
56
|
+
file_content = file.read
|
57
|
+
|
58
|
+
file_content
|
59
|
+
end
|
60
|
+
|
43
61
|
#
|
44
62
|
# Uses Redcarpet to parse the release notes markdown file into html.
|
45
63
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yolo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: xcodebuild-rb
|
@@ -75,7 +75,8 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
-
description:
|
78
|
+
description: yolo is a RubyGem which provides a Ruby interface to Continuous Integration
|
79
|
+
build tools. yolo is currently geared towards the Xcode toolchain and iOS development.
|
79
80
|
email: alex@alexefish.com
|
80
81
|
executables: []
|
81
82
|
extensions: []
|
@@ -87,6 +88,7 @@ files:
|
|
87
88
|
- lib/yolo/config.rb
|
88
89
|
- lib/yolo/deployment/base_deployer.rb
|
89
90
|
- lib/yolo/deployment/ota.rb
|
91
|
+
- lib/yolo/deployment/test_flight.rb
|
90
92
|
- lib/yolo/deployment.rb
|
91
93
|
- lib/yolo/formatters/error_formatter.rb
|
92
94
|
- lib/yolo/formatters/progress_formatter.rb
|