kettle-dev 2.3.8 → 2.3.9
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 +21 -1
- data/README.md +1 -1
- data/exe/kettle-changelog +5 -2
- data/lib/kettle/dev/changelog_cli.rb +4 -5
- data/lib/kettle/dev/gem_coop_versions.rb +92 -0
- data/lib/kettle/dev/release_cli.rb +16 -4
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +5 -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: 846ffb7540c0c7d69659591baf978274184f722f726aacc6e4915c0f376dbeb4
|
|
4
|
+
data.tar.gz: '08818034dfa875f33cdc89579cf455a011ecebf25be759b31af8702458e8eb6b'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0014c68a3e93d78a01c8b561956cbf474eaf25c6c8491b8ff1d229e7070eca06d3a3ed0282f739b1a3e4c38040f9bd8e5155e030a6baf1e7694a731a4bce5e2d
|
|
7
|
+
data.tar.gz: eeb028f65feddaac27a4f268a627d77fa686836bf368ca62c8b4b169acff3b43abf8aa432d96dc24341b4d27a61d74cd1197a529db1f2287c05661257f67880c
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,24 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [2.3.9] - 2026-07-21
|
|
34
|
+
|
|
35
|
+
- TAG: [v2.3.9][2.3.9t]
|
|
36
|
+
- COVERAGE: 92.06% -- 4443/4826 lines in 37 files
|
|
37
|
+
- BRANCH COVERAGE: 74.09% -- 1733/2339 branches in 37 files
|
|
38
|
+
- 54.64% documented
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- `kettle-release` now records a short-lived gem.coop release-state cache-bust
|
|
43
|
+
marker after publishing, and `kettle-changelog --release-state` uses it to
|
|
44
|
+
refresh just-published gem version lookups.
|
|
45
|
+
|
|
46
|
+
- `dep-heads.yml` now runs each engine directly from
|
|
47
|
+
`gemfiles/dep_heads.gemfile`, avoiding `Appraisal.root.gemfile` bootstrap
|
|
48
|
+
failures with RubyGems/Bundler and gem.coop before the dep-heads appraisal is
|
|
49
|
+
selected.
|
|
50
|
+
|
|
33
51
|
## [2.3.8] - 2026-07-21
|
|
34
52
|
|
|
35
53
|
- TAG: [v2.3.8][2.3.8t]
|
|
@@ -2568,7 +2586,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
2568
2586
|
- Selecting will run the selected workflow via `act`
|
|
2569
2587
|
- This may move to its own gem in the future.
|
|
2570
2588
|
|
|
2571
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.
|
|
2589
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.9...HEAD
|
|
2590
|
+
[2.3.9]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.8...v2.3.9
|
|
2591
|
+
[2.3.9t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.3.9
|
|
2572
2592
|
[2.3.8]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.7...v2.3.8
|
|
2573
2593
|
[2.3.8t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.3.8
|
|
2574
2594
|
[2.3.7]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.6...v2.3.7
|
data/README.md
CHANGED
|
@@ -889,7 +889,7 @@ Thanks for RTFM. ☺️
|
|
|
889
889
|
[📌gitmoji]: https://gitmoji.dev
|
|
890
890
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
891
891
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
892
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.
|
|
892
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.826-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
893
893
|
[🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
|
|
894
894
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
895
895
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/exe/kettle-changelog
CHANGED
|
@@ -55,7 +55,7 @@ end
|
|
|
55
55
|
|
|
56
56
|
if ARGV.include?("-h") || ARGV.include?("--help")
|
|
57
57
|
puts <<~USAGE
|
|
58
|
-
Usage: kettle-changelog [--version VERSION] [--update-prep] [--pending-release] [--release-state] [--add-unreleased-entry --section SECTION --entry TEXT] [--json] [--no-strict] [--no-coverage-threshold]
|
|
58
|
+
Usage: kettle-changelog [--version VERSION] [--update-prep] [--pending-release] [--release-state] [--refresh-cache] [--add-unreleased-entry --section SECTION --entry TEXT] [--json] [--no-strict] [--no-coverage-threshold]
|
|
59
59
|
|
|
60
60
|
Detects the current version from lib/**/version.rb, the latest live release, and
|
|
61
61
|
the most recent CHANGELOG.md release section, then prompts to confirm the selected plan:
|
|
@@ -70,6 +70,7 @@ if ARGV.include?("-h") || ARGV.include?("--help")
|
|
|
70
70
|
--pending-release Query whether the changelog has release work pending; exits 0 for yes, 1 for no
|
|
71
71
|
--release-state,
|
|
72
72
|
--release-status Print changelog release state, including latest published release and pending sources
|
|
73
|
+
--refresh-cache Bypass cached gem.coop version data for this invocation
|
|
73
74
|
--add-unreleased-entry Add one entry to an existing section under ## [Unreleased]
|
|
74
75
|
--section SECTION Unreleased section to receive the entry (Added, Changed, Deprecated, Removed, Fixed, Security)
|
|
75
76
|
--entry TEXT Changelog entry text; "- " is added when omitted
|
|
@@ -82,6 +83,7 @@ if ARGV.include?("-h") || ARGV.include?("--help")
|
|
|
82
83
|
K_CHANGELOG_COVERAGE_HARD=false Disable coverage threshold hard-failure
|
|
83
84
|
K_CHANGELOG_VERSION_FILE=path Read VERSION from this file instead of lib/**/version.rb
|
|
84
85
|
K_CHANGELOG_GEM_NAME=name Read live release data as this gem instead of root .gemspec
|
|
86
|
+
KETTLE_GEM_COOP_REFRESH=true Bypass cached gem.coop version data
|
|
85
87
|
|
|
86
88
|
Data generation:
|
|
87
89
|
Strict mode is the default. Release plans remove stale coverage output,
|
|
@@ -131,6 +133,7 @@ begin
|
|
|
131
133
|
update_prep = ARGV.delete("--update-prep")
|
|
132
134
|
pending_release_query = ARGV.delete("--pending-release")
|
|
133
135
|
release_state_query = ARGV.delete("--release-state") || ARGV.delete("--release-status")
|
|
136
|
+
refresh_cache = ARGV.delete("--refresh-cache")
|
|
134
137
|
add_unreleased_entry = ARGV.delete("--add-unreleased-entry") || ARGV.delete("--add-changelog-entry")
|
|
135
138
|
json_output = ARGV.delete("--json")
|
|
136
139
|
coverage_threshold_disabled = ARGV.include?("--no-coverage-threshold") || ARGV.include?("--no-coverage-thresholds")
|
|
@@ -167,7 +170,7 @@ begin
|
|
|
167
170
|
exit(0)
|
|
168
171
|
end
|
|
169
172
|
|
|
170
|
-
cli = Kettle::Dev::ChangelogCLI.new(strict: strict_mode, enforce_coverage_thresholds: coverage_hard, update_prep: update_prep, version: version_override)
|
|
173
|
+
cli = Kettle::Dev::ChangelogCLI.new(strict: strict_mode, enforce_coverage_thresholds: coverage_hard, update_prep: update_prep, version: version_override, refresh_cache: refresh_cache)
|
|
171
174
|
if release_state_query
|
|
172
175
|
state = cli.release_state
|
|
173
176
|
puts(json_output ? JSON.pretty_generate(state) : cli.release_state_table(state))
|
|
@@ -27,7 +27,7 @@ module Kettle
|
|
|
27
27
|
# @param enforce_coverage_thresholds [Boolean] when true, fail strict coverage generation below project thresholds
|
|
28
28
|
# @param update_prep [Boolean] when true, update the most recent prepared release section in place
|
|
29
29
|
# @param version [String, nil] explicit version override for gems without a literal VERSION constant
|
|
30
|
-
def initialize(strict: true, enforce_coverage_thresholds: true, update_prep: false, version: nil, root: Kettle::Dev::CIHelpers.project_root)
|
|
30
|
+
def initialize(strict: true, enforce_coverage_thresholds: true, update_prep: false, version: nil, root: Kettle::Dev::CIHelpers.project_root, refresh_cache: false)
|
|
31
31
|
@root = root
|
|
32
32
|
@changelog_path = File.join(@root, "CHANGELOG.md")
|
|
33
33
|
@coverage_path = File.join(@root, "coverage", "coverage.json")
|
|
@@ -35,6 +35,7 @@ module Kettle
|
|
|
35
35
|
@enforce_coverage_thresholds = enforce_coverage_thresholds
|
|
36
36
|
@update_prep = update_prep
|
|
37
37
|
@version_override = Kettle::Dev::Versioning.normalize_explicit_version(version)
|
|
38
|
+
@refresh_cache = refresh_cache
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
# Main entry point to update CHANGELOG.md
|
|
@@ -399,11 +400,9 @@ module Kettle
|
|
|
399
400
|
end
|
|
400
401
|
|
|
401
402
|
def latest_released_versions(gem_name, current_version)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
return [nil, nil] unless res.is_a?(Net::HTTPSuccess)
|
|
403
|
+
data = Kettle::Dev::GemCoopVersions.fetch(gem_name, version_hint: current_version, refresh: @refresh_cache)
|
|
404
|
+
return [nil, nil, nil] unless data.is_a?(Array)
|
|
405
405
|
|
|
406
|
-
data = JSON.parse(res.body)
|
|
407
406
|
versions = data.map { |h| h["number"] }.compact
|
|
408
407
|
versions.reject! { |v| v.to_s.include?("-pre") || v.to_s.include?(".pre") || v.to_s.match?(/[a-zA-Z]/) }
|
|
409
408
|
gversions = versions.map { |s| Gem::Version.new(s) }.sort
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "json"
|
|
5
|
+
require "net/http"
|
|
6
|
+
require "time"
|
|
7
|
+
require "uri"
|
|
8
|
+
|
|
9
|
+
module Kettle
|
|
10
|
+
module Dev
|
|
11
|
+
module GemCoopVersions
|
|
12
|
+
CACHE_BUST_TTL_SECONDS = 15 * 60
|
|
13
|
+
ENV_REFRESH = "KETTLE_GEM_COOP_REFRESH"
|
|
14
|
+
ENV_MARKER_PATH = "KETTLE_GEM_COOP_CACHE_BUST_PATH"
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
def fetch(gem_name, version_hint: nil, refresh: false)
|
|
18
|
+
cache_bust = refresh || env_refresh? || fresh_release_marker?(gem_name, version_hint)
|
|
19
|
+
uri = versions_uri(gem_name, cache_bust: cache_bust)
|
|
20
|
+
request = Net::HTTP::Get.new(uri)
|
|
21
|
+
if cache_bust
|
|
22
|
+
request["Cache-Control"] = "no-cache"
|
|
23
|
+
request["Pragma"] = "no-cache"
|
|
24
|
+
end
|
|
25
|
+
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
|
|
26
|
+
http.request(request)
|
|
27
|
+
end
|
|
28
|
+
return nil unless response.is_a?(Net::HTTPSuccess)
|
|
29
|
+
|
|
30
|
+
JSON.parse(response.body)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def mark_released(gem_name, version)
|
|
34
|
+
return if gem_name.to_s.empty? || version.to_s.empty?
|
|
35
|
+
|
|
36
|
+
path = marker_path
|
|
37
|
+
data = read_marker(path)
|
|
38
|
+
data["releases"] ||= {}
|
|
39
|
+
data["releases"][gem_name.to_s] = {
|
|
40
|
+
"version" => version.to_s,
|
|
41
|
+
"released_at" => Time.now.utc.iso8601
|
|
42
|
+
}
|
|
43
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
44
|
+
File.write(path, JSON.pretty_generate(data) << "\n")
|
|
45
|
+
rescue => error
|
|
46
|
+
warn("[kettle-dev] could not update gem.coop cache-bust marker: #{error.class}: #{error.message}") if Kettle::Dev::DEBUGGING
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def marker_path
|
|
50
|
+
configured = ENV.fetch(ENV_MARKER_PATH, "").to_s
|
|
51
|
+
return configured unless configured.empty?
|
|
52
|
+
|
|
53
|
+
state_home = ENV["XDG_STATE_HOME"]
|
|
54
|
+
state_home = File.join(Dir.home, ".local", "state") if state_home.to_s.empty?
|
|
55
|
+
File.join(state_home, "kettle-dev", "gem-coop-cache-bust.json")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def versions_uri(gem_name, cache_bust:)
|
|
61
|
+
uri = URI("https://gem.coop/api/v1/versions/#{gem_name}.json")
|
|
62
|
+
uri.query = "_kettle_cache_bust=#{Time.now.to_i}" if cache_bust
|
|
63
|
+
uri
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def fresh_release_marker?(gem_name, version_hint)
|
|
67
|
+
entry = read_marker(marker_path).fetch("releases", {})[gem_name.to_s]
|
|
68
|
+
return false unless entry
|
|
69
|
+
return false if version_hint && entry["version"].to_s != version_hint.to_s
|
|
70
|
+
|
|
71
|
+
released_at = Time.iso8601(entry["released_at"].to_s)
|
|
72
|
+
released_at >= Time.now.utc - CACHE_BUST_TTL_SECONDS
|
|
73
|
+
rescue ArgumentError
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def read_marker(path)
|
|
78
|
+
return {} unless File.file?(path)
|
|
79
|
+
|
|
80
|
+
parsed = JSON.parse(File.read(path))
|
|
81
|
+
parsed.is_a?(Hash) ? parsed : {}
|
|
82
|
+
rescue JSON::ParserError
|
|
83
|
+
{}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def env_refresh?
|
|
87
|
+
ENV.fetch(ENV_REFRESH, "").match?(Kettle::Dev::ENV_TRUE_RE)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -344,6 +344,7 @@ module Kettle
|
|
|
344
344
|
else
|
|
345
345
|
puts "Running release (you may be prompted for signing key password and RubyGems MFA OTP)..."
|
|
346
346
|
run_cmd!("bundle exec rake release")
|
|
347
|
+
mark_gem_coop_release_cache_bust(version || detect_version)
|
|
347
348
|
end
|
|
348
349
|
end
|
|
349
350
|
|
|
@@ -954,6 +955,7 @@ module Kettle
|
|
|
954
955
|
|
|
955
956
|
puts "Publishing #{File.basename(gem_path)} to RubyGems without pushing git refs..."
|
|
956
957
|
run_cmd!("gem push #{Shellwords.escape(gem_path)}")
|
|
958
|
+
mark_gem_coop_release_cache_bust(version, gem_name: gem_name_from_gem_path(gem_path, version))
|
|
957
959
|
end
|
|
958
960
|
|
|
959
961
|
def detect_version
|
|
@@ -971,11 +973,9 @@ module Kettle
|
|
|
971
973
|
end
|
|
972
974
|
|
|
973
975
|
def latest_released_versions(gem_name, current_version)
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return [nil, nil] unless res.is_a?(Net::HTTPSuccess)
|
|
976
|
+
data = Kettle::Dev::GemCoopVersions.fetch(gem_name, version_hint: current_version)
|
|
977
|
+
return [nil, nil] unless data.is_a?(Array)
|
|
977
978
|
|
|
978
|
-
data = JSON.parse(res.body)
|
|
979
979
|
versions = data.map { |h| h["number"] }.compact
|
|
980
980
|
versions.reject! { |v| v.to_s.include?("-pre") || v.to_s.include?(".pre") || /[a-zA-Z]/.match?(v.to_s) }
|
|
981
981
|
gversions = versions.map { |s| Gem::Version.new(s) }.sort
|
|
@@ -991,6 +991,18 @@ module Kettle
|
|
|
991
991
|
[nil, nil]
|
|
992
992
|
end
|
|
993
993
|
|
|
994
|
+
def mark_gem_coop_release_cache_bust(version, gem_name: nil)
|
|
995
|
+
gem_name ||= detect_gem_name
|
|
996
|
+
Kettle::Dev::GemCoopVersions.mark_released(gem_name, version)
|
|
997
|
+
rescue => error
|
|
998
|
+
warn("[kettle-release] could not mark gem.coop cache-bust for release-state: #{error.class}: #{error.message}") if Kettle::Dev::DEBUGGING
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
def gem_name_from_gem_path(gem_path, version)
|
|
1002
|
+
basename = File.basename(gem_path, ".gem")
|
|
1003
|
+
basename.delete_suffix("-#{version}")
|
|
1004
|
+
end
|
|
1005
|
+
|
|
994
1006
|
def commit_release_prep!(version)
|
|
995
1007
|
msg = "🔖 Prepare release v#{version}"
|
|
996
1008
|
# Stage all changes (including new/untracked files) prior to committing
|
data/lib/kettle/dev/version.rb
CHANGED
data/lib/kettle/dev.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative "dev/version"
|
|
|
5
5
|
if Gem.ruby_version < Gem::Version.new("2.7")
|
|
6
6
|
begin
|
|
7
7
|
require "backports/2.7.0/enumerable/filter_map"
|
|
8
|
+
require "backports/2.5.0/string/delete_suffix"
|
|
8
9
|
rescue LoadError => error
|
|
9
10
|
message = "kettle-dev on Ruby <= 2.6 requires the backports gem; " \
|
|
10
11
|
"add `gem \"backports\", \">= 3.25\"` to your Gemfile (#{error.message})"
|
|
@@ -33,6 +34,7 @@ module Kettle
|
|
|
33
34
|
autoload :CommitMsg, "kettle/dev/commit_msg"
|
|
34
35
|
autoload :DvcsCLI, "kettle/dev/dvcs_cli"
|
|
35
36
|
autoload :ExitAdapter, "kettle/dev/exit_adapter"
|
|
37
|
+
autoload :GemCoopVersions, "kettle/dev/gem_coop_versions"
|
|
36
38
|
autoload :GemSpecReader, "kettle/dev/gem_spec_reader"
|
|
37
39
|
autoload :GitAdapter, "kettle/dev/git_adapter"
|
|
38
40
|
autoload :GitCommitFooter, "kettle/dev/git_commit_footer"
|
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: 2.3.
|
|
4
|
+
version: 2.3.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -282,6 +282,7 @@ files:
|
|
|
282
282
|
- lib/kettle/dev/commit_msg.rb
|
|
283
283
|
- lib/kettle/dev/dvcs_cli.rb
|
|
284
284
|
- lib/kettle/dev/exit_adapter.rb
|
|
285
|
+
- lib/kettle/dev/gem_coop_versions.rb
|
|
285
286
|
- lib/kettle/dev/gem_spec_reader.rb
|
|
286
287
|
- lib/kettle/dev/gha_sha_pins_cli.rb
|
|
287
288
|
- lib/kettle/dev/git_adapter.rb
|
|
@@ -313,10 +314,10 @@ licenses:
|
|
|
313
314
|
- AGPL-3.0-only
|
|
314
315
|
metadata:
|
|
315
316
|
homepage_uri: https://kettle-dev.galtzo.com
|
|
316
|
-
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.3.
|
|
317
|
-
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.3.
|
|
317
|
+
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.3.9
|
|
318
|
+
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.3.9/CHANGELOG.md
|
|
318
319
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
|
|
319
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.3.
|
|
320
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.3.9
|
|
320
321
|
funding_uri: https://github.com/sponsors/pboling
|
|
321
322
|
wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
|
|
322
323
|
news_uri: https://www.railsbling.com/tags/kettle-dev
|
metadata.gz.sig
CHANGED
|
Binary file
|