knife-changelog 1.2.5 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|