kettle-family 1.3.26 → 1.3.28

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cd05963542f86f54bc825842b8f73649a7520e61ddc695c505a6d19b3897581
4
- data.tar.gz: c4fc9a81de19c42aa0265fa04d255dc4f40ddcd5485aff3eec57b44647a26ddd
3
+ metadata.gz: 367d63bb92d37a073b9f7bfd89c81dd888abc3096ea0f40a38a84420676baa1b
4
+ data.tar.gz: f90a8ff1e68e5906b016813c2b7f9b1bb863e22df3a217ac18aac97820b05b14
5
5
  SHA512:
6
- metadata.gz: 97f87951b90ef59a674a55678be2af49d853f874d221297f3dd8661311400997f5430b9dd9b9e4ce88b32c543baf0d60977b975602a2d01c54f3c0217442c495
7
- data.tar.gz: d25120f0322dc957334262f218c07ad8be84669d3632ddcc33aecc7e4f9217407246489b3bcca24aae5e26a43618bc8be888fbba0a3278b8920f6985468be242
6
+ metadata.gz: 2475a71506fa039212ababd06370f8fe2472147324f9d928e33fe5857e88bdf370fb63b24ffa70f08fe0d0d0bc632ac227bc146878160b26eae6d64f958010a3
7
+ data.tar.gz: 7bb3b6df1a83fed732d8b6dcf43004efb5f1a00ff21dbd51ba084b7336292d4d1b6a3a2ffdbad5504e6a007265ec23fd8623fd9972c5a5cdb21aea994837f43c
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,30 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.3.28] - 2026-10-21
34
+
35
+ - TAG: [v1.3.28][1.3.28t]
36
+ - COVERAGE: 93.04% -- 7461/8019 lines in 44 files
37
+ - BRANCH COVERAGE: 77.50% -- 2994/3863 branches in 44 files
38
+ - 37.45% documented
39
+
40
+ ### Fixed
41
+
42
+ - Order the release progress pane by wave plan (execution order), then queueing order within each wave, instead of raw member order
43
+
44
+ ## [1.3.27] - 2026-10-20
45
+
46
+ - TAG: [v1.3.27][1.3.27t]
47
+ - COVERAGE: 93.04% -- 7460/8018 lines in 44 files
48
+ - BRANCH COVERAGE: 77.50% -- 2994/3863 branches in 44 files
49
+ - 37.45% documented
50
+
51
+ ### Fixed
52
+
53
+ - Preserve branch identity in template reports and exact-branch resume hints, and support MEMBER@BRANCH selection and resume targets.
54
+
55
+ - Retry template preparation once when Bundler reports a cached gemspec evaluating to nil.
56
+
33
57
  ## [1.3.26] - 2026-10-20
34
58
 
35
59
  - TAG: [v1.3.26][1.3.26t]
@@ -3165,7 +3189,11 @@ Please file a bug if you notice a violation of semantic versioning.
3165
3189
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
3166
3190
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
3167
3191
 
3168
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.3.26...HEAD
3192
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.3.28...HEAD
3193
+ [1.3.28]: https://github.com/kettle-dev/kettle-family/compare/v1.3.27...v1.3.28
3194
+ [1.3.28t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.28
3195
+ [1.3.27]: https://github.com/kettle-dev/kettle-family/compare/v1.3.26...v1.3.27
3196
+ [1.3.27t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.27
3169
3197
  [1.3.26]: https://github.com/kettle-dev/kettle-family/compare/v1.3.25...v1.3.26
3170
3198
  [1.3.26t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.26
3171
3199
  [1.3.25]: https://github.com/kettle-dev/kettle-family/compare/v1.3.24...v1.3.25
data/README.md CHANGED
@@ -1225,7 +1225,7 @@ Thanks for RTFM. ☺️
1225
1225
  [📌gitmoji]: https://gitmoji.dev
1226
1226
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1227
1227
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1228
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-7.956-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1228
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-8.019-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1229
1229
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
1230
1230
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1231
1231
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -49,7 +49,7 @@ module Kettle
49
49
 
50
50
  module SelectionOptions
51
51
  def self.included(base)
52
- base.option :only, value: {type: String, usage: "MEMBERS"}, desc: "Select comma-separated members, or release-state tokens: unreleased/unrel, prepared/prep, pending/pend, bump"
52
+ base.option :only, value: {type: String, usage: "MEMBERS"}, desc: "Select comma-separated members or branch targets (MEMBER@BRANCH), or release-state tokens: unreleased/unrel, prepared/prep, pending/pend, bump"
53
53
  base.option :exclude, value: {type: String, usage: "MEMBERS"}, desc: "Exclude comma-separated members"
54
54
  base.option :start_at, long: "--start-at", value: {type: String, usage: "MEMBER[@BRANCH]"}, desc: "Select from member through the end of order"
55
55
  end
@@ -823,7 +823,7 @@ module Kettle
823
823
  def build_report(command, options)
824
824
  config = Config.load(root: options[:root], path: options[:config])
825
825
  start_at = parse_start_at(options[:start_at])
826
- Selection.validate_positional_start_at!(command, start_at.member)
826
+ Selection.validate_positional_start_at!(command, start_at.member, branch: start_at.branch)
827
827
  effective_only = default_only_filter(command: command, only: options[:only])
828
828
  discovery = Discovery.new(
829
829
  config: config,
@@ -841,6 +841,7 @@ module Kettle
841
841
  Orderer.new(members: members, mode: config.order_mode, hints: config.order_hints).ordered(allow_cycles: command == "release-state")
842
842
  end
843
843
  state_event_tape = release_state_event_tape(command: command, config: config, options: options)
844
+ branch_selection = template_branch_selection(command: command, config: config, members: ordered, only: effective_only)
844
845
  Selection.validate_release_state_only_filter!(effective_only)
845
846
  release_state_results = release_state_results_for_selection(
846
847
  command: command,
@@ -855,6 +856,7 @@ module Kettle
855
856
  members: ordered,
856
857
  release_state_results: release_state_results
857
858
  ).apply(only: effective_only, exclude: options[:exclude], start_at: start_at.member)
859
+ options = options.merge(template_branch_selection: branch_selection)
858
860
  result_members = selected
859
861
  display_members = display_members_for(command: command, config: config, members: ordered, selected_members: selected)
860
862
  display_selected_members = display_members_for(command: command, config: config, members: selected, selected_members: selected)
@@ -889,7 +891,7 @@ module Kettle
889
891
  config_path: config.path,
890
892
  branch_lanes: config.branch_lanes,
891
893
  release_target_branches: release_target_branches(command: command, config: config, start_at: start_at),
892
- member_release_target_branches: member_release_target_branches(command: command, members: selected, config: config, start_at: start_at),
894
+ member_release_target_branches: member_release_target_branches(command: command, members: selected, config: config, start_at: start_at, branch_selection: branch_selection),
893
895
  release_mode: release_mode(command: command, options: options),
894
896
  release_resume_arguments: release_resume_arguments(command: command, options: options),
895
897
  command: command,
@@ -955,7 +957,32 @@ module Kettle
955
957
  names = only.to_s.split(",").map(&:strip).reject(&:empty?)
956
958
  return nil if names.empty? || names.any? { |name| Selection.status_token?(name) }
957
959
 
958
- names
960
+ Selection.member_names(only)
961
+ end
962
+
963
+ def template_branch_selection(command:, config:, members:, only:)
964
+ selectors = Selection.branch_selectors(only)
965
+ unless command == "template"
966
+ raise Error, "MEMBER@BRANCH selectors are only supported for template" unless selectors.empty?
967
+
968
+ return {}
969
+ end
970
+ return {} if selectors.empty?
971
+
972
+ by_name = members.to_h { |member| [member.name, member] }
973
+ selectors.group_by(&:first).transform_values do |member_selectors|
974
+ member_name = member_selectors.first.first
975
+ member = by_name[member_name]
976
+ member_config = member && member_release_config(member: member, config: config)
977
+ branches = member_config && BranchTargetConfig.branch_targets_for(command, member_config.release_target_branches)
978
+ raise Error, "member #{member_name.inspect} has no template branch targets" unless branches
979
+
980
+ selected_branches = member_selectors.map(&:last).uniq
981
+ unknown = selected_branches - branches
982
+ raise Error, "unknown branch target(s) for #{member_name}: #{unknown.join(", ")}" unless unknown.empty?
983
+
984
+ selected_branches
985
+ end
959
986
  end
960
987
 
961
988
  def display_members_for(command:, config:, members:, selected_members:)
@@ -1031,6 +1058,7 @@ module Kettle
1031
1058
  bex_args: options[:bex_args],
1032
1059
  start_member: start_at.member,
1033
1060
  start_branch: start_at.branch,
1061
+ template_branch_selection: options[:template_branch_selection],
1034
1062
  event_tape: state_event_tape,
1035
1063
  release_state_results: release_state_results
1036
1064
  ).results
@@ -1560,10 +1588,18 @@ module Kettle
1560
1588
  slice_branch_targets(branch_targets, start_at.branch)
1561
1589
  end
1562
1590
 
1563
- def member_release_target_branches(command:, members:, config:, start_at:)
1591
+ def member_release_target_branches(command:, members:, config:, start_at:, branch_selection: {})
1564
1592
  members.each_with_object({}) do |member, memo|
1565
1593
  member_config = member_release_config(member: member, config: config)
1566
- memo[member.name] = member_branch_targets(command: command, member: member, member_config: member_config, start_at: start_at) if member_config
1594
+ next unless member_config
1595
+
1596
+ branches = if command == "template" && branch_selection.key?(member.name)
1597
+ branch_selection.fetch(member.name)
1598
+ else
1599
+ member_branch_targets(command: command, member: member, member_config: member_config, start_at: start_at)
1600
+ end
1601
+ branches = slice_branch_targets(branches, start_at.branch) if command == "template" && start_at.branch && start_at.member == member.name
1602
+ memo[member.name] = branches
1567
1603
  end
1568
1604
  end
1569
1605
 
@@ -122,7 +122,7 @@ module Kettle
122
122
 
123
123
  lines << "results:"
124
124
  visible_results.each do |result|
125
- lines << " #{result_state(result)} #{result.member_name} #{result.phase} #{result.reason || ""}".rstrip
125
+ lines << " #{result_state(result)} #{result_identity(result)} #{result.phase} #{result.reason || ""}".rstrip
126
126
  append_result_stdout(lines, result)
127
127
  append_indented_output(lines, result.stderr) if !result.ok? && !result.stderr.to_s.empty?
128
128
  resume_hint = resume_hint_for(result)
@@ -436,20 +436,39 @@ module Kettle
436
436
  end
437
437
 
438
438
  def selected_names
439
- selected_members.map(&:name)
439
+ return selected_members.map(&:name) unless branch_stack_template?
440
+
441
+ selected_members.flat_map do |member|
442
+ branches = member_release_target_branches[member.name]
443
+ branches ? branches.map { |branch| "#{member.name}@#{branch}" } : [member.name]
444
+ end
440
445
  end
441
446
 
442
447
  def selected_member_results
443
448
  return {} unless member_result_command?
444
449
 
450
+ selected_identities = selected_names
445
451
  built = visible_results.each_with_object(Hash.new { |hash, key| hash[key] = [] }) do |result, memo|
446
- next unless selected_names.include?(result.member_name)
452
+ identity = result_identity(result)
453
+ next unless selected_identities.include?(identity)
447
454
 
448
- memo[result.member_name] << result
455
+ memo[identity] << result
449
456
  end
450
457
  built.sort.to_h
451
458
  end
452
459
 
460
+ def result_identity(result)
461
+ if branch_stack_template? && result.branch && member_release_target_branches.fetch(result.member_name, []).include?(result.branch)
462
+ "#{result.member_name}@#{result.branch}"
463
+ else
464
+ result.member_name
465
+ end
466
+ end
467
+
468
+ def branch_stack_template?
469
+ command == "template" && !member_release_target_branches.empty?
470
+ end
471
+
453
472
  def summary_succeeded
454
473
  selected_member_results.filter_map do |member_name, member_results|
455
474
  next if member_results.empty?
@@ -479,7 +498,7 @@ module Kettle
479
498
  # Alphabetical summary lists, regardless of parallel completion order.
480
499
  visible_results.reject(&:ok?).sort_by.with_index { |result, index| [result.member_name, index] }.map do |result|
481
500
  {
482
- "member" => result.member_name,
501
+ "member" => result_identity(result),
483
502
  "phase" => result.phase,
484
503
  "reason" => result.reason || "command failed"
485
504
  }
@@ -511,9 +530,9 @@ module Kettle
511
530
 
512
531
  def summary_ran_member_names
513
532
  if command == "template"
514
- failed = visible_results.reject(&:ok?).map(&:member_name)
515
- templated = selected_member_results.filter_map do |member_name, member_results|
516
- member_name if member_results.any? { |result| result.phase == "template" }
533
+ failed = visible_results.reject(&:ok?).map { |result| result_identity(result) }
534
+ templated = selected_member_results.filter_map do |identity, member_results|
535
+ identity if member_results.any? { |result| result.phase == "template" }
517
536
  end
518
537
  return (failed + templated).uniq
519
538
  end
@@ -778,7 +797,7 @@ module Kettle
778
797
  return "kettle-family #{command}" if family_root_phase?(result.phase)
779
798
  # A positional --start-at would silently drop pending members that are
780
799
  # ordered ahead of this one, so wave-dispatched commands resume by name.
781
- return "kettle-family #{command} --only #{result.member_name}" if non_positional_dispatch?
800
+ return "kettle-family #{command} --only #{result_identity(result)}" if non_positional_dispatch?
782
801
 
783
802
  "kettle-family #{command} --start-at #{result.member_name}"
784
803
  end
@@ -41,13 +41,18 @@ module Kettle
41
41
  # than letting it silently drop members. Mirrors the class-method validation
42
42
  # convention used by validate_release_state_only_filter! so callers in the CLI
43
43
  # do not have to know which commands are affected.
44
- def self.validate_positional_start_at!(command, start_at)
44
+ def self.validate_positional_start_at!(command, start_at, branch: nil)
45
45
  return if start_at.nil? || start_at.to_s.empty?
46
46
  return unless non_positional_dispatch?(command)
47
+ return if command == "template" && !branch.to_s.empty?
47
48
 
49
+ detail = if command == "template"
50
+ "Use --only #{start_at} (or the prior report's retry hint), or MEMBER@BRANCH for a branch-stack resume."
51
+ else
52
+ "Use --only #{start_at} (or the resume hint from the previous report) instead."
53
+ end
48
54
  raise Error, "--start-at is not supported for #{command}: members are dispatched in dependency " \
49
- "waves, so a positional resume would silently skip members that never ran. " \
50
- "Use --only #{start_at} (or the resume hint from the previous report) instead."
55
+ "waves, so a positional resume would silently skip members that never ran. #{detail}"
51
56
  end
52
57
 
53
58
  def self.status_tokens
@@ -73,6 +78,20 @@ module Kettle
73
78
  end.map(&:branch).compact.uniq
74
79
  end
75
80
 
81
+ def self.member_names(only)
82
+ Array(only.to_s.split(",").map(&:strip).reject(&:empty?)).map { |selector| selector.split("@", 2).first }
83
+ end
84
+
85
+ def self.branch_selectors(only)
86
+ only.to_s.split(",").map(&:strip).reject(&:empty?).filter_map do |selector|
87
+ member_name, branch = selector.split("@", 2)
88
+ next unless branch
89
+ raise Error, "invalid branch selector #{selector.inspect}; expected MEMBER@BRANCH" if member_name.empty? || branch.empty?
90
+
91
+ [member_name, branch]
92
+ end
93
+ end
94
+
76
95
  def self.validate_release_state_only_filter!(only)
77
96
  names = only.to_s.split(",").map(&:strip).reject(&:empty?)
78
97
  status_tokens = names.select { |name| status_token?(name) }
@@ -112,9 +131,10 @@ module Kettle
112
131
  return select_release_state_status(selected, status_tokens)
113
132
  end
114
133
 
115
- unknown = names - members.map(&:name)
134
+ unknown = self.class.member_names(only) - members.map(&:name)
116
135
  raise Error, "unknown member(s): #{unknown.join(", ")}" unless unknown.empty?
117
136
 
137
+ names = self.class.member_names(only)
118
138
  selected.select { |candidate| names.include?(candidate.name) }
119
139
  end
120
140
 
@@ -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.26"
8
+ VERSION = "1.3.28"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
@@ -107,8 +107,9 @@ module Kettle
107
107
  RUBY
108
108
  REGISTRY_WAIT_ATTEMPTS = 15
109
109
  REGISTRY_WAIT_INTERVAL_SECONDS = 15
110
+ TEMPLATE_GEMSPEC_RETRY_DELAY_SECONDS = 0.25
110
111
 
111
- def initialize(command:, config:, members:, family_members: nil, execute: false, accept: true, commit: true, allow_dirty: false, autostash: true, template_cleanup: true, publish: false, push: false, tag: false, start_step: nil, skip_steps: nil, fast_recovery: nil, fast_recovery_members: nil, skip_ci: false, skip_changelog: false, skip_appraisals: false, local_ci: false, continue_ci_failures: false, ci_workflows: nil, skip_bundle_audit: false, skip_remotes: nil, required_remotes: nil, auto_dependency_floors: nil, validate_ci_bundles: nil, gha_sha_pins_upgrade: "patch", gha_sha_pins_check: false, gha_sha_pins_ttl_days: nil, env_overrides: {}, debug: false, verbose: false, gem_signing_password: nil, secrets_provider: nil, jobs: nil, progress_io: nil, reset_target: nil, bup_args: [], bex_args: [], start_member: nil, start_branch: nil, release_state_results: nil, event_tape: nil, **options)
112
+ def initialize(command:, config:, members:, family_members: nil, execute: false, accept: true, commit: true, allow_dirty: false, autostash: true, template_cleanup: true, publish: false, push: false, tag: false, start_step: nil, skip_steps: nil, fast_recovery: nil, fast_recovery_members: nil, skip_ci: false, skip_changelog: false, skip_appraisals: false, local_ci: false, continue_ci_failures: false, ci_workflows: nil, skip_bundle_audit: false, skip_remotes: nil, required_remotes: nil, auto_dependency_floors: nil, validate_ci_bundles: nil, gha_sha_pins_upgrade: "patch", gha_sha_pins_check: false, gha_sha_pins_ttl_days: nil, env_overrides: {}, debug: false, verbose: false, gem_signing_password: nil, secrets_provider: nil, jobs: nil, progress_io: nil, reset_target: nil, bup_args: [], bex_args: [], start_member: nil, start_branch: nil, template_branch_selection: {}, release_state_results: nil, event_tape: nil, **options)
112
113
  @command = command
113
114
  @config = config
114
115
  @members = members
@@ -162,6 +163,7 @@ module Kettle
162
163
  @bex_args = bex_args
163
164
  @start_member = start_member
164
165
  @start_branch = start_branch
166
+ @template_branch_selection = template_branch_selection
165
167
  @release_state_results = Array(release_state_results)
166
168
  @event_tape = event_tape
167
169
  @template_commit_mutex = Mutex.new
@@ -1634,7 +1636,10 @@ module Kettle
1634
1636
  # linked worktrees avoids repeatedly switching the primary checkout and
1635
1637
  # allows the branch stack to use the requested template worker budget.
1636
1638
  def template_branch_worktree_results(member:, member_config:)
1637
- branches = BranchTargetConfig.branch_targets_for(command, member_config.release_target_branches)
1639
+ branches = @template_branch_selection.fetch(member.name) do
1640
+ BranchTargetConfig.branch_targets_for(command, member_config.release_target_branches)
1641
+ end
1642
+ branches = slice_branch_targets(branches, start_branch) if start_member == member.name && start_branch
1638
1643
  return [] if branches.empty?
1639
1644
 
1640
1645
  entries = []
@@ -4870,15 +4875,18 @@ module Kettle
4870
4875
  end
4871
4876
 
4872
4877
  def start_release_progress(release_members)
4873
- wave_numbers = release_waves(release_members).each_with_index.flat_map do |wave, index|
4878
+ waves = release_waves(release_members)
4879
+ wave_numbers = waves.each_with_index.flat_map do |wave, index|
4874
4880
  wave.map { |member| [member.name, index + 1] }
4875
4881
  end.to_h
4882
+ # The pane is a schedule view: list members in execution order (wave
4883
+ # plan order, queueing order within each wave), not raw member order.
4876
4884
  progress = WorkflowProgress.new(
4877
4885
  io: progress_io,
4878
4886
  label: release_progress_label,
4879
4887
  total: release_members.length,
4880
4888
  jobs: release_jobs(release_members),
4881
- members: release_members,
4889
+ members: waves.flatten,
4882
4890
  waves: wave_numbers
4883
4891
  )
4884
4892
  progress.start
@@ -5595,6 +5603,13 @@ module Kettle
5595
5603
  commit_normalized_lockfiles(branch_members: [member], runner: runner, memo: memo, reason: "reset", force: true)
5596
5604
  end
5597
5605
 
5606
+ def transient_cached_gemspec_failure?(result)
5607
+ return false unless execute && result && !result.ok?
5608
+
5609
+ output = [result.stdout, result.stderr].join("\n")
5610
+ output.include?("Bundler::GemspecError") && output.match?(/isn't a Gem::Specification \(NilClass instead\)/)
5611
+ end
5612
+
5598
5613
  def recoverable_bundle_failure?(result)
5599
5614
  return false unless execute && !result.ok?
5600
5615
 
@@ -5794,6 +5809,19 @@ module Kettle
5794
5809
  command: template_prepare_command(member),
5795
5810
  env: template_prepare_env(wave_jobs: wave_jobs, member: member)
5796
5811
  )
5812
+ if transient_cached_gemspec_failure?(result)
5813
+ sleep(TEMPLATE_GEMSPEC_RETRY_DELAY_SECONDS)
5814
+ retry_result = runner.call(
5815
+ member: member,
5816
+ phase: "prepare_template_dependencies_retry",
5817
+ command: template_prepare_command(member),
5818
+ env: template_prepare_env(wave_jobs: wave_jobs, member: member)
5819
+ )
5820
+ unless retry_result.ok?
5821
+ retry_result.stderr = [result.stderr, "Initial attempt failed with a transient cached-gemspec error.", retry_result.stderr].compact.reject(&:empty?).join("\n")
5822
+ end
5823
+ result = retry_result
5824
+ end
5797
5825
  if recoverable_bundle_failure?(result)
5798
5826
  recover_template_lockfiles(
5799
5827
  member: member,
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.26
4
+ version: 1.3.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -134,7 +134,7 @@ dependencies:
134
134
  version: '3.1'
135
135
  - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: 3.1.19
137
+ version: 3.1.20
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
@@ -144,7 +144,7 @@ dependencies:
144
144
  version: '3.1'
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
- version: 3.1.19
147
+ version: 3.1.20
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: kettle-gha-pins
150
150
  requirement: !ruby/object:Gem::Requirement
@@ -567,10 +567,10 @@ licenses:
567
567
  - AGPL-3.0-only
568
568
  metadata:
569
569
  homepage_uri: https://kettle-family.galtzo.com
570
- source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.3.26
571
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.3.26/CHANGELOG.md
570
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.3.28
571
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.3.28/CHANGELOG.md
572
572
  bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
573
- documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.3.26
573
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.3.28
574
574
  funding_uri: https://github.com/sponsors/pboling
575
575
  wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
576
576
  news_uri: https://www.railsbling.com/tags/kettle-family
metadata.gz.sig CHANGED
Binary file