kettle-family 1.2.48 → 1.2.49

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: 93c01e2b68636f1592c6d7db043f4b733a3eb755caabd0d87ae9ffcb9fcd83cc
4
- data.tar.gz: 04a4d9fe0ab9716ae4ef096d69430f36c6810ded657b550e10f01378cd7c6017
3
+ metadata.gz: 475a61fdf4beaeb027dd5bedecfaaaa17eedf2dde3aeff94aa50feacb0d61aa5
4
+ data.tar.gz: 5cf55f665b5faf6a553ba7405994d53f31b8e95d898cbe87bf7dfd3d06128aa4
5
5
  SHA512:
6
- metadata.gz: a099005db334b512abaac80df84c47f1965036fcb0ceea0fdbf14aa57786c34a38b1f2b2ad8df955ae5f14e2b716f4aa669d4556ae7178349179819d301c1262
7
- data.tar.gz: 55c04739530546e6f8e1775fffaa11729d2c6faf1380b7eedbf16a7407dd321e94fd89956d37ed16d6784a468d15c5bfdcc71c4ff194a603df06571defa4d9cb
6
+ metadata.gz: 17eff45b0b3c50ab7947f4c347af164f35469441dcbfbb3b90875424938ed3f0a818e00c7cedbed1f7a126340b6b256f8d63f36f699cb76dcb9b5f745a79a071
7
+ data.tar.gz: 65c047a1a85c9e28509e3f66dc0fc7fb074c31614c46d6b4970fe490675c57877f24d39243b58c2068f2c2b6f24525c63fb4e4d4589fa6acf2a5631d8aa404c8
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -20,6 +20,8 @@ Please file a bug if you notice a violation of semantic versioning.
20
20
 
21
21
  ### Added
22
22
 
23
+ - Add --skip-changelog to release orchestration while retaining pre-release gates and specs.
24
+
23
25
  ### Changed
24
26
 
25
27
  ### Deprecated
@@ -28,6 +30,22 @@ Please file a bug if you notice a violation of semantic versioning.
28
30
 
29
31
  ### Fixed
30
32
 
33
+ - Shared-version release state now keeps members already at the highest local target out of the per-member bump flag while retaining complete-family selection.
34
+
35
+ - Run shared monorepo changelog gates with the family-local dependency graph.
36
+
37
+ - Preserve active workspace roots during release lockfile readiness checks.
38
+
39
+ - Run release action-pin preflight outside member Bundler environments.
40
+
41
+ - Run family changelog phases with the installed kettle-changelog executable outside member Bundler environments.
42
+
43
+ - Defer dependency-floor lockfile refreshes until all selected sibling dependencies are published.
44
+
45
+ - Honor configured release waves for sequential monorepo releases.
46
+
47
+ - Fix family release planning to use standalone tool executables and preserve the monorepo local dependency root.
48
+
31
49
  ### Security
32
50
 
33
51
  ## [1.2.48] - 2026-08-10
data/README.md CHANGED
@@ -56,7 +56,7 @@ provider supplies them.
56
56
 
57
57
  ### Compatibility
58
58
 
59
- Compatible with MRI Ruby 4.0.0+, and concordant releases of JRuby, and TruffleRuby.
59
+ Compatible with MRI Ruby 4.0.0+.
60
60
  CI workflows and Appraisals are generated for MRI Ruby 4.0.0+.
61
61
  This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
62
62
  may be higher than the gem's runtime compatibility floor when legacy Rubies are
@@ -591,8 +591,7 @@ See [SECURITY.md][🔐security].
591
591
  ## 🤝 Contributing
592
592
 
593
593
  If you need some ideas of where to help, you could work on adding more code coverage,
594
- or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
595
- or use the gem and think about how it could be better.
594
+ check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
596
595
 
597
596
  We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
598
597
 
@@ -628,19 +627,6 @@ Made with [contributors-img][🖐contrib-rocks].
628
627
 
629
628
  Also see GitLab Contributors: [https://gitlab.com/kettle-dev/kettle-family/-/graphs/main][🚎contributors-gl]
630
629
 
631
- <details markdown="1">
632
- <summary>⭐️ Star History</summary>
633
-
634
- <a href="https://star-history.com/kettle-dev/kettle-family&Date">
635
- <picture>
636
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=kettle-dev/kettle-family&type=Date&theme=dark" />
637
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=kettle-dev/kettle-family&type=Date" />
638
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=kettle-dev/kettle-family&type=Date" />
639
- </picture>
640
- </a>
641
-
642
- </details>
643
-
644
630
  ## 📌 Versioning
645
631
 
646
632
  This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
@@ -160,6 +160,7 @@ module Kettle
160
160
  publish: false,
161
161
  release_start_step: nil,
162
162
  release_skip_steps: nil,
163
+ release_skip_changelog: false,
163
164
  release_local_ci: false,
164
165
  release_continue_ci_failures: false,
165
166
  release_ci_workflows: nil,
@@ -519,6 +520,7 @@ module Kettle
519
520
  end
520
521
  option :start_step, long: "--start-step", value: {type: Integer, usage: "N"}, desc: "Pass start_step=N through to kettle-release commands"
521
522
  option :skip_steps, long: "--skip-steps", value: {type: String, usage: "LIST"}, desc: "Pass skip_steps=LIST through to kettle-release commands"
523
+ option :skip_changelog, long: "--skip-changelog", desc: "Run pre-release gates and specs, but skip kettle-changelog"
522
524
  option :local_ci, long: "--local-ci", desc: "Pass --local-ci through to kettle-release commands"
523
525
  option :continue_ci_failures, long: "--continue-ci-failures", desc: "Set K_RELEASE_CI_CONTINUE=true for release commands"
524
526
  option :ci_workflows, long: "--ci-workflows", value: {type: String, usage: "LIST"}, desc: "Pass a comma-separated CI workflow monitor subset through to kettle-release commands"
@@ -543,6 +545,7 @@ module Kettle
543
545
  publish: truthy_option?(:publish),
544
546
  release_start_step: options[:start_step],
545
547
  release_skip_steps: options[:skip_steps],
548
+ release_skip_changelog: truthy_option?(:skip_changelog),
546
549
  release_local_ci: truthy_option?(:local_ci),
547
550
  release_continue_ci_failures: truthy_option?(:continue_ci_failures),
548
551
  release_ci_workflows: options[:ci_workflows],
@@ -779,6 +782,7 @@ module Kettle
779
782
  tag: options[:tag],
780
783
  start_step: options[:release_start_step],
781
784
  skip_steps: options[:release_skip_steps],
785
+ skip_changelog: options[:release_skip_changelog],
782
786
  local_ci: options[:release_local_ci],
783
787
  continue_ci_failures: options[:release_continue_ci_failures],
784
788
  ci_workflows: options[:release_ci_workflows],
@@ -760,9 +760,22 @@ module Kettle
760
760
  def normalize_shared_version_bump(results)
761
761
  return results unless results.any? { |result| result.ok? && result.state["bump_release_pending"] == true }
762
762
 
763
+ successful = results.select(&:ok?)
764
+ target_version = successful.filter_map { |result| parse_version(result.state["version"]) }.max
765
+ released_version = successful.filter_map { |result| parse_version(result.state["latest_released"]) }.max
766
+ target_already_bumped = target_version && released_version && target_version > released_version
767
+
763
768
  results.map do |result|
764
769
  next result unless result.ok?
765
770
 
771
+ state = result.state
772
+ version = parse_version(state["version"])
773
+ bump_pending = if target_already_bumped && version == target_version
774
+ false
775
+ else
776
+ state["bump_release_pending"] == true
777
+ end
778
+
766
779
  result.class.new(
767
780
  member_name: result.member_name,
768
781
  command: result.command,
@@ -772,13 +785,19 @@ module Kettle
772
785
  stdout: result.stdout,
773
786
  stderr: result.stderr,
774
787
  elapsed_seconds: result.elapsed_seconds,
775
- state: result.state.merge("bump_release_pending" => true),
788
+ state: state.merge("bump_release_pending" => bump_pending),
776
789
  reason: result.reason,
777
790
  branch: result.branch
778
791
  )
779
792
  end
780
793
  end
781
794
 
795
+ def parse_version(value)
796
+ Gem::Version.new(value.to_s) unless value.to_s.empty?
797
+ rescue ArgumentError
798
+ nil
799
+ end
800
+
782
801
  def git_root
783
802
  stdout, stderr, status = Open3.capture3("git", "rev-parse", "--show-toplevel", chdir: config.root)
784
803
  raise Error, "could not determine git root for #{config.root}: #{stderr}" unless status.success?
@@ -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.48"
8
+ VERSION = "1.2.49"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
@@ -102,7 +102,7 @@ module Kettle
102
102
  REGISTRY_WAIT_ATTEMPTS = 15
103
103
  REGISTRY_WAIT_INTERVAL_SECONDS = 15
104
104
 
105
- def initialize(command:, config:, members:, execute: false, accept: true, commit: true, allow_dirty: false, autostash: true, publish: false, push: false, tag: false, start_step: nil, skip_steps: nil, local_ci: false, continue_ci_failures: false, ci_workflows: nil, skip_bundle_audit: false, skip_remotes: nil, required_remotes: nil, auto_dependency_floors: 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, **options)
105
+ def initialize(command:, config:, members:, execute: false, accept: true, commit: true, allow_dirty: false, autostash: true, publish: false, push: false, tag: false, start_step: nil, skip_steps: nil, skip_changelog: 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, 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, **options)
106
106
  @command = command
107
107
  @config = config
108
108
  @members = members
@@ -116,6 +116,7 @@ module Kettle
116
116
  @tag = tag
117
117
  @start_step = start_step
118
118
  @skip_steps = skip_steps
119
+ @skip_changelog = !!skip_changelog
119
120
  @local_ci = local_ci
120
121
  @continue_ci_failures = continue_ci_failures
121
122
  @ci_workflows = validate_ci_workflows(ci_workflows)
@@ -184,7 +185,7 @@ module Kettle
184
185
  execute && release_command_delegates_secrets_to_kettle_release?
185
186
  end
186
187
 
187
- attr_reader :command, :config, :members, :execute, :accept, :commit, :allow_dirty, :autostash, :publish, :push, :tag, :start_step, :skip_steps, :local_ci, :continue_ci_failures, :ci_workflows, :skip_bundle_audit, :skip_remotes, :required_remotes, :auto_dependency_floors, :gha_sha_pins_upgrade, :gha_sha_pins_check, :gha_sha_pins_ttl_days, :env_overrides, :debug, :verbose, :jobs, :progress_io, :reset_target, :bup_args, :bex_args, :start_member, :start_branch
188
+ attr_reader :command, :config, :members, :execute, :accept, :commit, :allow_dirty, :autostash, :publish, :push, :tag, :start_step, :skip_steps, :skip_changelog, :local_ci, :continue_ci_failures, :ci_workflows, :skip_bundle_audit, :skip_remotes, :required_remotes, :auto_dependency_floors, :gha_sha_pins_upgrade, :gha_sha_pins_check, :gha_sha_pins_ttl_days, :env_overrides, :debug, :verbose, :jobs, :progress_io, :reset_target, :bup_args, :bex_args, :start_member, :start_branch
188
189
 
189
190
  def template_with_worktree_sync_results
190
191
  runner = command_runner
@@ -420,7 +421,7 @@ module Kettle
420
421
  return check_results(workflow_members) if command == "check"
421
422
  return reset_member_results(workflow_members) if command == "reset"
422
423
  if command == "release"
423
- results = release_member_results(workflow_members, include_family_changelog: true)
424
+ results = release_member_results(workflow_members, include_family_changelog: !skip_changelog)
424
425
  return results unless explicit_monorepo_mode? && results.all?(&:ok?)
425
426
 
426
427
  results << aggregate_monorepo_github_release(workflow_members)
@@ -507,11 +508,12 @@ module Kettle
507
508
  return true if workflow_members.empty?
508
509
 
509
510
  repositories = []
511
+ command_text = standalone_gha_sha_pins_command(command_for("gha-sha-pins"))
510
512
  workflow_members.each do |member|
511
513
  result = runner.call(
512
514
  member: member,
513
515
  phase: "gha_sha_pins_list",
514
- command: gha_sha_pins_command(mode: :list, command_text: command_for("gha-sha-pins")),
516
+ command: gha_sha_pins_command(mode: :list, command_text: command_text),
515
517
  env: env,
516
518
  log_path: gha_sha_pins_log_path(member, phase: "list")
517
519
  )
@@ -524,7 +526,7 @@ module Kettle
524
526
  memo << CommandResult.new(
525
527
  member_name: member.name,
526
528
  phase: "gha_sha_pins_list",
527
- command: gha_sha_pins_command(mode: :list, command_text: command_for("gha-sha-pins")),
529
+ command: gha_sha_pins_command(mode: :list, command_text: command_text),
528
530
  workdir: member.root,
529
531
  status: 1,
530
532
  success: false,
@@ -548,7 +550,7 @@ module Kettle
548
550
  review_result = runner.call(
549
551
  member: workflow_members.first,
550
552
  phase: "gha_sha_pins_review",
551
- command: gha_sha_pins_command(mode: :review, input: review_path, command_text: command_for("gha-sha-pins")),
553
+ command: gha_sha_pins_command(mode: :review, input: review_path, command_text: command_text),
552
554
  env: env,
553
555
  log_path: gha_sha_pins_log_path(workflow_members.first, phase: "review")
554
556
  )
@@ -1061,7 +1063,7 @@ module Kettle
1061
1063
  def release_member_local_branch_target_results
1062
1064
  runner = command_runner
1063
1065
  results = []
1064
- append_family_changelog_result(runner: runner, memo: results)
1066
+ append_family_changelog_result(runner: runner, memo: results) unless skip_changelog
1065
1067
  return results unless results.all?(&:ok?)
1066
1068
 
1067
1069
  members.each_with_object(results) do |member, memo|
@@ -1089,6 +1091,7 @@ module Kettle
1089
1091
  tag: tag,
1090
1092
  start_step: start_step,
1091
1093
  skip_steps: skip_steps,
1094
+ skip_changelog: skip_changelog,
1092
1095
  local_ci: local_ci,
1093
1096
  continue_ci_failures: continue_ci_failures,
1094
1097
  ci_workflows: ci_workflows,
@@ -1122,22 +1125,35 @@ module Kettle
1122
1125
  return results unless results.all?(&:ok?)
1123
1126
  return parallel_release_member_results(release_members, results) if parallel_release_members?(release_members)
1124
1127
 
1128
+ sequential_release_member_results(release_members, results, runner: runner)
1129
+ end
1130
+
1131
+ def sequential_release_member_results(release_members, initial_results, runner:)
1132
+ results = initial_results
1133
+ waves = release_waves(release_members)
1134
+ ordered_members = waves.flatten
1135
+ show_wave_markers = config.release_waves.any? && waves.length > 1
1125
1136
  release_progress = start_release_progress(release_members)
1126
1137
  @release_progress = release_progress
1127
1138
  begin
1128
- release_members.each_with_object(results) do |member, memo|
1129
- memo.concat(release_results_for_member(member, runner: runner))
1130
- break memo unless memo.last.ok?
1131
-
1132
- remaining_members = release_members.drop(release_members.index(member) + 1)
1133
- @release_completed_member_names << member.name
1134
- append_dependency_floor_results(released_members: [member], dependent_members: remaining_members, runner: runner, memo: memo)
1135
- break memo unless memo.last&.ok?
1139
+ waves.each_with_index do |wave, index|
1140
+ results << release_wave_result(wave, index: index, total: waves.length, jobs: 1) if show_wave_markers
1141
+ wave.each do |member|
1142
+ results.concat(release_results_for_member(member, runner: runner))
1143
+ break unless results.last.ok?
1144
+
1145
+ remaining_members = ordered_members.drop(ordered_members.index(member) + 1)
1146
+ @release_completed_member_names << member.name
1147
+ append_dependency_floor_results(released_members: [member], dependent_members: remaining_members, runner: runner, memo: results)
1148
+ break unless results.last&.ok?
1149
+ end
1150
+ break unless results.last&.ok?
1136
1151
  end
1137
1152
  ensure
1138
1153
  emit_release_progress_summary(results, progress: release_progress)
1139
1154
  @release_progress = nil
1140
1155
  end
1156
+ results
1141
1157
  end
1142
1158
 
1143
1159
  def parallel_release_member_results(release_members, initial_results)
@@ -1200,7 +1216,7 @@ module Kettle
1200
1216
  ordered_results.compact
1201
1217
  end
1202
1218
 
1203
- def release_wave_result(wave, index:, total:)
1219
+ def release_wave_result(wave, index:, total:, jobs: nil)
1204
1220
  CommandResult.new(
1205
1221
  member_name: "wave #{index + 1}",
1206
1222
  phase: "release_wave",
@@ -1212,7 +1228,7 @@ module Kettle
1212
1228
  stderr: "",
1213
1229
  elapsed_seconds: 0.0,
1214
1230
  skipped: false,
1215
- reason: "jobs=#{release_jobs(wave)} total=#{total}"
1231
+ reason: "jobs=#{jobs || release_jobs(wave)} total=#{total}"
1216
1232
  )
1217
1233
  end
1218
1234
 
@@ -1349,6 +1365,9 @@ module Kettle
1349
1365
  require_relative "dependency_floor"
1350
1366
 
1351
1367
  affected_dependent_members = dependent_members_depending_on(released_members: released_members, dependent_members: dependent_members)
1368
+ lockfile_ready_dependent_members = affected_dependent_members.select do |member|
1369
+ dependency_floor_refresh_ready?(member, released_members: released_members)
1370
+ end
1352
1371
  floor_results = DependencyFloor.new(
1353
1372
  released_members: released_members,
1354
1373
  dependent_members: dependent_members,
@@ -1358,10 +1377,10 @@ module Kettle
1358
1377
  return if floor_results.empty?
1359
1378
  return if floor_results.any? && !floor_results.all?(&:ok?)
1360
1379
 
1361
- append_dependency_floor_lockfile_results(released_members: released_members, dependent_members: affected_dependent_members, runner: runner, memo: memo)
1380
+ append_dependency_floor_lockfile_results(released_members: released_members, dependent_members: lockfile_ready_dependent_members, runner: runner, memo: memo)
1362
1381
  return if memo.any? && !memo.last.ok?
1363
1382
 
1364
- append_dependency_floor_ci_bundle_results(released_members: released_members, dependent_members: affected_dependent_members, runner: runner, memo: memo)
1383
+ append_dependency_floor_ci_bundle_results(released_members: released_members, dependent_members: lockfile_ready_dependent_members, runner: runner, memo: memo)
1365
1384
  return if memo.any? && !memo.last.ok?
1366
1385
 
1367
1386
  commit_dependency_floor_changes(dependent_members: floor_results.map(&:member_name), runner: runner, memo: memo) if floor_results.any? && execute && commit
@@ -1374,6 +1393,17 @@ module Kettle
1374
1393
  end
1375
1394
  end
1376
1395
 
1396
+ # A release-valid lockfile must resolve every selected sibling dependency
1397
+ # from the registry. Defer refreshes for dependents that still require a
1398
+ # selected sibling from a later release wave; their gemspec floors can be
1399
+ # updated now, but Bundler cannot resolve the future sibling remotely yet.
1400
+ def dependency_floor_refresh_ready?(member, released_members:)
1401
+ selected_names = members.map(&:name)
1402
+ selected_dependencies = release_dependency_names(member).select { |dependency| selected_names.include?(dependency) }
1403
+ completed_names = Array(@release_completed_member_names) + released_members.map(&:name)
1404
+ selected_dependencies.all? { |dependency| completed_names.include?(dependency) }
1405
+ end
1406
+
1377
1407
  def release_dependency_names(member)
1378
1408
  Array(member.release_dependencies || member.dependencies).map(&:to_s)
1379
1409
  end
@@ -1885,14 +1915,14 @@ module Kettle
1885
1915
  def family_changelog_env
1886
1916
  env = release_env.merge(config.changelog_env)
1887
1917
  # A shared monorepo changelog runs the aggregate suite before each
1888
- # member release. Keep unpublished selected siblings on local paths for
1889
- # that suite; the member release's lockfile reset still disables them
1890
- # before building and publishing the gem.
1918
+ # member release. Keep that suite on the family-local dependency graph;
1919
+ # the member release's lockfile reset still disables local paths before
1920
+ # building and publishing each gem.
1891
1921
  family_env_name = config.family_local_path_env_name
1892
- if config.family_mode == "monorepo" && family_env_name &&
1893
- local_path_env_value?(release_env[family_env_name])
1894
- env[family_env_name] = release_env.fetch(family_env_name)
1922
+ if config.family_mode == "monorepo" && family_env_name
1923
+ env[family_env_name] = family_changelog_family_path(family_env_name)
1895
1924
  end
1925
+ family_changelog_tooling_env.each { |name, value| env[name] = value }
1896
1926
  return env unless config.shared_changelog?
1897
1927
 
1898
1928
  env.merge(
@@ -1903,6 +1933,26 @@ module Kettle
1903
1933
  )
1904
1934
  end
1905
1935
 
1936
+ def family_changelog_family_path(name)
1937
+ configured = config.changelog_env.fetch(name, nil)
1938
+ return configured if local_path_env_value?(configured)
1939
+
1940
+ override = env_overrides.fetch(name, nil)
1941
+ return override if local_path_env_value?(override)
1942
+
1943
+ ambient = ENV.fetch(name, nil)
1944
+ return ambient if local_path_env_value?(ambient)
1945
+
1946
+ config.family_local_path_root
1947
+ end
1948
+
1949
+ def family_changelog_tooling_env
1950
+ %w[KETTLE_DEV_DEV].each_with_object({}) do |name, env|
1951
+ value = env_overrides.fetch(name, ENV[name])
1952
+ env[name] = value if value && local_path_env_value?(value)
1953
+ end
1954
+ end
1955
+
1906
1956
  def family_changelog_version_file
1907
1957
  configured = config.changelog_version_file.to_s
1908
1958
  return configured if !configured.empty? && members.any? { |member| path_inside?(File.expand_path(configured, config.root), member.root) }
@@ -1928,7 +1978,9 @@ module Kettle
1928
1978
 
1929
1979
  def family_changelog_command
1930
1980
  command = config.release_family_changelog_command
1931
- kettle_changelog_command?(command) ? append_kettle_changelog_args(command) : command
1981
+ return command unless kettle_changelog_command?(command)
1982
+
1983
+ append_kettle_changelog_args(standalone_kettle_changelog_command(command))
1932
1984
  end
1933
1985
 
1934
1986
  def raw_release_command
@@ -1970,6 +2022,7 @@ module Kettle
1970
2022
  args = []
1971
2023
  args << "start_step=#{start_step}" if start_step
1972
2024
  args << "skip_steps=#{skip_steps}" if skip_steps && !skip_steps.to_s.empty?
2025
+ args << "--skip-changelog" if skip_changelog
1973
2026
  args << "--ci-workflows=#{ci_workflows}" if ci_workflows && !ci_workflows.to_s.empty?
1974
2027
  args << "--local-ci" if local_ci
1975
2028
  args << "--skip-bundle-audit" if skip_bundle_audit
@@ -2397,7 +2450,10 @@ module Kettle
2397
2450
 
2398
2451
  def workflow_command(member = nil)
2399
2452
  return template_command(member) if command == "template"
2400
- return gha_sha_pins_command if command == "gha-sha-pins"
2453
+ if command == "gha-sha-pins"
2454
+ command_text = standalone_gha_sha_pins_command(command_for("gha-sha-pins"))
2455
+ return gha_sha_pins_command(command_text: command_text)
2456
+ end
2401
2457
  return bup_command if command == "bup"
2402
2458
  return bex_command if command == "bex"
2403
2459
 
@@ -2473,6 +2529,63 @@ module Kettle
2473
2529
  configured || DEFAULT_COMMANDS.fetch(name)
2474
2530
  end
2475
2531
 
2532
+ # GHA pin inventory is a workspace-level release preflight, not a member
2533
+ # bundle operation. The installed RubyGems wrapper calls Gem.use_gemdeps,
2534
+ # which can load the member's Gemfile and make an otherwise independent
2535
+ # pin scan fail on unpublished sibling gems. Run the gem's actual
2536
+ # executable so this phase uses the shared installed tool and cache.
2537
+ def standalone_gha_sha_pins_command(command_text)
2538
+ argv = command_text.is_a?(Array) ? command_text.map(&:to_s) : Shellwords.split(command_text.to_s)
2539
+ executable_index = argv.index { |token| File.basename(token) == "kettle-gha-pins" }
2540
+ return command_text unless executable_index
2541
+
2542
+ executable = installed_gem_executable("kettle-gha-pins", "kettle-gha-pins")
2543
+ return command_text unless executable
2544
+
2545
+ [RbConfig.ruby, executable, *argv[(executable_index + 1)..]]
2546
+ rescue Gem::LoadError
2547
+ command_text
2548
+ end
2549
+
2550
+ # The family changelog phase must run the standalone published tool. A
2551
+ # member's generated bin/kettle-changelog wrapper belongs to kettle-dev
2552
+ # and can no longer resolve the executable after kettle-changelog moved
2553
+ # into its own gem. Calling the gem's executable directly also avoids
2554
+ # Gem.use_gemdeps loading an unrelated member Gemfile.
2555
+ def standalone_kettle_changelog_command(command_text)
2556
+ argv = command_text.is_a?(Array) ? command_text.map(&:to_s) : Shellwords.split(command_text.to_s)
2557
+ executable_index = argv.index { |token| File.basename(token) == "kettle-changelog" }
2558
+ return command_text unless executable_index
2559
+
2560
+ executable = installed_gem_executable("kettle-changelog", "kettle-changelog")
2561
+ return command_text unless executable
2562
+
2563
+ [RbConfig.ruby, executable, *argv[(executable_index + 1)..]]
2564
+ rescue Gem::LoadError
2565
+ command_text
2566
+ end
2567
+
2568
+ def installed_gem_executable(gem_name, executable_name)
2569
+ spec_executable = begin
2570
+ spec = Gem::Specification.find_by_name(gem_name)
2571
+ File.join(spec.full_gem_path, "exe", executable_name)
2572
+ rescue Gem::LoadError
2573
+ nil
2574
+ end
2575
+ return spec_executable if spec_executable && File.file?(spec_executable)
2576
+
2577
+ candidates = Gem.path.flat_map do |gem_path|
2578
+ Dir[File.join(gem_path, "gems", "#{gem_name}-*", "exe", executable_name)]
2579
+ end
2580
+ candidates.max_by do |candidate|
2581
+ directory = File.basename(File.dirname(candidate, 2))
2582
+ version = directory.delete_prefix("#{gem_name}-")
2583
+ Gem::Version.new(version)
2584
+ rescue ArgumentError
2585
+ Gem::Version.new("0")
2586
+ end
2587
+ end
2588
+
2476
2589
  def template_command(member)
2477
2590
  command_text = config.template_command || default_template_command(member)
2478
2591
  command_text = localize_kettle_jem_template_command(command_text)
@@ -3638,7 +3751,9 @@ module Kettle
3638
3751
  end
3639
3752
 
3640
3753
  def release_allowed_local_path_roots
3641
- release_local_path_env_sources.filter_map do |key, value|
3754
+ # Release env disables are passed to Bundler normalization, but they
3755
+ # must not hide the active workspace roots from readiness diagnostics.
3756
+ release_local_path_env_detection_sources.filter_map do |key, value|
3642
3757
  next unless key.end_with?("_LOCAL", "_DEV")
3643
3758
  next unless local_path_env_value?(value)
3644
3759
  next unless value.to_s.strip.start_with?("/", "./", "../", "~")
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.48
4
+ version: 1.2.49
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -71,7 +71,7 @@ dependencies:
71
71
  requirements:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
- version: 3.0.2
74
+ version: 3.0.6
75
75
  - - "<"
76
76
  - !ruby/object:Gem::Version
77
77
  version: 4.0.0
@@ -81,7 +81,7 @@ dependencies:
81
81
  requirements:
82
82
  - - ">="
83
83
  - !ruby/object:Gem::Version
84
- version: 3.0.2
84
+ version: 3.0.6
85
85
  - - "<"
86
86
  - !ruby/object:Gem::Version
87
87
  version: 4.0.0
@@ -224,7 +224,7 @@ dependencies:
224
224
  version: '3.2'
225
225
  - - ">="
226
226
  - !ruby/object:Gem::Version
227
- version: 3.2.0
227
+ version: 3.2.2
228
228
  type: :development
229
229
  prerelease: false
230
230
  version_requirements: !ruby/object:Gem::Requirement
@@ -234,7 +234,7 @@ dependencies:
234
234
  version: '3.2'
235
235
  - - ">="
236
236
  - !ruby/object:Gem::Version
237
- version: 3.2.0
237
+ version: 3.2.2
238
238
  - !ruby/object:Gem::Dependency
239
239
  name: turbo_tests2
240
240
  requirement: !ruby/object:Gem::Requirement
@@ -244,7 +244,7 @@ dependencies:
244
244
  version: '3.2'
245
245
  - - ">="
246
246
  - !ruby/object:Gem::Version
247
- version: 3.2.4
247
+ version: 3.2.5
248
248
  type: :development
249
249
  prerelease: false
250
250
  version_requirements: !ruby/object:Gem::Requirement
@@ -254,7 +254,7 @@ dependencies:
254
254
  version: '3.2'
255
255
  - - ">="
256
256
  - !ruby/object:Gem::Version
257
- version: 3.2.4
257
+ version: 3.2.5
258
258
  - !ruby/object:Gem::Dependency
259
259
  name: ruby-progressbar
260
260
  requirement: !ruby/object:Gem::Requirement
@@ -361,10 +361,10 @@ licenses:
361
361
  - AGPL-3.0-only
362
362
  metadata:
363
363
  homepage_uri: https://kettle-family.galtzo.com
364
- source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.48
365
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.48/CHANGELOG.md
364
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.49
365
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.49/CHANGELOG.md
366
366
  bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
367
- documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.48
367
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.49
368
368
  funding_uri: https://github.com/sponsors/pboling
369
369
  wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
370
370
  news_uri: https://www.railsbling.com/tags/kettle-family
metadata.gz.sig CHANGED
Binary file