yolo 1.0.0 → 1.0.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/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
|
+

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