kettle-family 1.2.16 → 1.2.17

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: 8b8259b472f99ca594e7956ac519a565fc7aa0fbab0ac70c27f04e23859aff81
4
- data.tar.gz: a07e5341f564dff2585318124c8967f20bda0fff30367d267ddcba6a4a758814
3
+ metadata.gz: cb71df81d320a71ba34e6f2f09233f8a02a59f84f266c3e55e92acbe6c35cae1
4
+ data.tar.gz: 0dd9fa2f1ef0f3ec59f4bbee09992245b03dc4fb8f991807d5b8eac70a817c3b
5
5
  SHA512:
6
- metadata.gz: 9b9cc51b230513a0c2e68429525ec18536079e9bbfd380add869fb141fa030d234a6a1768dfe80a5b54b73889b8272e730fc50594dae66bdc775d887415792fe
7
- data.tar.gz: ae21a58c95d2b3300fdf9c4b1f8c45b1698c32602038f2afcff5d836fa21949734acfdc525fe96d7aec05af080e1d1c80d81b498ffc51800d42f9c52e93fe681
6
+ metadata.gz: 2b81c2dc8313b89e2777a60fddadd2d459c8db4c5ba723f26aedb66eebec1d6e6fa91a7d4ebc57d9e040a87d1703b5cdb86758b256fb76e8e9621c999d1eeb19
7
+ data.tar.gz: afe0839807601723753b1e5c78849648a2af65bf19ee13b9a2fbe50e1e3e11d4980e5ed82a9d214f1bdddfacf299e1483c9c8d30884bb1daeb5406abbfeda5d1
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,21 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.2.17] - 2026-07-31
34
+
35
+ - TAG: [v1.2.17][1.2.17t]
36
+ - COVERAGE: 94.10% -- 4225/4490 lines in 28 files
37
+ - BRANCH COVERAGE: 76.58% -- 1658/2165 branches in 28 files
38
+ - 28.88% documented
39
+
40
+ ### Fixed
41
+
42
+ - Template branch-target workflows now recover a sole locally sourced
43
+ `Gemfile.lock` with the existing release-safe reset helper before checkout,
44
+ and retry a failed Bundler lock normalization once after recovery.
45
+ - Checksum-aware template lock normalization now upgrades Bundler and retries
46
+ once when the active Bundler rejects `--add-checksums`.
47
+
33
48
  ## [1.2.16] - 2026-07-31
34
49
 
35
50
  - TAG: [v1.2.16][1.2.16t]
@@ -1525,7 +1540,9 @@ Please file a bug if you notice a violation of semantic versioning.
1525
1540
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
1526
1541
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
1527
1542
 
1528
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.16...HEAD
1543
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.17...HEAD
1544
+ [1.2.17]: https://github.com/kettle-dev/kettle-family/compare/v1.2.16...v1.2.17
1545
+ [1.2.17t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.17
1529
1546
  [1.2.16]: https://github.com/kettle-dev/kettle-family/compare/v1.2.15...v1.2.16
1530
1547
  [1.2.16t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.16
1531
1548
  [1.2.15]: https://github.com/kettle-dev/kettle-family/compare/v1.2.14...v1.2.15
data/README.md CHANGED
@@ -819,7 +819,7 @@ Thanks for RTFM. ☺️
819
819
  [📌gitmoji]: https://gitmoji.dev
820
820
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
821
821
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
822
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.459-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
822
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.490-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
823
823
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
824
824
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
825
825
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -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.2.16"
8
+ VERSION = "1.2.17"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
@@ -151,13 +151,13 @@ module Kettle
151
151
  end
152
152
 
153
153
  preflight = branch_checkout_dirty_preflight_results
154
- return preflight unless preflight.empty?
154
+ return preflight if preflight.any? { |result| !result.ok? }
155
155
 
156
156
  prompt_for_gem_signing_password if command == "release" && execute && release_signing_prompt_required?
157
- return branch_target_results unless config.release_target_branches.empty?
158
- return member_local_branch_target_results if member_local_branch_targets?
157
+ return preflight + branch_target_results unless config.release_target_branches.empty?
158
+ return preflight + member_local_branch_target_results if member_local_branch_targets?
159
159
 
160
- current_branch_results(members)
160
+ preflight + current_branch_results(members)
161
161
  end
162
162
 
163
163
  private
@@ -509,14 +509,26 @@ module Kettle
509
509
  return [] if allow_dirty
510
510
  return [] unless branch_checkout_preflight_required?
511
511
 
512
- branch_checkout_preflight_members.filter_map do |member|
512
+ branch_checkout_preflight_members.each_with_object([]) do |member, results|
513
513
  dirty_paths = GitStatus.dirty_paths(member.root)
514
514
  next if dirty_paths.empty?
515
515
 
516
- branch_checkout_dirty_result(member, dirty_paths)
516
+ if recoverable_template_lockfile_dirt?(member, dirty_paths)
517
+ recover_template_lockfiles(member: member, runner: command_runner, memo: results, phase: "template_lockfile_recovery")
518
+ next if results.last&.ok? && GitStatus.dirty_paths(member.root).empty?
519
+ end
520
+
521
+ results << branch_checkout_dirty_result(member, GitStatus.dirty_paths(member.root))
517
522
  end
518
523
  end
519
524
 
525
+ def recoverable_template_lockfile_dirt?(member, dirty_paths)
526
+ return false unless command == "template" && config.normalize_lockfiles?
527
+ return false unless dirty_paths.length == 1 && dirty_paths.first.end_with?(" Gemfile.lock")
528
+
529
+ release_lockfile_has_local_path_remote?(member)
530
+ end
531
+
520
532
  def branch_checkout_preflight_required?
521
533
  !config.release_target_branches.empty? || member_local_branch_targets?
522
534
  end
@@ -1061,17 +1073,17 @@ module Kettle
1061
1073
  path.to_s
1062
1074
  end
1063
1075
 
1064
- def reset_gemfile_lock(member:, runner:, memo:)
1076
+ def reset_gemfile_lock(member:, runner:, memo:, phase: "reset_gemfile_lock", env: release_lockfile_env(member))
1065
1077
  result = runner.call(
1066
1078
  member: member,
1067
- phase: "reset_gemfile_lock",
1079
+ phase: phase,
1068
1080
  command: reset_gemfile_lock_command(member),
1069
- env: release_lockfile_env(member)
1081
+ env: env
1070
1082
  )
1071
1083
  memo << result
1072
1084
  return unless result.ok? && execute
1073
1085
 
1074
- validate_reset_gemfile_lock(member: member, memo: memo)
1086
+ validate_reset_gemfile_lock(member: member, memo: memo, phase: phase)
1075
1087
  end
1076
1088
 
1077
1089
  def reset_gemfile_lock_command(member)
@@ -1098,13 +1110,13 @@ module Kettle
1098
1110
  env_overrides["KETTLE_FAMILY_RESET_RUBY"].to_s.empty? ? RbConfig.ruby : env_overrides["KETTLE_FAMILY_RESET_RUBY"].to_s
1099
1111
  end
1100
1112
 
1101
- def validate_reset_gemfile_lock(member:, memo:)
1113
+ def validate_reset_gemfile_lock(member:, memo:, phase: "reset_gemfile_lock")
1102
1114
  diagnostics = reset_gemfile_lock_diagnostics(member)
1103
1115
  return if diagnostics.empty?
1104
1116
 
1105
1117
  memo << CommandResult.new(
1106
1118
  member.name,
1107
- "reset_gemfile_lock_readiness",
1119
+ "#{phase}_readiness",
1108
1120
  ["internal", "validate", "Gemfile.lock"],
1109
1121
  member.root,
1110
1122
  1,
@@ -2399,9 +2411,73 @@ module Kettle
2399
2411
  env: workflow_env
2400
2412
  )
2401
2413
  end
2414
+ if checksum_option_unsupported?(result)
2415
+ recovery = runner.call(
2416
+ member: member,
2417
+ phase: "#{phase}_bundler_recovery",
2418
+ command: %w[bundle update --bundler],
2419
+ env: workflow_env
2420
+ )
2421
+ memo << recovery
2422
+ return unless recovery.ok?
2423
+
2424
+ result = runner.call(
2425
+ member: member,
2426
+ phase: phase,
2427
+ command: normalize_lockfiles_command(member: member, phase: phase),
2428
+ env: workflow_env
2429
+ )
2430
+ end
2431
+ if template_lockfile_phase?(phase) && recoverable_bundle_failure?(result)
2432
+ recover_template_lockfiles(member: member, runner: runner, memo: memo, phase: "#{phase}_recovery")
2433
+ return unless memo.last&.ok?
2434
+
2435
+ result = runner.call(
2436
+ member: member,
2437
+ phase: phase,
2438
+ command: normalize_lockfiles_command(member: member, phase: phase),
2439
+ env: workflow_env
2440
+ )
2441
+ end
2402
2442
  memo << result
2403
2443
  end
2404
2444
 
2445
+ def recover_template_lockfiles(member:, runner:, memo:, phase:)
2446
+ reset_gemfile_lock(
2447
+ member: member,
2448
+ runner: runner,
2449
+ memo: memo,
2450
+ phase: phase,
2451
+ env: template_lockfile_recovery_env(member)
2452
+ )
2453
+ return unless memo.last&.ok?
2454
+
2455
+ commit_normalized_lockfiles(
2456
+ branch_members: [member],
2457
+ runner: runner,
2458
+ memo: memo,
2459
+ reason: "reset",
2460
+ force: true
2461
+ )
2462
+ end
2463
+
2464
+ def recoverable_bundle_failure?(result)
2465
+ return false unless execute && !result.ok?
2466
+
2467
+ output = [result.stdout, result.stderr].join("\n")
2468
+ output.match?(/Bundler::(?:GemNotFound|VersionConflict)|Could not (?:find|resolve) |already activated .* but your Gemfile requires/)
2469
+ end
2470
+
2471
+ def checksum_option_unsupported?(result)
2472
+ return false unless execute && !result.ok?
2473
+
2474
+ [result.stdout, result.stderr].join("\n").match?(/Unknown switches? .*--add-checksums/)
2475
+ end
2476
+
2477
+ def template_lockfile_recovery_env(member)
2478
+ release_lockfile_env(member).merge("K_JEM_TEMPLATING" => "false")
2479
+ end
2480
+
2405
2481
  def normalize_lockfiles_command(member:, phase:)
2406
2482
  configured = config.normalize_lockfiles_command
2407
2483
  return configured unless template_prepare_lockfiles_phase?(phase)
@@ -2461,6 +2537,10 @@ module Kettle
2461
2537
  command == "template" && phase == "prepare_lockfiles"
2462
2538
  end
2463
2539
 
2540
+ def template_lockfile_phase?(phase)
2541
+ command == "template" && %w[prepare_lockfiles normalize_lockfiles].include?(phase)
2542
+ end
2543
+
2464
2544
  def repair_checksum_mismatches(member, result)
2465
2545
  return false unless execute
2466
2546
  return false if result.ok?
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.2.16
4
+ version: 1.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -342,10 +342,10 @@ licenses:
342
342
  - AGPL-3.0-only
343
343
  metadata:
344
344
  homepage_uri: https://kettle-family.galtzo.com
345
- source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.16
346
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.16/CHANGELOG.md
345
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.17
346
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.17/CHANGELOG.md
347
347
  bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
348
- documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.16
348
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.17
349
349
  funding_uri: https://github.com/sponsors/pboling
350
350
  wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
351
351
  news_uri: https://www.railsbling.com/tags/kettle-family
metadata.gz.sig CHANGED
Binary file