kettle-family 1.3.3 → 1.3.4
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 +20 -1
- data/README.md +7 -1
- data/lib/kettle/family/cli.rb +29 -2
- data/lib/kettle/family/release_state_check.rb +60 -23
- data/lib/kettle/family/report.rb +1 -0
- data/lib/kettle/family/version.rb +1 -1
- data/lib/kettle/family/workflow.rb +7 -7
- data.tar.gz.sig +0 -0
- metadata +6 -6
- 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: 99e6506531c29efe6259ee3f592eb50d654eeef9f7074a1179f4f61960d7efdd
|
|
4
|
+
data.tar.gz: d3424e4481d1ced32dbb89228de517e3a0adf30a099883879c16fbb9f6feec8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfe9f450d1c65671d3599bfe3625952dc7106cfbfe896960bc236d0df04c033dd73116a94b49b5dba82502022ff503339e7a1457ff6c507888df0736489b5dd7
|
|
7
|
+
data.tar.gz: 4fc7889e44bd08e673899b0f3ea040ecec5129e4b90ef2ef166f11c51de0e4a05c2066036a8a600bf9dc9e35fd495f95ac60f603799709ec08e0e74522f22ef8
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,23 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [1.3.4] - 2026-10-02
|
|
34
|
+
|
|
35
|
+
- TAG: [v1.3.4][1.3.4t]
|
|
36
|
+
- COVERAGE: 93.26% -- 6571/7046 lines in 37 files
|
|
37
|
+
- BRANCH COVERAGE: 77.70% -- 2666/3431 branches in 37 files
|
|
38
|
+
- 33.33% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- kettle-family installs the latest stable Bundler and updates family lockfiles with `update-bundler`.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Lock each repository's worktree registry across process setup, parallel branch probes, and cleanup to prevent intermittent Git worktree failures.
|
|
47
|
+
|
|
48
|
+
- Family reports now include results from the update-bundler command.
|
|
49
|
+
|
|
33
50
|
## [1.3.3] - 2026-09-28
|
|
34
51
|
|
|
35
52
|
- TAG: [v1.3.3][1.3.3t]
|
|
@@ -2830,7 +2847,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
2830
2847
|
- Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
|
|
2831
2848
|
- Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
|
|
2832
2849
|
|
|
2833
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.3.
|
|
2850
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.3.4...HEAD
|
|
2851
|
+
[1.3.4]: https://github.com/kettle-dev/kettle-family/compare/v1.3.3...v1.3.4
|
|
2852
|
+
[1.3.4t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.4
|
|
2834
2853
|
[1.3.3]: https://github.com/kettle-dev/kettle-family/compare/v1.3.2...v1.3.3
|
|
2835
2854
|
[1.3.3t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.3
|
|
2836
2855
|
[1.3.2]: https://github.com/kettle-dev/kettle-family/compare/v1.3.1...v1.3.2
|
data/README.md
CHANGED
|
@@ -510,6 +510,7 @@ The command names below are available from `kettle-family --help`:
|
|
|
510
510
|
| `gha-sha-pins` | Inspect or update GitHub Actions SHA pins. |
|
|
511
511
|
| `bup` | Run `bundle update --all`, or update a named dependency, at the family root and per member. |
|
|
512
512
|
| `bupb` | Run `bundle update --bundler` at the family root and per member. |
|
|
513
|
+
| `update-bundler` | Install the latest stable Bundler from RubyGems, then update family lockfiles. |
|
|
513
514
|
| `bex` | Run an arbitrary `bundle exec` command per member. |
|
|
514
515
|
| `install` | Build and install selected local family gems. |
|
|
515
516
|
| `bump` | Check, plan, or execute family version alignment. |
|
|
@@ -614,6 +615,11 @@ root-first order with `bundle update --bundler`. A root that is itself a member
|
|
|
614
615
|
is updated only once. A gem name may be passed to `bup` to update only that
|
|
615
616
|
dependency, for example `kettle-family bup --execute kettle-test`.
|
|
616
617
|
|
|
618
|
+
`update-bundler` installs the latest stable Bundler from `https://rubygems.org`
|
|
619
|
+
without enabling prereleases, then runs the same root-first lockfile update as
|
|
620
|
+
`bupb`. Family mise tasks select an installed stable Bundler explicitly to
|
|
621
|
+
start the command, so an installed prerelease cannot intercept startup.
|
|
622
|
+
|
|
617
623
|
Executed member updates commit successful lockfile changes by default. The
|
|
618
624
|
family-root lockfile is also validated and committed for monorepos, where the
|
|
619
625
|
root and members share one Git repository. A sibling-repository family root is
|
|
@@ -1186,7 +1192,7 @@ Thanks for RTFM. ☺️
|
|
|
1186
1192
|
[📌gitmoji]: https://gitmoji.dev
|
|
1187
1193
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
1188
1194
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
1189
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-7.
|
|
1195
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-7.046-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
1190
1196
|
[🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
|
|
1191
1197
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
1192
1198
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/lib/kettle/family/cli.rb
CHANGED
|
@@ -4,14 +4,15 @@ require "command_kit"
|
|
|
4
4
|
require "command_kit/commands"
|
|
5
5
|
require "fileutils"
|
|
6
6
|
require "optparse"
|
|
7
|
+
require "rubygems/dependency_installer"
|
|
7
8
|
|
|
8
9
|
module Kettle
|
|
9
10
|
module Family
|
|
10
11
|
class CLI < CommandKit::Command
|
|
11
12
|
include CommandKit::Commands
|
|
12
13
|
|
|
13
|
-
COMMANDS = %w[version mise-trust discover plan report metadata check clean-unreleased reconcile-releases reset test lint docs template gha-sha-pins bup bupb bex install bump bump-version add-changelog release push pull sync up branch-lanes release-state state].freeze
|
|
14
|
-
WORKFLOW_COMMANDS = %w[check reset test lint docs template gha-sha-pins bup bupb bex release push pull sync up].freeze
|
|
14
|
+
COMMANDS = %w[version mise-trust discover plan report metadata check clean-unreleased reconcile-releases reset test lint docs template gha-sha-pins bup bupb update-bundler bex install bump bump-version add-changelog release push pull sync up branch-lanes release-state state].freeze
|
|
15
|
+
WORKFLOW_COMMANDS = %w[check reset test lint docs template gha-sha-pins bup bupb update-bundler bex release push pull sync up].freeze
|
|
15
16
|
|
|
16
17
|
command_name "kettle-family"
|
|
17
18
|
usage "[options] COMMAND [ARGS...]"
|
|
@@ -434,6 +435,31 @@ module Kettle
|
|
|
434
435
|
description "Plan or execute bundle update --bundler."
|
|
435
436
|
end
|
|
436
437
|
|
|
438
|
+
class UpdateBundler < WorkflowCommand
|
|
439
|
+
command_name "update-bundler"
|
|
440
|
+
usage "[options]"
|
|
441
|
+
description "Install the latest stable Bundler, then update family lockfiles."
|
|
442
|
+
|
|
443
|
+
def run(*args)
|
|
444
|
+
unexpected_arguments!(args)
|
|
445
|
+
install_latest_stable_bundler if truthy_option?(:execute)
|
|
446
|
+
run_family("update-bundler")
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
private
|
|
450
|
+
|
|
451
|
+
def install_latest_stable_bundler
|
|
452
|
+
original_sources = Gem.sources.to_a
|
|
453
|
+
Gem.sources = ["https://rubygems.org"]
|
|
454
|
+
Gem::DependencyInstaller.new(domain: :remote, prerelease: false, document: []).install("bundler")
|
|
455
|
+
Gem::Specification.reset
|
|
456
|
+
rescue => error
|
|
457
|
+
raise Error, "could not install latest stable Bundler from RubyGems: #{error.message}"
|
|
458
|
+
ensure
|
|
459
|
+
Gem.sources = original_sources if original_sources
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
|
|
437
463
|
class Bex < WorkflowCommand
|
|
438
464
|
command_name "bex"
|
|
439
465
|
usage "[options] -- COMMAND [ARGS...]"
|
|
@@ -626,6 +652,7 @@ module Kettle
|
|
|
626
652
|
command GhaShaPins
|
|
627
653
|
command Bup
|
|
628
654
|
command Bupb
|
|
655
|
+
command UpdateBundler
|
|
629
656
|
command Bex
|
|
630
657
|
command Install
|
|
631
658
|
command Bump
|
|
@@ -23,6 +23,7 @@ module Kettle
|
|
|
23
23
|
].freeze
|
|
24
24
|
TRANSFER_CHANGELOG_TOTAL_UNSET = Object.new.freeze
|
|
25
25
|
CACHE_MISS = Object.new.freeze
|
|
26
|
+
WORKTREE_ADMIN_MUTEX = Mutex.new
|
|
26
27
|
|
|
27
28
|
def initialize(members:, config: nil, jobs: nil)
|
|
28
29
|
@members = members
|
|
@@ -57,21 +58,30 @@ module Kettle
|
|
|
57
58
|
def branch_results(event_handler: nil)
|
|
58
59
|
root = git_root
|
|
59
60
|
selected_names = members.map(&:name)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
with_branch_worktrees(root: root, branches: release_target_branches) do |entries|
|
|
62
|
+
parallel_map(entries) do |entry|
|
|
63
|
+
if entry[:error]
|
|
64
|
+
error_result(branch: entry[:branch], error: entry[:error])
|
|
65
|
+
else
|
|
66
|
+
branch_results_for_worktree(
|
|
67
|
+
branch: entry[:branch],
|
|
68
|
+
worktree_root: entry[:worktree_root],
|
|
69
|
+
selected_names: selected_names,
|
|
70
|
+
event_handler: event_handler
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
end.flatten
|
|
74
|
+
end
|
|
63
75
|
end
|
|
64
76
|
|
|
65
|
-
def
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
next normalize_shared_version_bump(results)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
parallel_map(branch_members) { |member| check_member(member, branch: branch, event_handler: event_handler) }
|
|
77
|
+
def branch_results_for_worktree(branch:, worktree_root:, selected_names:, event_handler:)
|
|
78
|
+
branch_members = discover_branch_members(worktree_root: worktree_root, selected_names: selected_names)
|
|
79
|
+
if shared_changelog?
|
|
80
|
+
results = parallel_map(branch_members) { |member| check_shared_changelog_member_or_local(member, branch: branch, event_handler: event_handler) }
|
|
81
|
+
return normalize_shared_version_bump(results)
|
|
74
82
|
end
|
|
83
|
+
|
|
84
|
+
parallel_map(branch_members) { |member| check_member(member, branch: branch, event_handler: event_handler) }
|
|
75
85
|
rescue Error => error
|
|
76
86
|
[error_result(branch: branch, error: error)]
|
|
77
87
|
end
|
|
@@ -826,25 +836,52 @@ module Kettle
|
|
|
826
836
|
File.realpath(stdout.strip)
|
|
827
837
|
end
|
|
828
838
|
|
|
829
|
-
def
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
839
|
+
def with_branch_worktrees(root:, branches:)
|
|
840
|
+
with_worktree_registry_lock(root: root) do
|
|
841
|
+
base = File.join(root, "tmp", "kettle-family-release-state")
|
|
842
|
+
FileUtils.mkdir_p(base)
|
|
843
|
+
entries = branches.map do |branch|
|
|
844
|
+
{branch: branch, worktree_root: File.join(base, "worktree-#{Process.pid}-#{SecureRandom.hex(8)}")}
|
|
845
|
+
end
|
|
846
|
+
entries.each do |entry|
|
|
847
|
+
add_branch_worktree(root: root, branch: entry[:branch], worktree_root: entry[:worktree_root])
|
|
848
|
+
rescue Error => error
|
|
849
|
+
entry[:error] = error
|
|
850
|
+
end
|
|
851
|
+
yield entries
|
|
852
|
+
ensure
|
|
853
|
+
entries&.reverse_each do |entry|
|
|
854
|
+
remove_branch_worktree(root: root, worktree_root: entry[:worktree_root])
|
|
855
|
+
end
|
|
856
|
+
end
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
def with_worktree_registry_lock(root:)
|
|
860
|
+
stdout, stderr, status = Open3.capture3("git", "rev-parse", "--git-common-dir", chdir: root)
|
|
861
|
+
raise Error, "could not determine git common directory for #{root}: #{stderr}" unless status.success?
|
|
862
|
+
|
|
863
|
+
lock_path = File.join(File.expand_path(stdout.strip, root), "kettle-family-worktree.lock")
|
|
864
|
+
File.open(lock_path, File::RDWR | File::CREAT, 0o600) do |lock_file|
|
|
865
|
+
lock_file.flock(File::LOCK_EX)
|
|
866
|
+
yield
|
|
867
|
+
ensure
|
|
868
|
+
lock_file&.flock(File::LOCK_UN)
|
|
869
|
+
end
|
|
837
870
|
end
|
|
838
871
|
|
|
839
872
|
def add_branch_worktree(root:, branch:, worktree_root:)
|
|
840
|
-
|
|
841
|
-
|
|
873
|
+
WORKTREE_ADMIN_MUTEX.synchronize do
|
|
874
|
+
_stdout, stderr, status = Open3.capture3("git", "worktree", "add", "--detach", worktree_root, branch, chdir: root)
|
|
875
|
+
raise Error, "could not add worktree for #{branch}: #{stderr}" unless status.success?
|
|
876
|
+
end
|
|
842
877
|
end
|
|
843
878
|
|
|
844
879
|
def remove_branch_worktree(root:, worktree_root:)
|
|
845
880
|
return unless worktree_root && Dir.exist?(worktree_root)
|
|
846
881
|
|
|
847
|
-
|
|
882
|
+
WORKTREE_ADMIN_MUTEX.synchronize do
|
|
883
|
+
Open3.capture3("git", "worktree", "remove", "--force", worktree_root, chdir: root)
|
|
884
|
+
end
|
|
848
885
|
end
|
|
849
886
|
|
|
850
887
|
def discover_branch_members(worktree_root:, selected_names:)
|
data/lib/kettle/family/report.rb
CHANGED
|
@@ -29,6 +29,7 @@ module Kettle
|
|
|
29
29
|
template
|
|
30
30
|
test
|
|
31
31
|
up
|
|
32
|
+
update-bundler
|
|
32
33
|
].freeze
|
|
33
34
|
|
|
34
35
|
attr_reader :family_name, :family_mode, :order_mode, :members, :selected_members, :config_path, :command, :results, :branch_lanes, :release_target_branches, :member_release_target_branches, :release_mode, :release_resume_arguments, :warnings, :event_log_dirs
|
|
@@ -5,7 +5,7 @@ module Kettle
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = "1.3.
|
|
8
|
+
VERSION = "1.3.4"
|
|
9
9
|
end
|
|
10
10
|
# Current gem version exposed at the traditional constant location.
|
|
11
11
|
VERSION = Version::VERSION # Traditional Constant Location
|
|
@@ -574,7 +574,7 @@ module Kettle
|
|
|
574
574
|
|
|
575
575
|
runner = CommandRunner.new(execute: execute, accept: accept)
|
|
576
576
|
results = []
|
|
577
|
-
update_family_root_bundle(runner: runner, memo: results) if %w[bup bupb].include?(command)
|
|
577
|
+
update_family_root_bundle(runner: runner, memo: results) if %w[bup bupb update-bundler].include?(command)
|
|
578
578
|
return results unless results.all?(&:ok?)
|
|
579
579
|
|
|
580
580
|
if command == "gha-sha-pins" && execute
|
|
@@ -607,10 +607,10 @@ module Kettle
|
|
|
607
607
|
|
|
608
608
|
normalize_lockfiles(member: member, runner: runner, memo: memo, phase: "normalize_lockfiles") if command == "template"
|
|
609
609
|
commit_gha_sha_pins(member: member, runner: runner, memo: memo) if command == "gha-sha-pins"
|
|
610
|
-
if command
|
|
610
|
+
if %w[bupb update-bundler].include?(command)
|
|
611
611
|
bupb_appraisal_results(member: member, runner: runner, memo: memo)
|
|
612
612
|
end
|
|
613
|
-
if %w[bup bupb].include?(command) && memo.last&.ok? && validate_bundle_update_lockfile(member: member, memo: memo)
|
|
613
|
+
if %w[bup bupb update-bundler].include?(command) && memo.last&.ok? && validate_bundle_update_lockfile(member: member, memo: memo)
|
|
614
614
|
commit_bundle_update(member: member, runner: runner, memo: memo)
|
|
615
615
|
end
|
|
616
616
|
commit_bex_changes(member: member, runner: runner, memo: memo) if command == "bex"
|
|
@@ -4083,7 +4083,7 @@ module Kettle
|
|
|
4083
4083
|
return gha_sha_pins_command(command_text: command_text)
|
|
4084
4084
|
end
|
|
4085
4085
|
return bup_command if command == "bup"
|
|
4086
|
-
return bupb_command if command
|
|
4086
|
+
return bupb_command if %w[bupb update-bundler].include?(command)
|
|
4087
4087
|
return bex_command if command == "bex"
|
|
4088
4088
|
|
|
4089
4089
|
command_for(command)
|
|
@@ -4108,11 +4108,11 @@ module Kettle
|
|
|
4108
4108
|
|
|
4109
4109
|
def stable_bundler_version
|
|
4110
4110
|
active_version = Gem.loaded_specs["bundler"]&.version
|
|
4111
|
-
return active_version if active_version && !active_version.prerelease?
|
|
4112
|
-
|
|
4113
4111
|
Gem::Specification
|
|
4114
4112
|
.find_all_by_name("bundler")
|
|
4115
4113
|
.map(&:version)
|
|
4114
|
+
.push(active_version)
|
|
4115
|
+
.compact
|
|
4116
4116
|
.reject(&:prerelease?)
|
|
4117
4117
|
.max
|
|
4118
4118
|
end
|
|
@@ -4358,7 +4358,7 @@ module Kettle
|
|
|
4358
4358
|
end
|
|
4359
4359
|
|
|
4360
4360
|
def command_env
|
|
4361
|
-
return bundle_update_env if %w[bup bupb].include?(command)
|
|
4361
|
+
return bundle_update_env if %w[bup bupb update-bundler].include?(command)
|
|
4362
4362
|
|
|
4363
4363
|
workflow_env
|
|
4364
4364
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-family
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -94,7 +94,7 @@ dependencies:
|
|
|
94
94
|
version: '3.1'
|
|
95
95
|
- - ">="
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
|
-
version: 3.1.
|
|
97
|
+
version: 3.1.5
|
|
98
98
|
type: :runtime
|
|
99
99
|
prerelease: false
|
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -104,7 +104,7 @@ dependencies:
|
|
|
104
104
|
version: '3.1'
|
|
105
105
|
- - ">="
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
|
-
version: 3.1.
|
|
107
|
+
version: 3.1.5
|
|
108
108
|
- !ruby/object:Gem::Dependency
|
|
109
109
|
name: kettle-gha-pins
|
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -459,10 +459,10 @@ licenses:
|
|
|
459
459
|
- AGPL-3.0-only
|
|
460
460
|
metadata:
|
|
461
461
|
homepage_uri: https://kettle-family.galtzo.com
|
|
462
|
-
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.3.
|
|
463
|
-
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.3.
|
|
462
|
+
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.3.4
|
|
463
|
+
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.3.4/CHANGELOG.md
|
|
464
464
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
|
|
465
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.3.
|
|
465
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.3.4
|
|
466
466
|
funding_uri: https://github.com/sponsors/pboling
|
|
467
467
|
wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
|
|
468
468
|
news_uri: https://www.railsbling.com/tags/kettle-family
|
metadata.gz.sig
CHANGED
|
Binary file
|