stove 1.0.1 → 1.1.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.
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