stove 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d59cbc25446b69f0c4ce823c8cd5cef164b7e7e
4
- data.tar.gz: 66bb4d771096a47fd6417299b703c99a3d4bca15
3
+ metadata.gz: e6543792d8f0805391fd56ad612836f4413ebdd0
4
+ data.tar.gz: b67ea0a0cd771ef510e11bc2cbe2ea46e6caacdb
5
5
  SHA512:
6
- metadata.gz: 0fa2c9ea6c1790ea7c70c7579c4e6070340b7034e06e6c19675d815b8cc511b9165137dfcdfa3fdfcd37d67444672b68c25c4d8dec3874b8b96e953a8a94193d
7
- data.tar.gz: af61a2bb1256eee70c27602868615d1687359294c3780aa7550639602e0cdb3622274dda5f14fd6a87150467e869285891724e264e96c9b94ec9cfe79d61b776
6
+ metadata.gz: abfe99a45ed6757bff3e795689ab838cb1672d8c55013219d78ba890804e6aae0456d1c79891d41430dbc60d95614e235431b23e7872761d4bc4e8c42149852b
7
+ data.tar.gz: 789afa789f2f99fd3573b6206374df791347223c556301e6fba5f60157724ea13612b09faea91ac4674cdb58f803335434d082cd761a7e98af88299bd71e5dca
data/README.md CHANGED
@@ -11,7 +11,8 @@ A utility for releasing and managing Chef Cookbooks. It will:
11
11
  - Create a CHANGELOG from JIRA tickets
12
12
  - Commit and push these changes to git
13
13
  - Create a git tag and push those changes to git
14
- - Upload the cookbook to the Opscode community site
14
+ - Publish a release to GitHub releases
15
+ - Upload the cookbook to the Opscode Community Site
15
16
  - Resolve (close) the JIRA tickets
16
17
 
17
18
 
@@ -39,10 +40,17 @@ Create a special JIRA credentials file at '~/.stove' that has the following JSON
39
40
  "jira_username": "JIRA_USERNAME",
40
41
  "jira_password": "JIRA_PASSWORD",
41
42
  "opscode_username": "OPSCODE_USERNAME",
42
- "opscode_pem_file": "OPSCODE_PEM_FILE"
43
+ "opscode_pem_file": "OPSCODE_PEM_FILE",
44
+ "github_access_token": "PERSONAL_API_TOKEN"
43
45
  }
44
46
  ```
45
47
 
48
+ - `jira_username` - The username used to login to Opscode's JIRA
49
+ - `jira_password` - The password used to login to Opscode's JIRA
50
+ - `opscode_username` - The username used to login to Opscode's Community Site
51
+ - `opscode_password` - The password used to login to Opscode's Community Site
52
+ - `github_access_token` - Your personal access token for the GitHub API
53
+
46
54
  For example:
47
55
 
48
56
  ```javascript
@@ -50,7 +58,8 @@ For example:
50
58
  "jira_username": "sethvargo",
51
59
  "jira_password": "bAc0ñ",
52
60
  "opscode_username": "sethvargo",
53
- "opscode_pem_file": "~/.chef/sethvargo.pem"
61
+ "opscode_pem_file": "~/.chef/sethvargo.pem",
62
+ "github_access_token": "abcdefg1234567"
54
63
  }
55
64
  ```
56
65
 
@@ -67,8 +76,10 @@ Usage: bake x.y.z
67
76
  -c, --category [CATEGORY] The category for the cookbook (optional for existing cookbooks)
68
77
  -p, --path [PATH] The path to the cookbook to release (default: PWD)
69
78
  --[no-]git Automatically tag and push to git (default: true)
79
+ --[no-]github Automatically release to GitHub (default: true)
70
80
  -r, --remote The name of the git remote to push to
71
81
  -b, --branch The name of the git branch to push to
82
+ --[no-]devodd Automatically bump the metadata for devodd releases
72
83
  --[no-]jira Automatically populate the CHANGELOG from JIRA tickets and close them (default: false)
73
84
  --[no-]upload Upload the cookbook to the Opscode Community Site (default: true)
74
85
  --[no-]changelog Automatically generate a CHANGELOG (default: true)
@@ -77,6 +88,20 @@ Usage: bake x.y.z
77
88
  ```
78
89
 
79
90
 
91
+ Rake Task
92
+ ---------
93
+ Stove also includes a Rake task you can include in your Rakefile:
94
+
95
+ ```ruby
96
+ require 'stove/rake_task'
97
+
98
+ Stove::RakeTask.new do |stove|
99
+ stove.git = true
100
+ stove.devodd = true
101
+ end
102
+ ```
103
+
104
+
80
105
  Contributing
81
106
  ------------
82
107
  1. Fork it
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
@@ -1,8 +1,4 @@
1
1
  Feature: Changelog
2
- As a stove user
3
- In order to have a human-readable changeset
4
- I want to automatically generate a Changelog
5
-
6
2
  Background:
7
3
  * the CLI options are all off
8
4
  * I have a cookbook named "bacon"
@@ -1,8 +1,4 @@
1
1
  Feature: Cli
2
- As a stove user
3
- In order to use Stove
4
- I want to have a Cli that is useful
5
-
6
2
  Background:
7
3
  * I have a cookbook named "bacon"
8
4
 
@@ -0,0 +1,19 @@
1
+ Feature: Devodd
2
+ Background:
3
+ * the CLI options are all off
4
+ * I have a cookbook named "bacon"
5
+
6
+ Scenario: --no-devodd
7
+ * I successfully run `bake 1.0.0 --no-devodd`
8
+
9
+ Scenario: --devodd
10
+ * I successfully run `bake 1.0.0 --devodd`
11
+ * the file "metadata.rb" should contain:
12
+ """
13
+ version '1.0.1'
14
+ """
15
+
16
+ Scenario: --git --devodd
17
+ * I have a cookbook named "bacon" with git support
18
+ * I successfully run `bake 1.0.0 --devodd --git`
19
+ * the git remote will have the commit "Version bump to v1.0.1"
@@ -1,8 +1,4 @@
1
1
  Feature: Git
2
- As a stove user
3
- In order to have a useful git tree
4
- I want to automatically tag and push to git
5
-
6
2
  Background:
7
3
  * the CLI options are all off
8
4
 
@@ -30,3 +26,9 @@ Feature: Git
30
26
  * I have a cookbook named "bacon"
31
27
  * I run `bake 1.0.0 --git`
32
28
  * the exit status will be "GitError::NotARepo"
29
+
30
+ Scenario: Remote repository out of sync
31
+ * I have a cookbook named "bacon" with git support
32
+ * the remote repository has additional commits
33
+ * I run `bake 1.0.0 --git`
34
+ * the exit status will be "GitError::OutOfSync"
@@ -0,0 +1,16 @@
1
+ @spawn
2
+ Feature: Rake Task
3
+ Background:
4
+ * I have a cookbook named "bacon"
5
+
6
+ Scenario: Using rake to publish a cookbook
7
+ * I write to "Rakefile" with:
8
+ """
9
+ require 'stove/rake_task'
10
+ Stove::RakeTask.new
11
+ """
12
+ * I successfully run `rake -T`
13
+ * the output should contain:
14
+ """
15
+ rake publish # Publish this cookbook
16
+ """
@@ -13,11 +13,16 @@ When /^the CLI options are all off$/ do
13
13
  private
14
14
  def options
15
15
  @options ||= {
16
- :git => false,
17
- :jira => false,
18
- :upload => false,
19
- :changelog => false,
20
- :log_level => :debug,
16
+ path: Dir.pwd,
17
+ git: false,
18
+ github: false,
19
+ devodd: false,
20
+ remote: 'origin',
21
+ branch: 'master',
22
+ jira: false,
23
+ upload: false,
24
+ changelog: false,
25
+ log_level: :fatal,
21
26
  }
22
27
  end
23
28
  end
@@ -4,8 +4,8 @@ Given /^the Community Site has the cookbooks?:$/ do |table|
4
4
  category ||= 'Other'
5
5
 
6
6
  CommunityZero::Cookbook.create({
7
- name: name,
8
- version: version,
7
+ name: name,
8
+ version: version,
9
9
  category: category,
10
10
  })
11
11
  end
@@ -1,3 +1,11 @@
1
+ Given /^the remote repository has additional commits/ do
2
+ Dir.chdir(fake_git_remote) do
3
+ shellout 'touch myfile.txt'
4
+ git 'add myfile.txt'
5
+ git 'commit -m "Add a new file"'
6
+ end
7
+ end
8
+
1
9
  Then /^the git remote will( not)? have the commit "(.+)"$/ do |negate, message|
2
10
  commits = git_commits(fake_git_remote)
3
11
 
@@ -10,13 +10,12 @@ require_relative '../../spec/support/git'
10
10
  World(Aruba::Api)
11
11
  World(Stove::RSpec::Git)
12
12
 
13
- Aruba::InProcess.main_class = Stove::Cli
14
- Aruba.process = Aruba::InProcess
15
-
16
13
  Stove.set_formatter(:silent)
17
14
  Stove::Config.instance_variable_set(:@instance, {
18
15
  'jira_username' => 'default',
19
16
  'jira_password' => 'default',
17
+ 'github_usernmae' => 'default',
18
+ 'github_password' => 'default',
20
19
  'opscode_username' => 'stove',
21
20
  'opscode_pem_file' => File.expand_path(File.join(__FILE__, '..', 'stove.pem')),
22
21
  })
@@ -29,6 +28,15 @@ Before do
29
28
  Stove::RSpec::CommunitySite.reset!
30
29
  end
31
30
 
31
+ Before('~@spawn') do
32
+ Aruba::InProcess.main_class = Stove::Cli
33
+ Aruba.process = Aruba::InProcess
34
+ end
35
+
36
+ Before('@spawn') do
37
+ Aruba.process = Aruba::SpawnProcess
38
+ end
39
+
32
40
  # The path to Aruba's "stuff"
33
41
  def tmp_path
34
42
  File.expand_path(@dirs.first.to_s)
@@ -1,8 +1,4 @@
1
1
  Feature: Upload
2
- As a stove user
3
- In order to upload cookbooks
4
- I want to tar and push to a Community Site
5
-
6
2
  Background:
7
3
  * I have a cookbook named "bacon"
8
4
  * the CLI options are all off
@@ -8,6 +8,7 @@ module Stove
8
8
  require_relative 'stove/cookbook'
9
9
  require_relative 'stove/error'
10
10
  require_relative 'stove/formatter'
11
+ require_relative 'stove/github'
11
12
  require_relative 'stove/jira'
12
13
  require_relative 'stove/mash'
13
14
  require_relative 'stove/packager'
@@ -54,14 +54,23 @@ module Stove
54
54
  options[:git] = v
55
55
  end
56
56
 
57
- opts.on('-r', '--remote', String, 'The name of the git remote to push to') do |v|
57
+ opts.on('--[no-]github', 'Automatically release to GitHub (default: true)') do |v|
58
+ options[:git] = v if v
59
+ options[:github] = v
60
+ end
61
+
62
+ opts.on('-r', '--remote [REMOTE]', String, 'The name of the git remote to push to') do |v|
58
63
  options[:remote] = v
59
64
  end
60
65
 
61
- opts.on('-b', '--branch', String, 'The name of the git branch to push to') do |v|
66
+ opts.on('-b', '--branch [BRANCH]', String, 'The name of the git branch to push to') do |v|
62
67
  options[:branch] = v
63
68
  end
64
69
 
70
+ opts.on('--[no-]devodd', 'Automatically bump the metadata for devodd releases') do |v|
71
+ options[:devodd] = v
72
+ end
73
+
65
74
  opts.on('--[no-]jira', 'Automatically populate the CHANGELOG from JIRA tickets and close them (default: false)') do |v|
66
75
  options[:jira] = v
67
76
  end
@@ -92,14 +101,16 @@ module Stove
92
101
  # @return [Hash]
93
102
  def options
94
103
  @options ||= {
95
- :path => Dir.pwd,
96
- :git => true,
97
- :remote => 'origin',
98
- :branch => 'master',
99
- :jira => false,
100
- :upload => true,
101
- :changelog => true,
102
- :log_level => :warn,
104
+ path: Dir.pwd,
105
+ git: true,
106
+ github: true,
107
+ devodd: false,
108
+ remote: 'origin',
109
+ branch: 'master',
110
+ jira: false,
111
+ upload: true,
112
+ changelog: true,
113
+ log_level: :warn,
103
114
  }
104
115
  end
105
116
 
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'retryable'
2
3
  require 'time'
3
4
 
4
5
  module Stove
@@ -86,43 +87,143 @@ module Stove
86
87
  #
87
88
  def release!
88
89
  if options[:git]
90
+ Stove::Logger.info "Running validations"
89
91
  validate_git_repo!
90
92
  validate_git_clean!
93
+ validate_remote_updated!
91
94
  end
92
95
 
96
+ Stove::Logger.info "Bumping version"
93
97
  version_bump
94
98
 
95
99
  if options[:changelog]
100
+ Stove::Logger.info "Updating changelog"
96
101
  update_changelog
97
102
  end
98
103
 
99
104
  if options[:git]
100
105
  Dir.chdir(path) do
106
+ Stove::Logger.info "Committing git changes in '#{path}'"
107
+
101
108
  git "add metadata.rb"
102
109
  git "add CHANGELOG.md"
103
- git "commit -m 'Version bump to v#{version}'"
104
- git "push #{options[:remote] || 'origin'} #{options[:branch] || 'master'}"
105
-
106
- git "tag v#{version}"
107
- git "push #{options[:remote] || 'origin'} v#{version}"
110
+ git "commit -m 'Version bump to #{tag_version}'"
111
+ git "push #{options[:remote]} #{options[:branch]}"
112
+
113
+ if options[:github]
114
+ Stove::Logger.info "Pushing release to GitHub"
115
+ Stove::GitHub.new(self).publish_release!
116
+ else
117
+ Stove::Logger.info "Tagging a release"
118
+ git "tag #{tag_version}"
119
+ git "push #{options[:remote]} #{tag_version}"
120
+ end
108
121
  end
109
122
  end
110
123
 
111
124
  if options[:upload]
112
- upload
125
+ Stove::Logger.info "Uploading cookbook"
126
+ retryable(tries: 3) do
127
+ upload
128
+ end
113
129
  end
114
130
 
115
131
  if options[:jira]
132
+ Stove::Logger.info "Resolving JIRA issues"
116
133
  resolve_jira_issues
117
134
  end
135
+
136
+ if options[:devodd]
137
+ Stove::Logger.info "Bumping devodd release"
138
+ split = version.split('.').map(&:to_i)
139
+ split[2] += 1
140
+ devodd = split.join('.')
141
+
142
+ version_bump(devodd)
143
+
144
+ if options[:git]
145
+ Dir.chdir(path) do
146
+ git "add metadata.rb"
147
+ git "commit -m 'Version bump to #{tag_version}'"
148
+ git "push #{options[:remote]} #{options[:branch]}"
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ def tag_version
155
+ "v#{version}"
156
+ end
157
+
158
+ # So there's this really really crazy bug that the tmp directory could
159
+ # be deleted mid-request...
160
+ #
161
+ # @return [File]
162
+ def tarball
163
+ return @tarball if @tarball && File.exists?(@tarball)
164
+
165
+ begin
166
+ @tarball = Stove::Packager.new(self).package_path
167
+ end until File.exists?(@tarball)
168
+ @tarball
118
169
  end
119
170
 
120
171
  #
121
172
  def upload
122
- return true unless options[:upload]
123
173
  Stove::Uploader.new(self).upload!
124
174
  end
125
175
 
176
+ # The URL for this repository on GitHub. This method automatically
177
+ # translates SSH and git:// URLs to https:// URLs.
178
+ #
179
+ # @return [String]
180
+ def repository_url
181
+ @repository_url ||= git("config --get remote.#{options[:remote]}.url")
182
+ .strip
183
+ .gsub(/\.git$/, '')
184
+ .gsub(':', '/')
185
+ .gsub('@', '://')
186
+ .gsub('git://', 'https://')
187
+ end
188
+
189
+ # The set of changes for this diff/patch in markdown format.
190
+ #
191
+ # @return [String]
192
+ def changeset
193
+ return @changeset if @changeset
194
+
195
+ contents = []
196
+ contents << "v#{version}"
197
+ contents << '-'*(version.length+1)
198
+
199
+ if options[:jira]
200
+ by_type = unreleased_tickets.inject({}) do |hash, ticket|
201
+ issue_type = ticket.fields.current['issuetype']['name']
202
+ hash[issue_type] ||= []
203
+ hash[issue_type] << {
204
+ number: ticket.jira_key,
205
+ details: ticket.fields.current['summary'],
206
+ }
207
+
208
+ hash
209
+ end
210
+
211
+ by_type.each do |issue_type, tickets|
212
+ contents << "### #{issue_type}"
213
+ tickets.sort { |a,b| b[:number].to_i <=> a[:number].to_i }.each do |ticket|
214
+ contents << "- **[#{ticket[:number]}](#{Stove::JIRA::JIRA_URL}/browse/#{ticket[:number]})** - #{ticket[:details]}"
215
+ end
216
+ contents << ""
217
+ end
218
+ else
219
+ contents << "_Enter CHANGELOG for #{name} (#{version}) here_"
220
+ contents << ""
221
+ end
222
+
223
+ @changeset = contents.join("\n")
224
+ @changeset
225
+ end
226
+
126
227
  private
127
228
  # Load the metadata and set the @metadata instance variable.
128
229
  #
@@ -142,42 +243,15 @@ module Stove
142
243
  end
143
244
  alias_method :reload_metadata!, :load_metadata!
144
245
 
145
- # Create a new CHANGELOG in markdown format.
146
- #
147
- # @example given a cookbook named bacon
148
- # cookbook.create_changelog #=> <<EOH
149
- # bacon Cookbook CHANGELOG
150
- # ------------------------
151
- # EOH
152
- #
153
- # @return [String]
154
- # the path to the new CHANGELOG
155
- def create_changelog
156
- destination = File.join(path, 'CHANGELOG.md')
157
-
158
- # Be idempotent :)
159
- return destination if File.exists?(destination)
160
-
161
- header = "#{name} Cookbook CHANGELOG\n"
162
- header << "#{'='*header.length}\n"
163
- header << "This file is used to list changes made in each version of the #{cookbook.name} cookbook.\n\n"
164
-
165
- File.open(destination, 'wb') do |file|
166
- file.write(header)
167
- end
168
-
169
- destination
170
- end
171
-
172
246
  # Update the CHANGELOG with the new contents, but inserting
173
247
  # the newest version's CHANGELOG at the top of the file (after
174
248
  # the header)
175
249
  def update_changelog
176
- changelog = create_changelog
250
+ changelog = File.join(path, 'CHANGELOG.md')
177
251
  contents = File.readlines(changelog)
178
252
 
179
253
  index = contents.find_index { |line| line =~ /(--)+/ } - 2
180
- contents.insert(index, "\n" + generate_changelog)
254
+ contents.insert(index, "\n" + changeset)
181
255
 
182
256
  Dir.mktmpdir do |dir|
183
257
  tmpfile = File.join(dir, 'CHANGELOG.md')
@@ -195,56 +269,18 @@ module Stove
195
269
  raise Stove::UserCanceledError
196
270
  end
197
271
 
198
- # Generate a CHANGELOG in markdown format.
199
- #
200
- # @param [String] version
201
- # the version string in x.y.z format
202
- #
203
- # @return [String]
204
- def generate_changelog
205
- contents = []
206
- contents << "v#{version}"
207
- contents << '-'*(version.length+1)
208
-
209
- if options[:jira]
210
- by_type = unreleased_tickets.inject({}) do |hash, ticket|
211
- issue_type = ticket.fields.current['issuetype']['name']
212
- hash[issue_type] ||= []
213
- hash[issue_type] << {
214
- number: ticket.jira_key,
215
- details: ticket.fields.current['summary'],
216
- }
217
-
218
- hash
219
- end
220
-
221
- by_type.each do |issue_type, tickets|
222
- contents << "### #{issue_type}"
223
- tickets.sort { |a,b| b[:number].to_i <=> a[:number].to_i }.each do |ticket|
224
- contents << "- **[#{ticket[:number]}](#{Stove::JIRA::JIRA_URL}/browse/#{ticket[:number]})** - #{ticket[:details]}"
225
- end
226
- contents << ""
227
- end
228
- else
229
- contents << "_Enter CHANGELOG for #{name} (#{version}) here_"
230
- contents << ""
231
- end
232
-
233
- contents.join("\n")
234
- end
235
-
236
272
  # Bump the version in the metdata.rb to the specified
237
273
  # parameter.
238
274
  #
239
275
  # @return [String]
240
276
  # the new version string
241
- def version_bump
242
- return true if new_version.to_s == version.to_s
277
+ def version_bump(bump_version = new_version)
278
+ return true if bump_version.to_s == version.to_s
243
279
 
244
280
  metadata_path = File.join(path, 'metadata.rb')
245
281
  contents = File.read(metadata_path)
246
282
 
247
- contents.sub!(/^version(\s+)('|")#{version.to_s}('|")/, "version\\1\\2#{new_version.to_s}\\3")
283
+ contents.sub!(/^version(\s+)('|")#{version.to_s}('|")/, "version\\1\\2#{bump_version.to_s}\\3")
248
284
 
249
285
  File.open(metadata_path, 'w') { |f| f.write(contents) }
250
286
  reload_metadata!
@@ -276,5 +312,15 @@ module Stove
276
312
  raise Stove::GitError::DirtyRepo unless git_repo_clean?
277
313
  end
278
314
  end
315
+
316
+ # Validate that the remote git repository is up to date.
317
+ #
318
+ # @raise [Stove::GitError::OutOfSync]
319
+ # if the current git repo is not up to date with the remote
320
+ def validate_remote_updated!
321
+ Dir.chdir(path) do
322
+ raise Stove::GitError::OutOfSync unless git_remote_uptodate?(options)
323
+ end
324
+ end
279
325
  end
280
326
  end
@@ -70,6 +70,14 @@ module Stove
70
70
  'You have untracked files!'
71
71
  end
72
72
  end
73
+
74
+ class OutOfSync < GitError
75
+ set_exit_code 133
76
+
77
+ def message
78
+ 'Your remote repository is out of sync!'
79
+ end
80
+ end
73
81
  end
74
82
 
75
83
  class UploadError < Error
@@ -81,7 +89,7 @@ module Stove
81
89
 
82
90
  def message
83
91
  "The following errors occured when uploading:\n" <<
84
- @response.parsed_response['error_messages'].map do |error|
92
+ (@response.parsed_response['error_messages'] || []).map do |error|
85
93
  " - #{error}"
86
94
  end.join("\n")
87
95
  end
@@ -44,6 +44,14 @@ module Stove
44
44
  false
45
45
  end
46
46
 
47
+ def git_remote_uptodate?(options = {})
48
+ git('fetch')
49
+ local = git("rev-parse #{options[:branch]}").strip
50
+ remote = git("rev-parse #{options[:remote]}/#{options[:branch]}").strip
51
+
52
+ local == remote
53
+ end
54
+
47
55
  def shellout(command)
48
56
  out, err = Tempfile.new('shellout.stdout'), Tempfile.new('shellout.stderr')
49
57
 
@@ -0,0 +1,43 @@
1
+ require 'octokit'
2
+
3
+ module Stove
4
+ class GitHub
5
+ attr_reader :cookbook
6
+
7
+ def initialize(cookbook)
8
+ @cookbook = cookbook
9
+
10
+ Octokit.configure do |config|
11
+ config.access_token = Stove::Config['github_access_token']
12
+ end
13
+ end
14
+
15
+ def publish_release!
16
+ release = Octokit.create_release(repository, cookbook.tag_version,
17
+ name: cookbook.tag_version,
18
+ body: changeset,
19
+ )
20
+ asset = Octokit.upload_asset("repos/#{repository}/releases/#{release.id}", cookbook.tarball,
21
+ content_type: 'application/x-gzip',
22
+ name: filename,
23
+ )
24
+ Octokit.update_release_asset("repos/#{repository}/releases/assets/#{asset.id}",
25
+ name: filename,
26
+ label: 'Download Cookbook',
27
+ )
28
+ end
29
+
30
+ private
31
+ def repository
32
+ @repository ||= Octokit::Repository.from_url(cookbook.repository_url)
33
+ end
34
+
35
+ def changeset
36
+ cookbook.changeset.split("\n")[2..-1].join("\n").strip
37
+ end
38
+
39
+ def filename
40
+ @filename ||= "#{cookbook.name}-#{cookbook.version}.tar.gz"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,63 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ module Stove
5
+ #
6
+ # Run Stove tasks from your +Rakefile+.
7
+ #
8
+ # @example
9
+ # desc "Run stove tasks"
10
+ # Stove::RakeTask.new(:release) do |stove|
11
+ # stove.git = true
12
+ # stove.devodd = true
13
+ # end
14
+ #
15
+ class RakeTask < ::Rake::TaskLib
16
+ class << self
17
+ #
18
+ # Define a CLI option.
19
+ #
20
+ # @param [Symbol] option
21
+ #
22
+ def cli_option(option)
23
+ define_method("#{option}=".to_sym) do |value|
24
+ options[option] = value
25
+ end
26
+
27
+ define_method(option.to_sym) do
28
+ options[option]
29
+ end
30
+ end
31
+ end
32
+
33
+ # @return [Symbol]
34
+ attr_accessor :name
35
+
36
+ # @return [Hash]
37
+ attr_reader :options
38
+
39
+ def initialize(task_name = nil)
40
+ @options = {}
41
+ @name = (task_name || :publish).to_sym
42
+
43
+ yield self if block_given?
44
+
45
+ desc 'Publish this cookbook' unless ::Rake.application.last_comment
46
+ task name do |t, args|
47
+ require 'stove'
48
+ Stove::Cookbook.new(options).release!
49
+ end
50
+ end
51
+
52
+ cli_option :branch
53
+ cli_option :category
54
+ cli_option :changelog
55
+ cli_option :devodd
56
+ cli_option :git
57
+ cli_option :jira
58
+ cli_option :log_level
59
+ cli_option :path
60
+ cli_option :remote
61
+ cli_option :upload
62
+ end
63
+ end
@@ -24,7 +24,7 @@ module Stove
24
24
  response = self.class.post(upload_url, {
25
25
  :headers => headers,
26
26
  :query => {
27
- :tarball => File.new(tarball),
27
+ :tarball => File.new(cookbook.tarball),
28
28
  :cookbook => { category: cookbook.category }.to_json,
29
29
  },
30
30
  })
@@ -45,19 +45,10 @@ module Stove
45
45
  :timestamp => Time.now.utc.iso8601,
46
46
  :user_id => username,
47
47
  :path => URI.parse(upload_url).path,
48
- :file => File.new(tarball),
48
+ :file => File.new(cookbook.tarball),
49
49
  }).sign(pem_file))
50
50
  end
51
51
 
52
- # So there's this really really crazy bug that the tmp directory could
53
- # be deleted mid-request...
54
- def tarball
55
- begin
56
- tgz = Stove::Packager.new(cookbook).package_path
57
- end until File.exists?(tgz)
58
- tgz
59
- end
60
-
61
52
  def pem_file
62
53
  OpenSSL::PKey::RSA.new(File.read(File.expand_path(Stove::Config['opscode_pem_file'])))
63
54
  end
@@ -1,3 +1,3 @@
1
1
  module Stove
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -11,6 +11,7 @@ module Stove
11
11
  git 'add --all'
12
12
  git 'commit --message "Initial commit"'
13
13
  git 'remote add origin file://' + fake_git_remote
14
+ git 'push origin master'
14
15
  end
15
16
  end
16
17
 
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'jiralicious', '~> 0.3'
24
24
  spec.add_dependency 'minitar', '~> 0.5'
25
25
  spec.add_dependency 'mixlib-authentication', '~> 1.3'
26
+ spec.add_dependency 'octokit', '~> 2.2'
27
+ spec.add_dependency 'retryable', '~> 1.3'
26
28
  spec.add_dependency 'solve', '~> 0.8'
27
29
 
28
30
  spec.add_development_dependency 'bundler', '~> 1.3'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stove
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seth Vargo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-28 00:00:00.000000000 Z
11
+ date: 2013-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: octokit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '2.2'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '2.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: retryable
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.3'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.3'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: solve
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -183,7 +211,9 @@ files:
183
211
  - bin/bake
184
212
  - features/changelog.feature
185
213
  - features/cli.feature
214
+ - features/devodd.feature
186
215
  - features/git.feature
216
+ - features/rake.feature
187
217
  - features/step_definitions/cli_steps.rb
188
218
  - features/step_definitions/community_site_steps.rb
189
219
  - features/step_definitions/cookbook_steps.rb
@@ -203,10 +233,12 @@ files:
203
233
  - lib/stove/formatter/human.rb
204
234
  - lib/stove/formatter/silent.rb
205
235
  - lib/stove/git.rb
236
+ - lib/stove/github.rb
206
237
  - lib/stove/jira.rb
207
238
  - lib/stove/logger.rb
208
239
  - lib/stove/mash.rb
209
240
  - lib/stove/packager.rb
241
+ - lib/stove/rake_task.rb
210
242
  - lib/stove/uploader.rb
211
243
  - lib/stove/version.rb
212
244
  - spec/support/community_site.rb
@@ -241,7 +273,9 @@ summary: A simple gem for packaging, releasing, and sanity-checking an Opscode c
241
273
  test_files:
242
274
  - features/changelog.feature
243
275
  - features/cli.feature
276
+ - features/devodd.feature
244
277
  - features/git.feature
278
+ - features/rake.feature
245
279
  - features/step_definitions/cli_steps.rb
246
280
  - features/step_definitions/community_site_steps.rb
247
281
  - features/step_definitions/cookbook_steps.rb