yolo 1.2.8 → 1.3.0

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.
@@ -16,3 +16,7 @@ deployment:
16
16
  url: http://example.com
17
17
  api_token: example
18
18
  team_token: example
19
+
20
+ # Github
21
+ github:
22
+ token: token
@@ -168,6 +168,16 @@ module Yolo
168
168
  end
169
169
  end
170
170
 
171
+ #
172
+ # The github token used to connect to the github api
173
+ #
174
+ # @return [String] The token defined in config.yml
175
+ def github_token
176
+ if @yaml["github"]["token"] != "token"
177
+ return @yaml["github"]["token"]
178
+ end
179
+ end
180
+
171
181
  #
172
182
  # The path to the users home directory, same as ~
173
183
  #
@@ -46,6 +46,14 @@ module Yolo
46
46
  puts red("There was a problem deploying the ipa: #{error}")
47
47
  end
48
48
 
49
+ #
50
+ # Outputs a red string stating that there was an issue deploying the bundle to github
51
+ # @param error [String] The error string
52
+ #
53
+ def github_upload_failed(error)
54
+ puts red("There was a problem deploying the bundle to github: #{error}")
55
+ end
56
+
49
57
  #
50
58
  # Outputs a red string stating that no deploy URL was found in the config file
51
59
  #
@@ -74,6 +82,10 @@ module Yolo
74
82
  puts red("Can't send mail notification, missing details")
75
83
  end
76
84
 
85
+ def no_github_token
86
+ puts red("No Github token found, please specify one in ~/.yolo/config.yml ")
87
+ end
88
+
77
89
  #
78
90
  # Outputs a red string stating that a release notes file could not be found
79
91
  # @param notes [String] The path which should contain a notes file
@@ -93,6 +93,41 @@ module Yolo
93
93
  puts
94
94
  end
95
95
 
96
+ #
97
+ # Outputs a string stating that the github release is being generated
98
+ #
99
+ def creating_github_release
100
+ github = "Generating Github release"
101
+ puts bold(github)
102
+ puts github.length.times.map {"="}.join
103
+ puts
104
+ end
105
+
106
+ #
107
+ # Outputs a green string stating that the github release was created
108
+ #
109
+ def created_release(version)
110
+ puts green("Release #{version} created")
111
+ end
112
+
113
+ #
114
+ # Outputs a green string stating that the github release finished
115
+ #
116
+ def github_released
117
+ puts green("Release completed")
118
+ end
119
+
120
+ #
121
+ # Outputs an underlined bold string stating that the is uploading
122
+ #
123
+ def github_uploading
124
+ puts
125
+ github = "Uploading package"
126
+ puts bold(github)
127
+ puts github.length.times.map {"="}.join
128
+ puts
129
+ end
130
+
96
131
  #
97
132
  # Outputs a green string stating that the release notes have been generated
98
133
  # @param notes [String] The path to the release notes
@@ -23,7 +23,6 @@ module Yolo
23
23
  self.format = :junit
24
24
  self.device = "iphone"
25
25
  self.output_dir = "test-reports/calabash"
26
- super
27
26
  end
28
27
 
29
28
  #
@@ -16,6 +16,8 @@ module Yolo
16
16
  attr_accessor :deployment
17
17
  # A Hash of additional options
18
18
  attr_accessor :options
19
+ # A Github repo to release to
20
+ attr_accessor :github_repo
19
21
 
20
22
  #
21
23
  # Initializes the class with default settings
@@ -127,6 +129,22 @@ module Yolo
127
129
  end
128
130
  end
129
131
 
132
+ #
133
+ # Release the ipa using the github releases API, the ipa will be zipped and
134
+ # uploaded as well as the release notes used as the release body and
135
+ # version for the release title
136
+ #
137
+ # @param ipa_path [String] The full path to the IPA file to deploy
138
+ #
139
+ def release_to_github(bundle_path)
140
+ if self.github_repo
141
+ github = Yolo::Tools::Github.new
142
+ notes = Yolo::Tools::Ios::ReleaseNotes.html
143
+ github.repo = self.github_repo
144
+ github.release(bundle_path, version, notes)
145
+ end
146
+ end
147
+
130
148
  #
131
149
  # Sends a notificaiton email from a deployment
132
150
  # @param url [String] The URL which the build has been deplyed too
@@ -172,6 +190,7 @@ module Yolo
172
190
  xcodebuild :build
173
191
  Yolo::Tools::Ios::IPA.generate(app_path,dsym_path,bundle_path) do |ipa|
174
192
  deploy(ipa) if ipa and self.deployment
193
+ release_to_github(bundle_path) if ipa and self.github_repo
175
194
  end
176
195
  end
177
196
 
@@ -9,4 +9,5 @@ module Yolo
9
9
  end
10
10
 
11
11
  require 'yolo/tools/git'
12
+ require 'yolo/tools/github'
12
13
  require 'yolo/tools/ios'
@@ -79,6 +79,20 @@ module Yolo
79
79
  @commit
80
80
  end
81
81
 
82
+ #
83
+ # Finds the current branch using some regex and git branch
84
+ #
85
+ # @return [String] The current branch name
86
+ def current_branch
87
+ branch = `git branch`
88
+ branchs = branch.split("\n")
89
+ current_branch = ""
90
+ branchs.each do |b|
91
+ current_branch = b if b.count("*") == 1
92
+ end
93
+ current_branch.gsub("* ", "")
94
+ end
95
+
82
96
  private
83
97
 
84
98
  #
@@ -198,19 +212,6 @@ module Yolo
198
212
  `git log --decorate=short -n 1 --pretty=oneline`
199
213
  end
200
214
 
201
- #
202
- # Finds the current branch using some regex and git branch
203
- #
204
- # @return [String] The current branch name
205
- def current_branch
206
- branch = `git branch`
207
- branchs = branch.split("\n")
208
- current_branch = ""
209
- branchs.each do |b|
210
- current_branch = b if b.count("*") == 1
211
- end
212
- current_branch.gsub("* ", "")
213
- end
214
215
  end
215
216
  end
216
217
  end
@@ -0,0 +1,145 @@
1
+ require "zip"
2
+ require "net/http"
3
+ require "uri"
4
+ require 'json'
5
+
6
+ module Yolo
7
+ module Tools
8
+ #
9
+ # Communicates with Github
10
+ #
11
+ # @author [Alex Fish]
12
+ #
13
+ class Github
14
+
15
+ # The github repo that all actions will target
16
+ attr_accessor :repo
17
+
18
+ #
19
+ # Creates the class with default variables
20
+ #
21
+ def initialize
22
+ @token = Yolo::Config::Settings.instance.github_token
23
+ if !@token
24
+ error = Yolo::Formatters::ErrorFormatter.new
25
+ error.no_github_token
26
+ end
27
+ end
28
+
29
+ # Release the bundle using the github releases API, the bundle will be zipped and
30
+ # uploaded as well as the release notes used as the release body and
31
+ # version for the release title
32
+ #
33
+ # @param bundle [String] The full path to the bundle folder to release
34
+ # @param version [String] The version of the release
35
+ # @param body [String] The body of the release
36
+ #
37
+ def release(bundle, version, body)
38
+ @progress = Yolo::Formatters::ProgressFormatter.new
39
+ @progress.creating_github_release
40
+
41
+ uri = URI.parse("https://api.github.com/repos/#{self.repo}/releases?access_token=#{@token}")
42
+
43
+ http = Net::HTTP.new(uri.host, uri.port)
44
+ http.use_ssl = true
45
+
46
+ request = Net::HTTP::Post.new(uri.request_uri)
47
+ request.body = options(body, version)
48
+
49
+ # Tweak headers, removing this will default to application/x-www-form-urlencoded
50
+ request["Content-Type"] = "application/json"
51
+
52
+ response = http.request(request)
53
+ response = JSON.parse(response.body)
54
+
55
+ @progress.created_release(version)
56
+
57
+ url = response["upload_url"].gsub("{?name}","")
58
+ upload_bundle(bundle, url, "#{version}.zip")
59
+ end
60
+
61
+ # Upload the bundle to the github release url
62
+ #
63
+ # @param bundle [String] The full path to the bundle folder to release
64
+ # @param url [String] The github asset url returned from create_release
65
+ #
66
+ def upload_bundle(bundle, url, name)
67
+ @progress = Yolo::Formatters::ProgressFormatter.new
68
+ @progress.github_uploading
69
+ zipped_bundle = zip_bundle(bundle)
70
+
71
+ response = ""
72
+ curl = curl_string(name, zipped_bundle, url)
73
+ puts curl
74
+ IO.popen(curl) do |io|
75
+ begin
76
+ while line = io.readline
77
+ response << line
78
+ end
79
+ if response.length == 0
80
+ @error_formatter.github_upload_failed("Upload error")
81
+ end
82
+ rescue EOFError
83
+ end
84
+ end
85
+
86
+ @progress.github_released
87
+ end
88
+
89
+ private
90
+
91
+ # Generate a curl command string to upload the release to github with
92
+ #
93
+ # @param name [String] The name of the file
94
+ # @param zipped_bundle [String] The full path to the zipped bundle folder
95
+ # @param url [String] The URL for the request
96
+ #
97
+ # @return [String] The curl command string
98
+ def curl_string(name, zipped_bundle, url)
99
+ "curl -# -H \"Accept: application/vnd.github.manifold-preview\" \
100
+ -H \"Content-Type: application/zip\" \
101
+ --data-binary @#{zipped_bundle} \
102
+ \"#{url}?name=#{name}&access_token=#{@token}\"
103
+ "
104
+ end
105
+
106
+ # Zip the bundle ready for upload to github, the zip will have the same
107
+ # name as the bundle folder with .zip appended
108
+ #
109
+ # @param bundle [String] The full path to the bundle folder to zip
110
+ #
111
+ # @return [String] The zipped bundle path
112
+ def zip_bundle(bundle)
113
+ bundle.sub!(%r[/$],'')
114
+ archive = File.join(bundle,File.basename(bundle))+'.zip'
115
+ FileUtils.rm archive, :force=>true
116
+
117
+ Zip::File.open(archive, 'w') do |zipfile|
118
+ Dir["#{bundle}/**/**"].reject{|f|f==archive}.each do |file|
119
+ zipfile.add(file.sub(bundle+'/',''),file)
120
+ end
121
+ return archive
122
+ end
123
+ end
124
+
125
+ #
126
+ # Generates an options hash for a github release
127
+ #
128
+ # @return [String] The current branch name
129
+ def options(body, version)
130
+ options = {"body" => body, "tag_name" => version, "name" => version, "target_commitish" => current_branch}
131
+ options.to_json
132
+ end
133
+
134
+ #
135
+ # Finds the current branch using the git tool
136
+ #
137
+ # @return [String] The current branch name
138
+ def current_branch
139
+ git = Yolo::Tools::Git.new
140
+ git.current_branch
141
+ end
142
+
143
+ end
144
+ end
145
+ end
@@ -22,14 +22,6 @@ module Yolo
22
22
  File.open("#{directory}/release_notes.md", 'w') {|f|
23
23
  f.write("### Version\n- - -\n")
24
24
  f.write("#{xcode.version_number} (#{xcode.build_number})\n\n")
25
- f.write("### Change log\n- - -\n")
26
- f.write("* No Changes\n\n")
27
- f.write("### Fixes\n- - -\n")
28
- f.write("* No Fixes\n\n")
29
- f.write("### Notes\n- - -\n")
30
- f.write("No Notes\n\n")
31
- f.write("### Known issues\n- - -\n")
32
- f.write("No Known issues\n\n")
33
25
  f.write("### Date\n- - -\n")
34
26
  f.write("#{time.day}/#{time.month}/#{time.year} - #{time.hour}:#{time.min}")
35
27
  }
@@ -37,7 +29,7 @@ module Yolo
37
29
  formatter = Yolo::Formatters::ProgressFormatter.new
38
30
  formatter.notes_generated("#{directory}/release_notes.md")
39
31
 
40
- `open #{directory}/release_notes.md`
32
+ #`open #{directory}/release_notes.md`
41
33
  end
42
34
 
43
35
  #
@@ -98,6 +98,9 @@ describe Yolo::Config::Settings do
98
98
  "port" => "test_port",
99
99
  "host" => "test_host",
100
100
  "from" => "test_from"
101
+ },
102
+ "github" => {
103
+ "token" => "test_token"
101
104
  }
102
105
  }
103
106
  YAML.stub(:load_file){@yaml}
@@ -139,5 +142,9 @@ describe Yolo::Config::Settings do
139
142
  it "should hold a mail from" do
140
143
  Yolo::Config::Settings.instance.mail_from.should eq("test_from")
141
144
  end
145
+
146
+ it "should hold a github token" do
147
+ Yolo::Config::Settings.instance.github_token.should eq("test_token")
148
+ end
142
149
  end
143
150
  end
@@ -11,6 +11,10 @@ describe Yolo::Tasks::Ios::Release do
11
11
  @email.stub(:send)
12
12
  Yolo::Notify::Ios::OTAEmail.stub(:new){@email}
13
13
 
14
+ @github = mock(Yolo::Tools::Github)
15
+ @github.stub(:repo=)
16
+ Yolo::Tools::Github.stub(:new){@github}
17
+
14
18
  @ota = mock(Yolo::Deployment::OTA)
15
19
  Yolo::Deployment::OTA.stub(:new){@ota}
16
20
 
@@ -149,6 +153,18 @@ describe Yolo::Tasks::Ios::Release do
149
153
  @release.deploy("")
150
154
  end
151
155
 
156
+ it "should release to github if a repo is set" do
157
+ @github.should_receive(:release)
158
+ @release.stub(:github_repo){"test_repo"}
159
+ @release.release_to_github("")
160
+ end
161
+
162
+ it "should not release to github if no repo is set" do
163
+ @github.should_not_receive(:release)
164
+ @release.stub(:github_repo){nil}
165
+ @release.release_to_github("")
166
+ end
167
+
152
168
  it "shouldnt build mail options without a url" do
153
169
  @ota.stub(:deploy).and_yield(nil, nil)
154
170
  @email.should_not_receive(:send)
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'yolo'
3
+
4
+ describe Yolo::Tools::Github do
5
+
6
+ before do
7
+ Yolo::Formatters::ProgressFormatter.any_instance.stub(:puts)
8
+ Yolo::Formatters::ErrorFormatter.any_instance.stub(:puts)
9
+ end
10
+
11
+ describe "when initlized" do
12
+ it "should load the token from settings" do
13
+ Yolo::Config::Settings.instance.stub(:github_token){"token"}
14
+ github = Yolo::Tools::Github.new
15
+ github.instance_variable_get(:@token).should_not eq(nil)
16
+ end
17
+
18
+ it "should thrown an error if there is no token" do
19
+ Yolo::Config::Settings.instance.stub(:github_token){nil}
20
+ Yolo::Formatters::ErrorFormatter.any_instance.should_receive(:no_github_token)
21
+
22
+ github = Yolo::Tools::Github.new
23
+ end
24
+ end
25
+
26
+ describe "when releasing" do
27
+ before do
28
+ @git = mock(Yolo::Tools::Git)
29
+ Yolo::Tools::Git.stub(:new){@git}
30
+ @git.stub(:current_branch){"branch"}
31
+
32
+ @github = Yolo::Tools::Github.new
33
+ @github.instance_variable_get(:@octokit).stub(:create_release)
34
+ end
35
+
36
+ it "should get the current git branch" do
37
+ @github.instance_eval{current_branch}.should eq("branch")
38
+ end
39
+
40
+ it "should zip the bundle" do
41
+ @github.instance_variable_get(:@octokit).stub(:upload_asset)
42
+ @github.should_receive(:zip_bundle).with("path")
43
+ @github.upload_bundle("path", "version", "name")
44
+ end
45
+ end
46
+
47
+ describe "when generating options" do
48
+
49
+ before do
50
+ github = Yolo::Tools::Github.new
51
+ github.stub(:current_branch){"target_commitish"}
52
+ @options = github.instance_eval{options("body", "version")}
53
+ end
54
+
55
+ it "should hold a version" do
56
+ @options["name"].should eq("name")
57
+ end
58
+
59
+ it "should hold a body" do
60
+ @options["body"].should eq("body")
61
+ end
62
+
63
+ it "should hold the target_commitish" do
64
+ @options["target_commitish"].should eq("target_commitish")
65
+ end
66
+ end
67
+ end
@@ -54,11 +54,6 @@ describe Yolo::Tools::Ios::ReleaseNotes do
54
54
  @time.should_receive(:min)
55
55
  @release_notes.generate("path")
56
56
  end
57
-
58
- it "should open the release notes after writting" do
59
- @release_notes.should_receive(:`).with(/open current_path\/release_notes.md/)
60
- @release_notes.generate("path")
61
- end
62
57
  end
63
58
 
64
59
  describe "when parsing release notes to plain text" do
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.2.8
4
+ version: 1.3.0
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-08-13 00:00:00.000000000 Z
12
+ date: 2013-11-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: xcodebuild-rb
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rubyzip
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.1.0
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.1.0
78
94
  description: yolo is a RubyGem which provides a Ruby interface to Continuous Integration
79
95
  build tools. yolo is currently geared towards the Xcode toolchain and iOS development.
80
96
  email: alex@alexefish.com
@@ -111,6 +127,7 @@ files:
111
127
  - lib/yolo/tasks/ios.rb
112
128
  - lib/yolo/tasks.rb
113
129
  - lib/yolo/tools/git.rb
130
+ - lib/yolo/tools/github.rb
114
131
  - lib/yolo/tools/ios/calabash.rb
115
132
  - lib/yolo/tools/ios/coverage.rb
116
133
  - lib/yolo/tools/ios/ipa.rb
@@ -134,6 +151,7 @@ files:
134
151
  - spec/tasks/ios/ocunit_spec.rb
135
152
  - spec/tasks/ios/release_spec.rb
136
153
  - spec/tools/git_spec.rb
154
+ - spec/tools/github_spec.rb
137
155
  - spec/tools/ios/calabash_spec.rb
138
156
  - spec/tools/ios/coverage_spec.rb
139
157
  - spec/tools/ios/ipa_spec.rb
@@ -160,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
178
  version: '0'
161
179
  requirements: []
162
180
  rubyforge_project:
163
- rubygems_version: 1.8.23
181
+ rubygems_version: 1.8.24
164
182
  signing_key:
165
183
  specification_version: 3
166
184
  summary: YOLO!