knife-changelog 1.2.5 → 1.5.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 +4 -4
- data/.github/workflows/ci.yml +15 -0
- data/.github/workflows/release.yml +18 -0
- data/Rakefile +4 -7
- data/knife-changelog.gemspec +1 -2
- data/lib/chef/knife/changelog.rb +7 -1
- data/lib/knife/changelog/changelog.rb +8 -3
- data/lib/knife/changelog/policyfile.rb +43 -5
- data/spec/unit/policyfile_spec.rb +39 -5
- metadata +5 -19
- data/.travis.yml +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac82fb7552ead5bf08e8d7340883adab40185d5098c60ab3944472b3d51555b8
|
4
|
+
data.tar.gz: 22f9713b7df19b7a332a1a275e3a69db6dfa0d9d59abd815d7728c22b6d7c006
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64bed7f1436c1d8536d479673d92d7749e7a8e9d16c271f81bbeac380c24b1f305300ff77bd4e17f7698746b2545b7773897923c7cb27dd68f6266f50ae5888a
|
7
|
+
data.tar.gz: e7939f44aefd0b409a9e5d2a12f7bdf1cd4ad9671c6ec906b1a650f51aaddb3cd72985ec3f220a5b8f96f532ddd1735d3bf7c9948927ac3905fc2f6dfb8e97c3
|
@@ -0,0 +1,15 @@
|
|
1
|
+
name: Tests
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
runs-on: ubuntu-latest
|
6
|
+
strategy:
|
7
|
+
matrix:
|
8
|
+
ruby-version: ['2.5', '2.7']
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v2
|
11
|
+
- uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: ${{ matrix.ruby-version }}
|
14
|
+
bundler-cache: true
|
15
|
+
- run: bundle exec rake
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: Release
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
tags: [ '*' ]
|
5
|
+
jobs:
|
6
|
+
release:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
- uses: ruby/setup-ruby@v1
|
11
|
+
with:
|
12
|
+
ruby-version: 2.7
|
13
|
+
- run: |
|
14
|
+
install -D -m 600 <(echo -e "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}") $HOME/.gem/credentials
|
15
|
+
gem build *.gemspec
|
16
|
+
gem push *.gem
|
17
|
+
env:
|
18
|
+
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
|
data/Rakefile
CHANGED
@@ -1,9 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
2
3
|
|
3
|
-
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
5
|
|
7
|
-
|
8
|
-
rescue LoadError
|
9
|
-
end
|
6
|
+
task default: :spec
|
data/knife-changelog.gemspec
CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'knife-changelog'
|
8
|
-
spec.version = '1.
|
8
|
+
spec.version = '1.5.0'
|
9
9
|
spec.authors = ['Gregoire Seux']
|
10
10
|
spec.email = ['kamaradclimber@gmail.com']
|
11
11
|
spec.summary = 'Facilitate access to cookbooks changelog'
|
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
21
|
spec.add_development_dependency 'pry'
|
23
22
|
spec.add_development_dependency 'rake'
|
24
23
|
spec.add_development_dependency 'rspec'
|
data/lib/chef/knife/changelog.rb
CHANGED
@@ -42,6 +42,12 @@ class Chef
|
|
42
42
|
long: '--submodules SUBMODULE[,SUBMODULE]',
|
43
43
|
description: 'Submoduless to check for changes as well (comma separated)'
|
44
44
|
|
45
|
+
option :prevent_downgrade,
|
46
|
+
long: '--prevent-downgrade',
|
47
|
+
description: 'Fail if knife-changelog detect a cookbook downgrade',
|
48
|
+
boolean: true,
|
49
|
+
default: false
|
50
|
+
|
45
51
|
option :policyfile,
|
46
52
|
long: '--policyfile PATH',
|
47
53
|
description: 'Link to policyfile, defaults to "Policyfile.rb"',
|
@@ -58,7 +64,7 @@ class Chef
|
|
58
64
|
description: 'Update Berksfile'
|
59
65
|
|
60
66
|
def run
|
61
|
-
Log.info config
|
67
|
+
Log.info config.to_s
|
62
68
|
if config[:policyfile] && File.exist?(config[:policyfile])
|
63
69
|
puts PolicyChangelog.new(
|
64
70
|
@name_args,
|
@@ -239,10 +239,15 @@ class KnifeChangelog
|
|
239
239
|
c
|
240
240
|
end
|
241
241
|
|
242
|
+
GERRIT_REGEXP = %r{^(.*)/[^/]+/[^/]+(?:\.git)$}
|
242
243
|
def linkify(url, changelog)
|
243
|
-
|
244
|
-
|
245
|
-
|
244
|
+
format = case url
|
245
|
+
when /gitlab/, /github/
|
246
|
+
"\\2 (#{url.chomp('.git')}/commit/\\1)"
|
247
|
+
when GERRIT_REGEXP
|
248
|
+
"\\2 (#{::Regexp.last_match(1)}/#/q/\\1)"
|
249
|
+
end
|
250
|
+
format ? changelog.map { |line| line.sub(/^([a-f0-9]+) (.*)$/, format) } : changelog
|
246
251
|
end
|
247
252
|
|
248
253
|
def https_url(location)
|
@@ -11,6 +11,9 @@ require 'rest-client'
|
|
11
11
|
|
12
12
|
class PolicyChangelog
|
13
13
|
TMP_PREFIX = 'knife-changelog'
|
14
|
+
# Regex matching Chef cookbook version syntax
|
15
|
+
# See https://docs.chef.io/cookbook_versioning.html#syntax
|
16
|
+
VERSION_REGEX = /^[1-9]*[0-9](\.[0-9]+){1,2}$/
|
14
17
|
|
15
18
|
# Initialzes Helper class
|
16
19
|
#
|
@@ -104,14 +107,30 @@ class PolicyChangelog
|
|
104
107
|
# @param current [String] current cookbook version tag
|
105
108
|
# @param target [String] target cookbook version tag
|
106
109
|
# @return [String] changelog between tags for one cookbook
|
107
|
-
def git_changelog(source_url, current, target)
|
110
|
+
def git_changelog(source_url, current, target, cookbook = nil)
|
108
111
|
dir = Dir.mktmpdir(TMP_PREFIX)
|
109
112
|
repo = Git.clone(source_url, dir)
|
110
|
-
|
113
|
+
cookbook_path = cookbook ? git_cookbook_path(repo, cookbook) : '.'
|
114
|
+
repo.log.path(cookbook_path).between(git_ref(current, repo, cookbook), git_ref(target, repo, cookbook)).map do |commit|
|
111
115
|
"#{commit.sha[0, 7]} #{commit.message.lines.first.strip}"
|
112
116
|
end.join("\n")
|
113
117
|
end
|
114
118
|
|
119
|
+
# Tries to find the location of a specific cookbook in the given repo
|
120
|
+
#
|
121
|
+
# @param repo [Git::Base] Git repository object
|
122
|
+
# @param cookbook [String] name of the cookbook to search the location
|
123
|
+
# @return [String] reative location of the cookbook in the repo
|
124
|
+
def git_cookbook_path(repo, cookbook)
|
125
|
+
metadata_files = ['metadata.rb', '*/metadata.rb'].flat_map { |location| repo.ls_files(location).keys }
|
126
|
+
metadata_path = metadata_files.find do |path|
|
127
|
+
path = ::File.join(repo.dir.to_s, path)
|
128
|
+
::Chef::Cookbook::Metadata.new.tap { |m| m.from_file(path) }.name == cookbook
|
129
|
+
end
|
130
|
+
raise "Impossible to find matching metadata for #{cookbook} in #{repo.remote.url}" unless metadata_path
|
131
|
+
::File.dirname(metadata_path)
|
132
|
+
end
|
133
|
+
|
115
134
|
# Tries to convert a supermarket tag to a git reference
|
116
135
|
# if there is a difference in formatting between the two.
|
117
136
|
# This is issue is present for the 'java' cookbook.
|
@@ -119,9 +138,11 @@ class PolicyChangelog
|
|
119
138
|
#
|
120
139
|
# @param ref [String] version reference
|
121
140
|
# @param repo [Git::Base] Git repository object
|
141
|
+
# @param cookbook [String] name of the cookbook to ref against
|
122
142
|
# @return [String]
|
123
|
-
def git_ref(myref, repo)
|
143
|
+
def git_ref(myref, repo, cookbook_name = nil)
|
124
144
|
possible_refs = ['v' + myref, myref]
|
145
|
+
possible_refs += possible_refs.map { |ref| "#{cookbook_name}-#{ref}" } if cookbook_name
|
125
146
|
possible_refs += possible_refs.map { |ref| ref.chomp('.0') } if myref[/\.0$/]
|
126
147
|
existing_ref = possible_refs.find do |ref|
|
127
148
|
begin
|
@@ -159,7 +180,7 @@ class PolicyChangelog
|
|
159
180
|
output = ["\nChangelog for #{name}: #{data['current_version']}->#{data['target_version']}"]
|
160
181
|
output << '=' * output.first.size
|
161
182
|
output << if data['current_version']
|
162
|
-
git_changelog(data['source_url'], data['current_version'], data['target_version'])
|
183
|
+
git_changelog(data['source_url'], data['current_version'], data['target_version'], name)
|
163
184
|
else
|
164
185
|
'Cookbook was not in the Policyfile.lock.json'
|
165
186
|
end
|
@@ -176,10 +197,24 @@ class PolicyChangelog
|
|
176
197
|
data['current_version'] == data['target_version'] || data['target_version'].nil?
|
177
198
|
end
|
178
199
|
|
200
|
+
# Search for cookbook downgrade and raise an error if any
|
201
|
+
def validate_downgrade!(data)
|
202
|
+
downgrade = data.select do |_, ck|
|
203
|
+
# Do not try to validate downgrade on non-sementic versions (e.g. git revision)
|
204
|
+
ck['target_version'] =~ VERSION_REGEX && ck['current_version'] =~ VERSION_REGEX &&
|
205
|
+
::Gem::Version.new(ck['target_version']) < ::Gem::Version.new(ck['current_version'])
|
206
|
+
end
|
207
|
+
|
208
|
+
return if downgrade.empty?
|
209
|
+
|
210
|
+
details = downgrade.map { |name, data| "#{name} (#{data['current_version']} -> #{data['target_version']})" }
|
211
|
+
raise "Trying to downgrade following cookbooks: #{details.join(', ')}"
|
212
|
+
end
|
213
|
+
|
179
214
|
# Generates Policyfile changelog
|
180
215
|
#
|
181
216
|
# @return [String] formatted version changelog
|
182
|
-
def generate_changelog
|
217
|
+
def generate_changelog(prevent_downgrade: false)
|
183
218
|
lock_current = read_policyfile_lock(@policyfile_dir)
|
184
219
|
current = versions(lock_current['cookbook_locks'], 'current')
|
185
220
|
|
@@ -192,6 +227,9 @@ class PolicyChangelog
|
|
192
227
|
else
|
193
228
|
updated_cookbooks.select { |name, _data| @cookbooks_to_update.include?(name) }
|
194
229
|
end
|
230
|
+
|
231
|
+
validate_downgrade!(updated_cookbooks) if prevent_downgrade
|
232
|
+
|
195
233
|
generate_changelog_from_versions(changelog_cookbooks)
|
196
234
|
end
|
197
235
|
|
@@ -92,6 +92,35 @@ RSpec.describe PolicyChangelog do
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
+
describe '#linkify' do
|
96
|
+
subject { KnifeChangelog::Changelog.new(config) }
|
97
|
+
let(:config) { double('config') }
|
98
|
+
let(:changelog) do
|
99
|
+
['9363423 Leverage criteo-flavor 3.11 to benefit from labels']
|
100
|
+
end
|
101
|
+
context 'when url is gitlab style' do
|
102
|
+
let(:url) { 'https://gitlab.com/chef-cookbooks/criteo-rackguru.git' }
|
103
|
+
|
104
|
+
it 'creates a gitlab style link' do
|
105
|
+
expect(subject.linkify(url, changelog).first).to match(%r{https://gitlab.com/chef-cookbooks/criteo-rackguru/commit/9363423})
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when url is github style' do
|
110
|
+
let(:url) { 'https://github.com/chef-cookbooks/criteo-rackguru.git' }
|
111
|
+
it 'creates a github style link' do
|
112
|
+
expect(subject.linkify(url, changelog).first).to match(%r{https://github.com/chef-cookbooks/criteo-rackguru/commit/9363423})
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when url has no known style' do
|
117
|
+
let(:url) { 'https://review.mycompany.com/chef-cookbooks/criteo-rackguru.git' }
|
118
|
+
it 'creates a gerrit style link' do
|
119
|
+
expect(subject.linkify(url, changelog).first).to match(%r{https://review.mycompany.com/#/q/9363423})
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
95
124
|
describe '#versions' do
|
96
125
|
context 'when type is current' do
|
97
126
|
it 'returns correct current versions' do
|
@@ -185,7 +214,7 @@ RSpec.describe PolicyChangelog do
|
|
185
214
|
allow(changelog).to receive(:git_ref).with('1.0.0', any_args).and_return('v1.0.0')
|
186
215
|
allow(changelog).to receive(:git_ref).with('1.0.1', any_args).and_return('v1.0.1')
|
187
216
|
allow(changelog).to receive(:correct_tags)
|
188
|
-
allow(git_repo).to receive_message_chain(:log, :between)
|
217
|
+
allow(git_repo).to receive_message_chain(:log, :path, :between)
|
189
218
|
.with('v1.0.0', 'v1.0.1')
|
190
219
|
.and_return([git_commit])
|
191
220
|
|
@@ -209,11 +238,16 @@ RSpec.describe PolicyChangelog do
|
|
209
238
|
|
210
239
|
context 'when tag invalid and able to correct' do
|
211
240
|
it 'returns correct git tag' do
|
212
|
-
allow(repo).to receive(:checkout).with(/v1.0/).and_raise(::Git::GitExecuteError)
|
213
241
|
allow(repo).to receive(:checkout).with('1.0.0').and_raise(::Git::GitExecuteError)
|
214
|
-
allow(repo).to receive(:checkout).with('1.0').and_return(true)
|
215
242
|
|
216
|
-
|
243
|
+
tags = %w[v1.0.0 1.0 v1.0 cookbook_name-1.0.0 cookbook_name-1.0 cookbook_name-v1.0.0 cookbook_name-v1.0]
|
244
|
+
tags.each do |valid_result|
|
245
|
+
allow(repo).to receive(:checkout).with(valid_result).and_return(true)
|
246
|
+
tags.reject { |v| v == valid_result }.each do |invalid_result|
|
247
|
+
allow(repo).to receive(:checkout).with(invalid_result).and_raise(::Git::GitExecuteError)
|
248
|
+
end
|
249
|
+
expect(changelog.git_ref('1.0.0', repo, 'cookbook_name')).to eq valid_result
|
250
|
+
end
|
217
251
|
end
|
218
252
|
end
|
219
253
|
|
@@ -279,7 +313,7 @@ RSpec.describe PolicyChangelog do
|
|
279
313
|
}
|
280
314
|
|
281
315
|
allow(changelog).to receive(:git_changelog)
|
282
|
-
.with(instance_of(String), '4.0.0', '5.0.0')
|
316
|
+
.with(instance_of(String), '4.0.0', '5.0.0', 'users')
|
283
317
|
.and_return('e1b971a Add test commit message')
|
284
318
|
|
285
319
|
output = <<~COMMIT.chomp
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-changelog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregoire Seux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.6'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.6'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: pry
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,9 +185,10 @@ executables: []
|
|
199
185
|
extensions: []
|
200
186
|
extra_rdoc_files: []
|
201
187
|
files:
|
188
|
+
- ".github/workflows/ci.yml"
|
189
|
+
- ".github/workflows/release.yml"
|
202
190
|
- ".gitignore"
|
203
191
|
- ".rubocop.yml"
|
204
|
-
- ".travis.yml"
|
205
192
|
- Gemfile
|
206
193
|
- LICENSE.txt
|
207
194
|
- README.md
|
@@ -243,8 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
243
230
|
- !ruby/object:Gem::Version
|
244
231
|
version: '0'
|
245
232
|
requirements: []
|
246
|
-
|
247
|
-
rubygems_version: 2.7.7
|
233
|
+
rubygems_version: 3.1.6
|
248
234
|
signing_key:
|
249
235
|
specification_version: 4
|
250
236
|
summary: Facilitate access to cookbooks changelog
|
data/.travis.yml
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.4
|
4
|
-
deploy:
|
5
|
-
provider: rubygems
|
6
|
-
api_key:
|
7
|
-
secure: LAM8qxTQa6oxzKiQpWrqRlcE1czmGFj16NSj1FVgZYJLZIfXKdvSpth+DfuCk8mxG1tvDXa3ckfERrzexG3lYGNPGyZH2sjnyt900Evd3Bn8vhv0LXE7cEZb3x/uJ3RHRvKpEDnMsy4gqoVByDLWXWnI9Q/8B4AtzFeTVsTr48g=
|
8
|
-
gem: knife-changelog
|
9
|
-
on:
|
10
|
-
tags: true
|
11
|
-
repo: criteo/knife-changelog
|
12
|
-
sudo: false # use docker based infra
|