kettle-dev 2.3.8 → 2.3.10
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 +50 -1
- data/README.md +3 -1
- data/exe/kettle-changelog +5 -2
- data/exe/kettle-gha-sha-pins +5 -31
- data/lib/kettle/dev/changelog_cli.rb +4 -5
- data/lib/kettle/dev/gem_coop_versions.rb +92 -0
- data/lib/kettle/dev/gha_sha_pins_cli.rb +12 -1357
- 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 +28 -7
- 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: 043a73e1a2fb35f02748261dc4d5f81865e233a982c10b73d6b957ef7a7ce66d
|
|
4
|
+
data.tar.gz: 4695065e3a9a9ce34f586fb4baeb76064b59048914a7c12e5e1590435dfe5862
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 555075c8b24c72b0a3ae955d790d0af6b97f265a5fcd00dd3aad16bf3c46ca315081b64d6a39553039e70c438774553826eb7e2a7ecc358e441fa1a066cadeb1
|
|
7
|
+
data.tar.gz: 896b19afe31b86aaed964605cf63767ec1d8bc4d8c214e1599835781c2f86919d1510d1601a7597cb53cf57713812779b07de550d710e0d7ac40c3c4f7d28d4b
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,51 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [2.3.10] - 2026-07-23
|
|
34
|
+
|
|
35
|
+
- TAG: [v2.3.10][2.3.10t]
|
|
36
|
+
- COVERAGE: 92.35% -- 3790/4104 lines in 37 files
|
|
37
|
+
- BRANCH COVERAGE: 75.95% -- 1500/1975 branches in 37 files
|
|
38
|
+
- 60.00% documented
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Local development tooling now uses `kettle-gha-pins` 0.2.0 or newer on
|
|
43
|
+
Ruby 3.2+, while keeping older supported Ruby bundles solvable.
|
|
44
|
+
- `kettle-gha-sha-pins` now delegates GitHub Actions release-tag parsing,
|
|
45
|
+
canonicalization, cache persistence, GitHub release/tag/commit resolution,
|
|
46
|
+
and upgrade-target selection to the shared
|
|
47
|
+
`kettle-gha-pins` gem.
|
|
48
|
+
- `kettle-gha-sha-pins` is now a compatibility wrapper around the
|
|
49
|
+
`kettle-gha-pins` executable.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- Restored `kettle-gha-pins` as a normal runtime dependency now that 0.2.1
|
|
54
|
+
supports the full `kettle-dev` Ruby floor.
|
|
55
|
+
|
|
56
|
+
- Appraisal rake task specs now rely on kettle-test's `silent_stream`
|
|
57
|
+
integration instead of stubbing `Object#warn`, which is not supported under
|
|
58
|
+
JRuby 9.4.
|
|
59
|
+
|
|
60
|
+
## [2.3.9] - 2026-07-21
|
|
61
|
+
|
|
62
|
+
- TAG: [v2.3.9][2.3.9t]
|
|
63
|
+
- COVERAGE: 92.06% -- 4443/4826 lines in 37 files
|
|
64
|
+
- BRANCH COVERAGE: 74.09% -- 1733/2339 branches in 37 files
|
|
65
|
+
- 54.64% documented
|
|
66
|
+
|
|
67
|
+
### Fixed
|
|
68
|
+
|
|
69
|
+
- `kettle-release` now records a short-lived gem.coop release-state cache-bust
|
|
70
|
+
marker after publishing, and `kettle-changelog --release-state` uses it to
|
|
71
|
+
refresh just-published gem version lookups.
|
|
72
|
+
|
|
73
|
+
- `dep-heads.yml` now runs each engine directly from
|
|
74
|
+
`gemfiles/dep_heads.gemfile`, avoiding `Appraisal.root.gemfile` bootstrap
|
|
75
|
+
failures with RubyGems/Bundler and gem.coop before the dep-heads appraisal is
|
|
76
|
+
selected.
|
|
77
|
+
|
|
33
78
|
## [2.3.8] - 2026-07-21
|
|
34
79
|
|
|
35
80
|
- TAG: [v2.3.8][2.3.8t]
|
|
@@ -2568,7 +2613,11 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
2568
2613
|
- Selecting will run the selected workflow via `act`
|
|
2569
2614
|
- This may move to its own gem in the future.
|
|
2570
2615
|
|
|
2571
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.
|
|
2616
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.10...HEAD
|
|
2617
|
+
[2.3.10]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.9...v2.3.10
|
|
2618
|
+
[2.3.10t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.3.10
|
|
2619
|
+
[2.3.9]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.8...v2.3.9
|
|
2620
|
+
[2.3.9t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.3.9
|
|
2572
2621
|
[2.3.8]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.7...v2.3.8
|
|
2573
2622
|
[2.3.8t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.3.8
|
|
2574
2623
|
[2.3.7]: https://github.com/kettle-dev/kettle-dev/compare/v2.3.6...v2.3.7
|
data/README.md
CHANGED
|
@@ -470,6 +470,8 @@ What it does:
|
|
|
470
470
|
### Pre-release checks
|
|
471
471
|
|
|
472
472
|
- Script: `exe/kettle-gha-sha-pins` (run as `kettle-gha-sha-pins`)
|
|
473
|
+
- New projects should install `kettle-gha-pins` and run `kettle-gha-pins`
|
|
474
|
+
directly; this `kettle-dev` command remains as a compatibility wrapper.
|
|
473
475
|
- Purpose: Validate and optionally update GitHub Actions `uses:` refs to pinned
|
|
474
476
|
SHAs and current allowed release versions.
|
|
475
477
|
- Usage:
|
|
@@ -889,7 +891,7 @@ Thanks for RTFM. ☺️
|
|
|
889
891
|
[📌gitmoji]: https://gitmoji.dev
|
|
890
892
|
[📌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
893
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
892
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.
|
|
894
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.104-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
893
895
|
[🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
|
|
894
896
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
895
897
|
[📄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))
|
data/exe/kettle-gha-sha-pins
CHANGED
|
@@ -3,38 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
# vim: set syntax=ruby
|
|
5
5
|
|
|
6
|
-
$stdout.sync = true
|
|
7
|
-
$stderr.sync = true
|
|
8
|
-
|
|
9
|
-
# Do not rely on Bundler; allow running in repos that do not depend on kettle-dev
|
|
10
|
-
begin
|
|
11
|
-
require "rubygems"
|
|
12
|
-
rescue LoadError
|
|
13
|
-
# Older Rubies always have rubygems; continue anyway
|
|
14
|
-
end
|
|
15
|
-
|
|
16
6
|
script_basename = File.basename(__FILE__)
|
|
17
7
|
|
|
18
8
|
begin
|
|
19
|
-
|
|
20
|
-
rescue LoadError
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
require "kettle/dev"
|
|
25
|
-
rescue LoadError => e
|
|
26
|
-
warn("#{script_basename}: could not load dependency: #{e.class}: #{e.message}")
|
|
27
|
-
warn("Hint: Install the kettle-dev gem (`gem install kettle-dev`) or add it to your Gemfile. Bundler is not required for this script.")
|
|
28
|
-
exit(1)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
begin
|
|
33
|
-
cli = Kettle::Dev::GhaShaPinsCLI.new(ARGV)
|
|
34
|
-
status = cli.run!
|
|
35
|
-
Kettle::Dev::ExitAdapter.exit(status)
|
|
36
|
-
rescue => e
|
|
37
|
-
warn("#{script_basename}: unexpected error: #{e.class}: #{e.message}")
|
|
38
|
-
warn(e.backtrace.join("\n"))
|
|
39
|
-
Kettle::Dev::ExitAdapter.exit(1)
|
|
9
|
+
Kernel.exec(Gem.ruby, Gem.bin_path("kettle-gha-pins", "kettle-gha-pins"), *ARGV)
|
|
10
|
+
rescue Gem::Exception, LoadError => e
|
|
11
|
+
warn("#{script_basename}: could not load kettle-gha-pins executable: #{e.class}: #{e.message}")
|
|
12
|
+
warn("Hint: Install the kettle-gha-pins gem (`gem install kettle-gha-pins`) or add it to your Gemfile.")
|
|
13
|
+
exit(1)
|
|
40
14
|
end
|
|
@@ -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
|