kettle-dev 3.0.10 → 3.0.12
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +33 -1
- data/README.md +5 -3
- data/lib/kettle/dev/bundler_env_guard.rb +18 -6
- data/lib/kettle/dev/lockfile_reset.rb +79 -14
- data/lib/kettle/dev/pre_release_cli.rb +7 -0
- data/lib/kettle/dev/release_cli.rb +4 -1
- data/lib/kettle/dev/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 778a9528095541a29e4c6a15022c1fe312cf32ccb8f336972c046b02134bae32
|
|
4
|
+
data.tar.gz: bcc27b14726e3f17ad56b4e305e324c4ccb38df57df754f5f41b73e121f33a41
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f4b916aeb6714071d76ab84ae57e08650e42fe0607df2e7b366855932c66019ad3f8a2ba37befa0089b9261eb38092ab3bc33cce61237b0d9880139da3399de
|
|
7
|
+
data.tar.gz: 238a0802ae743f219f919a9fbdd2d1500aeea06ad8a756e5e377c4bc8c275e0d80bf07911f9a78b94e0095e9809afbb8eaeb9f98d9ee2e6db72242cfc2aa5fd9
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,34 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [3.0.12] - 2026-08-25
|
|
34
|
+
|
|
35
|
+
- TAG: [v3.0.12][3.0.12t]
|
|
36
|
+
- COVERAGE: 91.48% -- 5754/6290 lines in 47 files
|
|
37
|
+
- BRANCH COVERAGE: 76.34% -- 2207/2891 branches in 47 files
|
|
38
|
+
- 50.74% documented
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Expose shared lockfile section inspection primitives for family release validation.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Skip unresolved Kettle-Jem template image URLs during pre-release validation.
|
|
47
|
+
|
|
48
|
+
## [3.0.11] - 2026-08-24
|
|
49
|
+
|
|
50
|
+
- TAG: [v3.0.11][3.0.11t]
|
|
51
|
+
- COVERAGE: 91.27% -- 5699/6244 lines in 47 files
|
|
52
|
+
- BRANCH COVERAGE: 76.11% -- 2176/2859 branches in 47 files
|
|
53
|
+
- 51.11% documented
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- Run release changelog coverage against the registry-backed dependency graph instead of inheriting local templating paths.
|
|
58
|
+
|
|
59
|
+
- Reset dynamic Bundler parent markers before switching a child process to another Gemfile, so release changelog coverage runs the target project specs.
|
|
60
|
+
|
|
33
61
|
## [3.0.10] - 2026-08-23
|
|
34
62
|
|
|
35
63
|
- TAG: [v3.0.10][3.0.10t]
|
|
@@ -3529,7 +3557,11 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
3529
3557
|
- Selecting will run the selected workflow via `act`
|
|
3530
3558
|
- This may move to its own gem in the future.
|
|
3531
3559
|
|
|
3532
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.
|
|
3560
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.12...HEAD
|
|
3561
|
+
[3.0.12]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.11...v3.0.12
|
|
3562
|
+
[3.0.12t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.0.12
|
|
3563
|
+
[3.0.11]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.10...v3.0.11
|
|
3564
|
+
[3.0.11t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.0.11
|
|
3533
3565
|
[3.0.10]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.9...v3.0.10
|
|
3534
3566
|
[3.0.10t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.0.10
|
|
3535
3567
|
[3.0.9]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.8...v3.0.9
|
data/README.md
CHANGED
|
@@ -635,10 +635,12 @@ versions that are newer than the latest released version.
|
|
|
635
635
|
- Checks:
|
|
636
636
|
- 1) Validate GitHub Actions workflow action refs with `kettle-gha-sha-pins --check`; if pins are stale, it prints an outdated-actions summary, exits non-zero, and recommends `kettle-gha-sha-pins --write --upgrade patch`.
|
|
637
637
|
- 2) Normalize Markdown image URLs.
|
|
638
|
-
- 3) Validate
|
|
638
|
+
- 3) Validate Markdown references and local heading targets.
|
|
639
|
+
- 4) Validate that all image URLs referenced by Markdown files resolve (HTTP HEAD).
|
|
639
640
|
- Image URL skips:
|
|
640
641
|
- Star-history image API URLs are skipped by default because they are volatile.
|
|
641
|
-
-
|
|
642
|
+
- Unresolved Kettle-Jem template tokens are skipped because they are not URLs until templating completes.
|
|
643
|
+
- Add project-specific shell-style URL patterns in `.kettle-family.yml` or a config path pointed to by `KETTLE_FAMILY_CONFIG`. `kettle-family` passes this path through when it orchestrates a member release, but `kettle-dev` owns the matching and validation:
|
|
642
644
|
```yaml
|
|
643
645
|
pre_release:
|
|
644
646
|
image_url_skip_patterns:
|
|
@@ -1012,7 +1014,7 @@ Thanks for RTFM. ☺️
|
|
|
1012
1014
|
[📌gitmoji]: https://gitmoji.dev
|
|
1013
1015
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
1014
1016
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
1015
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-6.
|
|
1017
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-6.290-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
1016
1018
|
[🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
|
|
1017
1019
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
1018
1020
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -12,6 +12,14 @@ module Kettle
|
|
|
12
12
|
BUNDLER_VERSION
|
|
13
13
|
].freeze
|
|
14
14
|
|
|
15
|
+
# Bundler uses these markers to restore the environment of the parent
|
|
16
|
+
# bundle. They are not inert when a child explicitly selects another
|
|
17
|
+
# Gemfile: Bundler can use BUNDLER_ORIG_BUNDLE_GEMFILE to reselect the
|
|
18
|
+
# parent bundle. Clear the dynamic keys along with RESET_ENV_KEYS.
|
|
19
|
+
RESET_ENV_PREFIXES = %w[
|
|
20
|
+
BUNDLER_ORIG_
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
15
23
|
INERT_ENV_KEYS = %w[
|
|
16
24
|
BUNDLE_DEBUG
|
|
17
25
|
BUNDLE_QUIET
|
|
@@ -22,16 +30,18 @@ module Kettle
|
|
|
22
30
|
BUNDLER_DEBUG
|
|
23
31
|
].freeze
|
|
24
32
|
|
|
25
|
-
INERT_ENV_PREFIXES = %w[
|
|
26
|
-
BUNDLER_ORIG_
|
|
27
|
-
].freeze
|
|
28
|
-
|
|
29
33
|
module_function
|
|
30
34
|
|
|
31
35
|
def unbundled_env
|
|
32
|
-
RESET_ENV_KEYS.each_with_object({}) do |key,
|
|
36
|
+
env = RESET_ENV_KEYS.each_with_object({}) do |key, result|
|
|
37
|
+
result[key] = nil
|
|
38
|
+
end
|
|
39
|
+
ENV.each_key do |key|
|
|
40
|
+
next unless RESET_ENV_PREFIXES.any? { |prefix| key.start_with?(prefix) }
|
|
41
|
+
|
|
33
42
|
env[key] = nil
|
|
34
43
|
end
|
|
44
|
+
env
|
|
35
45
|
end
|
|
36
46
|
|
|
37
47
|
def warn_unexpected_env!(stream: $stderr)
|
|
@@ -45,6 +55,7 @@ module Kettle
|
|
|
45
55
|
)
|
|
46
56
|
end
|
|
47
57
|
|
|
58
|
+
# rubocop:disable ThreadSafety/ClassInstanceVariable -- warning state is intentionally shared by module functions.
|
|
48
59
|
def reset_warning_cache!
|
|
49
60
|
@warned_unexpected_env_keys = {}
|
|
50
61
|
end
|
|
@@ -56,7 +67,7 @@ module Kettle
|
|
|
56
67
|
def expected_env_key?(key)
|
|
57
68
|
RESET_ENV_KEYS.include?(key) ||
|
|
58
69
|
INERT_ENV_KEYS.include?(key) ||
|
|
59
|
-
|
|
70
|
+
RESET_ENV_PREFIXES.any? { |prefix| key.start_with?(prefix) }
|
|
60
71
|
end
|
|
61
72
|
|
|
62
73
|
def warned_unexpected_env?(keys)
|
|
@@ -67,6 +78,7 @@ module Kettle
|
|
|
67
78
|
@warned_unexpected_env_keys[signature] = true
|
|
68
79
|
false
|
|
69
80
|
end
|
|
81
|
+
# rubocop:enable ThreadSafety/ClassInstanceVariable
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
end
|
|
@@ -28,6 +28,84 @@ module Kettle
|
|
|
28
28
|
RUBYOPT
|
|
29
29
|
]).freeze
|
|
30
30
|
|
|
31
|
+
class << self
|
|
32
|
+
def local_path_remote_lines_from_source(lockfile_source)
|
|
33
|
+
in_path = false
|
|
34
|
+
lockfile_source.each_line.with_index(1).filter_map do |line, index|
|
|
35
|
+
stripped = line.strip
|
|
36
|
+
if stripped.match?(/\A[A-Z][A-Z ]*\z/)
|
|
37
|
+
in_path = stripped == "PATH"
|
|
38
|
+
next
|
|
39
|
+
end
|
|
40
|
+
next unless in_path
|
|
41
|
+
next unless stripped.start_with?("remote:")
|
|
42
|
+
next if stripped == "remote: ."
|
|
43
|
+
next unless stripped.start_with?("remote: /", "remote: ./", "remote: ../")
|
|
44
|
+
|
|
45
|
+
index
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def checksum_entries_from_source(lockfile_source)
|
|
50
|
+
in_checksums = false
|
|
51
|
+
entries = {}
|
|
52
|
+
lockfile_source.each_line do |line|
|
|
53
|
+
stripped = line.chomp
|
|
54
|
+
if stripped == "CHECKSUMS"
|
|
55
|
+
in_checksums = true
|
|
56
|
+
next
|
|
57
|
+
end
|
|
58
|
+
next unless in_checksums
|
|
59
|
+
break if !stripped.empty? && stripped == stripped.upcase && !stripped.start_with?(" ")
|
|
60
|
+
next unless stripped.start_with?(" ")
|
|
61
|
+
|
|
62
|
+
parsed = parse_lockfile_spec_line(stripped)
|
|
63
|
+
entries[[parsed.fetch(:name), parsed.fetch(:version)]] = parsed.fetch(:suffix) if parsed
|
|
64
|
+
end
|
|
65
|
+
in_checksums ? entries : nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def gem_specs_from_source(lockfile_source)
|
|
69
|
+
in_gem = false
|
|
70
|
+
in_specs = false
|
|
71
|
+
specs = []
|
|
72
|
+
lockfile_source.each_line do |line|
|
|
73
|
+
stripped = line.chomp
|
|
74
|
+
if stripped == "GEM"
|
|
75
|
+
in_gem = true
|
|
76
|
+
in_specs = false
|
|
77
|
+
next
|
|
78
|
+
end
|
|
79
|
+
next unless in_gem
|
|
80
|
+
break if !stripped.empty? && stripped == stripped.upcase && !stripped.start_with?(" ")
|
|
81
|
+
|
|
82
|
+
if stripped == " specs:"
|
|
83
|
+
in_specs = true
|
|
84
|
+
next
|
|
85
|
+
end
|
|
86
|
+
next unless in_specs
|
|
87
|
+
next unless line.start_with?(" ") && !line.start_with?(" ")
|
|
88
|
+
|
|
89
|
+
parsed = parse_lockfile_spec_line(stripped)
|
|
90
|
+
specs << [parsed.fetch(:name), parsed.fetch(:version)] if parsed
|
|
91
|
+
end
|
|
92
|
+
specs.uniq
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def parse_lockfile_spec_line(line)
|
|
98
|
+
stripped = line.to_s.strip
|
|
99
|
+
return nil if stripped.empty? || !stripped.include?(" (")
|
|
100
|
+
|
|
101
|
+
name, remainder = stripped.split(" (", 2)
|
|
102
|
+
version, suffix = remainder.to_s.split(")", 2)
|
|
103
|
+
return nil if name.to_s.empty? || version.to_s.empty?
|
|
104
|
+
|
|
105
|
+
{name: name, version: version, suffix: suffix.to_s.strip}
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
31
109
|
def initialize(root:, command_runner:)
|
|
32
110
|
@root = root
|
|
33
111
|
@command_runner = command_runner
|
|
@@ -248,20 +326,7 @@ module Kettle
|
|
|
248
326
|
end
|
|
249
327
|
|
|
250
328
|
def local_path_remote_lines(path)
|
|
251
|
-
|
|
252
|
-
File.readlines(path).filter_map.with_index(1) do |line, index|
|
|
253
|
-
stripped = line.strip
|
|
254
|
-
if stripped.match?(/\A[A-Z][A-Z ]*\z/)
|
|
255
|
-
in_path = stripped == "PATH"
|
|
256
|
-
next
|
|
257
|
-
end
|
|
258
|
-
next unless in_path
|
|
259
|
-
next unless stripped.start_with?("remote:")
|
|
260
|
-
next if stripped == "remote: ."
|
|
261
|
-
next unless stripped.start_with?("remote: /", "remote: ./", "remote: ../")
|
|
262
|
-
|
|
263
|
-
index
|
|
264
|
-
end
|
|
329
|
+
self.class.local_path_remote_lines_from_source(File.read(path))
|
|
265
330
|
end
|
|
266
331
|
|
|
267
332
|
def empty_registry_checksums(path)
|
|
@@ -511,6 +511,9 @@ module Kettle
|
|
|
511
511
|
end
|
|
512
512
|
|
|
513
513
|
def configured_image_url_skip_patterns
|
|
514
|
+
# Keep generic release safety in kettle-dev. Family-specific patterns
|
|
515
|
+
# are optional policy loaded from the family config when present, so a
|
|
516
|
+
# standalone kettle-release remains complete without kettle-family.
|
|
514
517
|
DEFAULT_IMAGE_URL_SKIP_PATTERNS + family_configured_image_url_skip_patterns
|
|
515
518
|
end
|
|
516
519
|
|
|
@@ -539,6 +542,10 @@ module Kettle
|
|
|
539
542
|
end
|
|
540
543
|
|
|
541
544
|
def image_url_skipped?(url)
|
|
545
|
+
# Unresolved Kettle-Jem tokens are valid in template source files and
|
|
546
|
+
# are not real URLs until templating. This rule must live here because
|
|
547
|
+
# direct kettle-dev releases do not run through kettle-family.
|
|
548
|
+
return true if url.to_s.include?("{KJ|")
|
|
542
549
|
return true if github_actions_badge_for_local_workflow?(url)
|
|
543
550
|
|
|
544
551
|
@image_url_skip_patterns.any? do |pattern|
|
|
@@ -902,7 +902,10 @@ module Kettle
|
|
|
902
902
|
escaped_gemfile = Shellwords.escape(gemfile)
|
|
903
903
|
command = +"env -u BUNDLE_GEMFILE -u BUNDLE_LOCKFILE"
|
|
904
904
|
if (local_root = release_changelog_local_root)
|
|
905
|
-
|
|
905
|
+
# Changelog coverage runs before the release lockfile reset. Keep it
|
|
906
|
+
# on the registry-backed release graph instead of reintroducing local
|
|
907
|
+
# sibling paths through the inherited templating switch.
|
|
908
|
+
command << " KETTLE_DEV_DEV=false K_JEM_TEMPLATING=false KETTLE_CHANGELOG_DEV_ROOT=#{Shellwords.escape(local_root)}"
|
|
906
909
|
end
|
|
907
910
|
command << " BUNDLE_GEMFILE=#{escaped_gemfile} bundle exec kettle-changelog"
|
|
908
911
|
command
|
data/lib/kettle/dev/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Kettle
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = "3.0.
|
|
8
|
+
VERSION = "3.0.12"
|
|
9
9
|
end
|
|
10
10
|
# Current gem version exposed at the traditional constant location.
|
|
11
11
|
VERSION = Version::VERSION # Traditional Constant Location
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-dev
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -400,10 +400,10 @@ licenses:
|
|
|
400
400
|
- AGPL-3.0-only
|
|
401
401
|
metadata:
|
|
402
402
|
homepage_uri: https://kettle-dev.galtzo.com
|
|
403
|
-
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.0.
|
|
404
|
-
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.0.
|
|
403
|
+
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.0.12
|
|
404
|
+
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.0.12/CHANGELOG.md
|
|
405
405
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
|
|
406
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.0.
|
|
406
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.0.12
|
|
407
407
|
funding_uri: https://github.com/sponsors/pboling
|
|
408
408
|
wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
|
|
409
409
|
news_uri: https://www.railsbling.com/tags/kettle-dev
|
metadata.gz.sig
CHANGED
|
Binary file
|