kettle-family 1.2.81 → 1.2.83

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: 28cb9e0600f04c071246e2616958ef2f590c55bab8e803f3b38b9063e93973c3
4
- data.tar.gz: 6f31c62982bc551f886a34d7a65c4e10cfe901762c45af0b7f4125963ec8722e
3
+ metadata.gz: 4597b93884181bec791afb1965da15957f01eec43876c13835191eb9419ff0fe
4
+ data.tar.gz: 57e1d3dd4799d826baed78d1fb258ce8fe658eae94d163681b20d1af718b4151
5
5
  SHA512:
6
- metadata.gz: 84cc1ed99e586d4f7da3483e04097b4098b8576015be0b9f52db5605395bd6c9403cd015d1698d58ce3683e313dbed4f0b7b30c65e0dcd1c2f0736862bc169ed
7
- data.tar.gz: f4ff4feb6aed25083c3a2b2ee90d1723abed2a126fbd609ead0ad5b97bd6a3fc4bcb7b40d7881675e77089acad0b1f9e803c60202a0dfb1635b0128fb7f437b9
6
+ metadata.gz: dabdf35f9aa98339e0443282e1bd5ed26c61ec9ebdb9a71b7238c8b4282cf26b87a54888e0cf853874cb6becf165050e218d6ac11708bcea0306dbf9d97a8ff6
7
+ data.tar.gz: 0da1b0a6fb5f9f4391613c7431d4b4e54827e90c137f87df16b06399fbfe009236d4dbbc9bc20bef450930be11dcf78f13f76f18e121b9a658fe1c8596f4e632
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,28 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.2.83] - 2026-09-02
34
+
35
+ - TAG: [v1.2.83][1.2.83t]
36
+ - COVERAGE: 93.08% -- 5782/6212 lines in 33 files
37
+ - BRANCH COVERAGE: 76.04% -- 2345/3084 branches in 33 files
38
+ - 30.69% documented
39
+
40
+ ### Fixed
41
+
42
+ - Run aggregate monorepo release members in isolated worktrees and serialize shared release finalization.
43
+
44
+ ## [1.2.82] - 2026-09-01
45
+
46
+ - TAG: [v1.2.82][1.2.82t]
47
+ - COVERAGE: 93.26% -- 5655/6064 lines in 33 files
48
+ - BRANCH COVERAGE: 76.34% -- 2310/3026 branches in 33 files
49
+ - 30.69% documented
50
+
51
+ ### Fixed
52
+
53
+ - Keep the configured family local dependency graph active throughout template bootstrap and preparation; release-only lockfile cleanup remains isolated to release commands.
54
+
33
55
  ## [1.2.81] - 2026-09-01
34
56
 
35
57
  - TAG: [v1.2.81][1.2.81t]
@@ -2477,7 +2499,11 @@ Please file a bug if you notice a violation of semantic versioning.
2477
2499
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
2478
2500
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
2479
2501
 
2480
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.81...HEAD
2502
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.83...HEAD
2503
+ [1.2.83]: https://github.com/kettle-dev/kettle-family/compare/v1.2.82...v1.2.83
2504
+ [1.2.83t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.83
2505
+ [1.2.82]: https://github.com/kettle-dev/kettle-family/compare/v1.2.81...v1.2.82
2506
+ [1.2.82t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.82
2481
2507
  [1.2.81]: https://github.com/kettle-dev/kettle-family/compare/v1.2.80...v1.2.81
2482
2508
  [1.2.81t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.81
2483
2509
  [1.2.80]: https://github.com/kettle-dev/kettle-family/compare/v1.2.79...v1.2.80
data/README.md CHANGED
@@ -1049,7 +1049,7 @@ Thanks for RTFM. ☺️
1049
1049
  [📌gitmoji]: https://gitmoji.dev
1050
1050
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1051
1051
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1052
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.079-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1052
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.212-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1053
1053
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
1054
1054
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1055
1055
  [📄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.81"
8
+ VERSION = "1.2.83"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
@@ -822,34 +822,13 @@ module Kettle
822
822
  versions.max
823
823
  end
824
824
 
825
- def template_bootstrap_dependency_env(member)
826
- env = release_lockfile_local_path_env_overrides(member).merge(workflow_env)
827
- env.each_key do |key|
828
- env[key] = "false" if key.end_with?("_DEV") && !local_path_env_requested?(key)
829
- end
825
+ def template_bootstrap_dependency_env(_member)
826
+ env = template_prepare_env
830
827
  env["K_JEM_TEMPLATING"] = "false"
831
828
  env["BUNDLE_DISABLE_CHECKSUM_VALIDATION"] = "true"
832
- family_env_name = config.family_local_path_env_name
833
- env[family_env_name] = "false" if family_env_name && !local_path_env_requested?(family_env_name)
834
- env.merge!(template_bootstrap_direct_sibling_env(member))
835
829
  env
836
830
  end
837
831
 
838
- # The bootstrap refreshes nomono before the template bundle is available,
839
- # but a sibling member can itself require an unreleased family gem. Keep
840
- # that direct dependency local without enabling the full template context.
841
- def template_bootstrap_direct_sibling_env(member)
842
- return {} unless config.family_mode == "sibling_repos"
843
-
844
- direct_sibling_env = "#{config.family_name.gsub(/[^A-Za-z0-9]+/, "_").upcase}_DEV"
845
- return {} if local_path_env_requested?(direct_sibling_env)
846
-
847
- family_names = family_members.map(&:name)
848
- return {} if (Array(member.dependencies) & family_names).empty?
849
-
850
- {direct_sibling_env => config.family_local_path_root}
851
- end
852
-
853
832
  def template_results_for_member(member, progress: nil)
854
833
  progress&.start_member(member, total: template_phase_total(member), status: template_initial_status(member))
855
834
  runner = CommandRunner.new(execute: execute, accept: accept)
@@ -1035,15 +1014,15 @@ module Kettle
1035
1014
  File.join(config.root, "tmp", "kettle-family", "template-worktrees", safe_member, "#{Process.pid}-#{safe_branch}")
1036
1015
  end
1037
1016
 
1038
- def relocate_member_to_worktree(member, worktree_root)
1017
+ def relocate_member_to_worktree(member, worktree_root, source_root: member.root)
1039
1018
  relocate = lambda do |path|
1040
1019
  next unless path
1041
1020
 
1042
- relative = Pathname.new(path).relative_path_from(Pathname.new(member.root))
1021
+ relative = Pathname.new(path).relative_path_from(Pathname.new(source_root))
1043
1022
  File.join(worktree_root, relative)
1044
1023
  end
1045
1024
  member.dup.tap do |worktree_member|
1046
- worktree_member.root = worktree_root
1025
+ worktree_member.root = relocate.call(member.root)
1047
1026
  worktree_member.gemspec_path = relocate.call(member.gemspec_path)
1048
1027
  worktree_member.version_file = relocate.call(member.version_file)
1049
1028
  end
@@ -1464,6 +1443,8 @@ module Kettle
1464
1443
  end
1465
1444
 
1466
1445
  def parallel_release_member_results(release_members, initial_results)
1446
+ return parallel_monorepo_release_member_results(release_members, initial_results) if monorepo_release_workers?
1447
+
1467
1448
  results = initial_results.dup
1468
1449
  waves = release_waves(release_members)
1469
1450
  completed_members = []
@@ -1523,6 +1504,248 @@ module Kettle
1523
1504
  ordered_results.compact
1524
1505
  end
1525
1506
 
1507
+ def parallel_monorepo_release_member_results(release_members, initial_results)
1508
+ results = initial_results.dup
1509
+ completed_members = []
1510
+ @release_completed_member_names = []
1511
+ release_progress = start_release_progress(release_members)
1512
+ @release_progress = release_progress
1513
+ begin
1514
+ release_waves(release_members).each_with_index do |wave, index|
1515
+ results << release_wave_result(wave, index: index, total: release_waves(release_members).length)
1516
+ aggregate_members, independent_members = wave.partition { |member| aggregate_release_member?(member) }
1517
+
1518
+ unless aggregate_members.empty?
1519
+ worker_results = run_monorepo_release_wave(aggregate_members)
1520
+ results.concat(worker_results.flatten)
1521
+ break unless worker_results.all? { |member_results| member_results.all?(&:ok?) }
1522
+
1523
+ finalization_results = finalize_monorepo_release_wave(aggregate_members)
1524
+ results.concat(finalization_results)
1525
+ break unless finalization_results.all?(&:ok?)
1526
+ end
1527
+
1528
+ independent_members.each do |member|
1529
+ results.concat(release_results_for_member(member, runner: release_command_runner))
1530
+ break unless results.last.ok?
1531
+ end
1532
+ break unless results.last&.ok?
1533
+
1534
+ completed_members.concat(wave)
1535
+ @release_completed_member_names.concat(wave.map(&:name))
1536
+ remaining_members = release_members - completed_members
1537
+ append_dependency_floor_results(released_members: wave, dependent_members: remaining_members, runner: release_command_runner, memo: results)
1538
+ break unless results.last&.ok?
1539
+ end
1540
+ ensure
1541
+ emit_release_progress_summary(results, progress: release_progress)
1542
+ @release_progress = nil
1543
+ end
1544
+ results
1545
+ end
1546
+
1547
+ def run_monorepo_release_wave(members)
1548
+ entries, setup_results = monorepo_release_worktree_entries(members)
1549
+ unless setup_results.all?(&:ok?)
1550
+ return setup_results.zip
1551
+ end
1552
+
1553
+ worker_results = run_monorepo_release_worktree_entries(entries)
1554
+ materialization_results = materialize_monorepo_release_artifacts(entries, worker_results)
1555
+ worker_results.each_with_index.map do |member_results, index|
1556
+ artifact_result = materialization_results[index]
1557
+ artifact_result ? [*member_results, artifact_result] : member_results
1558
+ end
1559
+ ensure
1560
+ cleanup_monorepo_release_worktrees(entries || [])
1561
+ end
1562
+
1563
+ def monorepo_release_worktree_entries(members)
1564
+ runner = command_runner
1565
+ control_member = monorepo_release_control_member
1566
+ entries = []
1567
+ results = []
1568
+ members.each do |member|
1569
+ root = monorepo_release_worktree_path(member)
1570
+ result = runner.call(
1571
+ member: control_member,
1572
+ phase: "release_worktree_add",
1573
+ command: ["git", "worktree", "add", "--detach", root, "HEAD"]
1574
+ )
1575
+ results << result
1576
+ break unless result.ok?
1577
+
1578
+ entries << {member: relocate_member_to_worktree(member, root, source_root: config.root), original_member: member, worktree_root: root}
1579
+ end
1580
+ [entries, results]
1581
+ end
1582
+
1583
+ def monorepo_release_worktree_path(member)
1584
+ safe_member = member.name.to_s.gsub(/[^A-Za-z0-9_.-]+/, "_")
1585
+ File.join(config.root, "tmp", "kettle-family", "release-worktrees", safe_member, "#{Process.pid}-#{Time.now.to_i}")
1586
+ end
1587
+
1588
+ def monorepo_release_control_member
1589
+ family_member.dup.tap { |member| member.root = config.root }
1590
+ end
1591
+
1592
+ def run_monorepo_release_worktree_entries(entries)
1593
+ queue = Queue.new
1594
+ entries.each_with_index { |entry, index| queue << [index, entry] }
1595
+ ordered_results = Array.new(entries.length)
1596
+ mutex = Mutex.new
1597
+ stop = false
1598
+ Array.new(release_jobs(entries)) do
1599
+ Thread.new do # rubocop:disable ThreadSafety/NewThread -- each member has an isolated detached monorepo worktree.
1600
+ loop do
1601
+ break if mutex.synchronize { stop }
1602
+
1603
+ index, entry = queue.pop(true)
1604
+ member_results = release_results_for_monorepo_worktree(entry)
1605
+ mutex.synchronize do
1606
+ ordered_results[index] = member_results
1607
+ stop = true unless member_results.all?(&:ok?)
1608
+ end
1609
+ rescue ThreadError
1610
+ break
1611
+ rescue => error
1612
+ mutex.synchronize do
1613
+ ordered_results[index] = [release_worker_error_result(entry.fetch(:original_member), error)]
1614
+ stop = true
1615
+ end
1616
+ break
1617
+ end
1618
+ end
1619
+ end.each(&:join)
1620
+ ordered_results.compact
1621
+ end
1622
+
1623
+ def release_results_for_monorepo_worktree(entry)
1624
+ member = entry.fetch(:member)
1625
+ original_member = entry.fetch(:original_member)
1626
+ progress = @release_progress
1627
+ progress&.start_member(original_member, total: release_phase_total(original_member), status: "check")
1628
+ [].tap do |memo|
1629
+ if skip_already_released?(original_member)
1630
+ memo << already_released_result(original_member)
1631
+ emit_member_result_progress(original_member, memo.last, progress: progress)
1632
+ return memo
1633
+ end
1634
+
1635
+ append_release_internal_checks(member: member, memo: memo)
1636
+ memo.last(2).each { |result| emit_member_result_progress(original_member, result, progress: progress) }
1637
+ return memo unless memo.last(2).all?(&:ok?)
1638
+
1639
+ release_event_state = {}
1640
+ result = release_command_runner.call(
1641
+ member: member,
1642
+ phase: release_phase,
1643
+ command: release_command_for(member),
1644
+ env: release_env_for_member(member, family_root: entry.fetch(:worktree_root)).merge("KETTLE_RELEASE_FAMILY_MEMBER_PUBLISH" => "true"),
1645
+ interactive: release_command_interactive?,
1646
+ stdout_line_handler: release_event_line_handler(original_member, progress: progress, state: release_event_state),
1647
+ log_path: release_command_log_path(original_member, release_phase),
1648
+ passthrough_output: release_command_passthrough_output?
1649
+ )
1650
+ result.member_name = original_member.name
1651
+ result.resume_step = release_event_state[:failed_step] unless result.ok?
1652
+ memo << result
1653
+ emit_member_result_progress(original_member, result, progress: progress)
1654
+ ensure
1655
+ finished_result = memo.find { |result| result.phase == release_phase } || memo.last
1656
+ progress&.finish_member(original_member, success: memo.all?(&:ok?), status: release_member_finish_status(finished_result)) if finished_result
1657
+ end
1658
+ end
1659
+
1660
+ def materialize_monorepo_release_artifacts(entries, worker_results)
1661
+ entries.each_with_index.map do |entry, index|
1662
+ next unless worker_results[index]&.all?(&:ok?)
1663
+
1664
+ copy_monorepo_release_artifact(entry)
1665
+ end
1666
+ end
1667
+
1668
+ def copy_monorepo_release_artifact(entry)
1669
+ member = entry.fetch(:member)
1670
+ original_member = entry.fetch(:original_member)
1671
+ version = original_member.version.to_s
1672
+ source = Dir[File.join(member.root, "pkg", "#{original_member.name}-#{version}.gem")].first
1673
+ destination = File.join(original_member.root, "pkg", "#{original_member.name}-#{version}.gem")
1674
+ unless source && File.file?(source)
1675
+ return release_worker_error_result(original_member, Error.new("worker did not produce #{File.basename(destination)}"))
1676
+ end
1677
+
1678
+ FileUtils.mkdir_p(File.dirname(destination))
1679
+ FileUtils.cp(source, destination)
1680
+ CommandResult.new(
1681
+ member_name: original_member.name,
1682
+ phase: "release_artifact_materialize",
1683
+ command: ["internal", "copy-release-artifact"],
1684
+ workdir: original_member.root,
1685
+ status: 0,
1686
+ success: true,
1687
+ stdout: File.basename(destination),
1688
+ stderr: "",
1689
+ elapsed_seconds: 0.0,
1690
+ skipped: false,
1691
+ reason: "copied from isolated release worktree"
1692
+ )
1693
+ rescue => error
1694
+ release_worker_error_result(original_member, error)
1695
+ end
1696
+
1697
+ def cleanup_monorepo_release_worktrees(entries)
1698
+ runner = command_runner
1699
+ control_member = monorepo_release_control_member
1700
+ entries.each do |entry|
1701
+ root = entry.fetch(:worktree_root)
1702
+ next unless Dir.exist?(root)
1703
+
1704
+ runner.call(member: control_member, phase: "release_worktree_remove", command: ["git", "worktree", "remove", "--force", root])
1705
+ end
1706
+ end
1707
+
1708
+ def finalize_monorepo_release_wave(members)
1709
+ runner = release_command_runner
1710
+ results = []
1711
+ members.each do |member|
1712
+ results << ensure_monorepo_release_tag(member, runner: runner)
1713
+ break unless results.last.ok?
1714
+
1715
+ results << runner.call(
1716
+ member: member,
1717
+ phase: "release_finalize",
1718
+ command: release_command_for(member),
1719
+ env: release_env_for_member(member).merge("KETTLE_RELEASE_FAMILY_MEMBER_FINALIZE" => "true"),
1720
+ interactive: release_command_interactive?,
1721
+ stdout_line_handler: release_event_line_handler(member, progress: @release_progress, state: {}),
1722
+ log_path: release_command_log_path(member, "release_finalize"),
1723
+ passthrough_output: release_command_passthrough_output?
1724
+ )
1725
+ break unless results.last.ok?
1726
+ end
1727
+ return results unless results.all?(&:ok?)
1728
+
1729
+ results << runner.call(
1730
+ member: monorepo_release_control_member,
1731
+ phase: "release_shared_push",
1732
+ command: config.release_push_command
1733
+ )
1734
+ results
1735
+ end
1736
+
1737
+ def ensure_monorepo_release_tag(member, runner:)
1738
+ version = member.version.to_s
1739
+ tag = release_tag_name(version)
1740
+ escaped_tag = Shellwords.escape(tag)
1741
+ runner.call(
1742
+ member: monorepo_release_control_member,
1743
+ phase: "release_shared_tag",
1744
+ command: ["sh", "-lc", "git rev-parse -q --verify refs/tags/#{escaped_tag} >/dev/null || git tag -a #{escaped_tag} -m #{escaped_tag}"],
1745
+ env: release_env
1746
+ )
1747
+ end
1748
+
1526
1749
  def release_wave_result(wave, index:, total:, jobs: nil)
1527
1750
  CommandResult.new(
1528
1751
  member_name: "wave #{index + 1}",
@@ -1647,7 +1870,19 @@ module Kettle
1647
1870
  execute &&
1648
1871
  release_jobs(release_members) > 1 &&
1649
1872
  release_members.length > 1 &&
1650
- distinct_git_roots?(release_members)
1873
+ (distinct_git_roots?(release_members) || monorepo_release_workers?)
1874
+ end
1875
+
1876
+ # Aggregate monorepo members share one Git checkout, so their complete
1877
+ # kettle-release workflows cannot safely run concurrently. They are
1878
+ # instead published from disposable worktrees using the explicit
1879
+ # member-only contract, then finalized serially in the primary checkout.
1880
+ def monorepo_release_workers?
1881
+ execute &&
1882
+ publish &&
1883
+ config.configured_monorepo_release? &&
1884
+ aggregate_monorepo_github_release? &&
1885
+ kettle_release_command?(raw_release_command)
1651
1886
  end
1652
1887
 
1653
1888
  def release_jobs(release_members)
@@ -2701,10 +2936,10 @@ module Kettle
2701
2936
  # A monorepo member runs kettle-release from its own checkout, while its
2702
2937
  # changelog may live at the family root. Pass the shared paths to the
2703
2938
  # member release phase as well as to the separate family phase.
2704
- def release_env_for_member(member)
2939
+ def release_env_for_member(member, family_root: config.root)
2705
2940
  env = release_env
2706
- env.merge!(release_wave_local_path_env_for(member))
2707
- env.merge!(release_local_path_policy_env)
2941
+ env.merge!(release_wave_local_path_env_for(member, family_root: family_root))
2942
+ env.merge!(release_local_path_policy_env(family_root: family_root))
2708
2943
  # Family release performs one live pin review before member releases.
2709
2944
  # Child kettle-release must consume that reviewed cache instead of
2710
2945
  # repeating the GitHub API lookup for every member.
@@ -2724,7 +2959,7 @@ module Kettle
2724
2959
  if config.family_mode == "monorepo"
2725
2960
  # Monorepo members release from subdirectories, while CI workflows
2726
2961
  # live at the shared repository root.
2727
- env["K_RELEASE_CI_ROOT"] = config.root
2962
+ env["K_RELEASE_CI_ROOT"] = family_root
2728
2963
  env["K_RELEASE_CI_WORKFLOWS"] ||= "current.yml"
2729
2964
  # Explicit multi-gem monorepos publish one aggregate GitHub Release
2730
2965
  # after their member gems. A standalone gem uses the default
@@ -2784,13 +3019,13 @@ module Kettle
2784
3019
  # release for the next member. Dependencies outside the selected set are
2785
3020
  # already treated as registry dependencies; this is what makes resume
2786
3021
  # runs work after an earlier wave has been published.
2787
- def release_wave_local_path_env_for(member)
3022
+ def release_wave_local_path_env_for(member, family_root: config.root)
2788
3023
  # Monorepo members and their sibling dependencies share the same CI
2789
3024
  # checkout, so their canonical development lockfile may keep those
2790
3025
  # paths throughout every release wave.
2791
3026
  if config.configured_monorepo_release?
2792
3027
  env_name = config.family_local_path_env_name
2793
- return env_name ? {env_name => config.family_local_path_root} : {}
3028
+ return env_name ? {env_name => family_local_path_root_for(family_root)} : {}
2794
3029
  end
2795
3030
 
2796
3031
  return {} unless config.release_local_path_strategy == "waves"
@@ -4377,10 +4612,10 @@ module Kettle
4377
4612
  end
4378
4613
 
4379
4614
  def template_prepare_env
4380
- env = workflow_env
4381
- family_env_name = config.family_local_path_env_name
4382
- env[family_env_name] = "false" if family_env_name && !local_path_env_requested?(family_env_name)
4383
- env
4615
+ # Templating is development work. It must resolve the configured
4616
+ # family graph exactly as template application does; release-only
4617
+ # lockfile cleanup owns disabling local path sources.
4618
+ workflow_env
4384
4619
  end
4385
4620
 
4386
4621
  def local_path_env_requested?(name)
@@ -4451,14 +4686,28 @@ module Kettle
4451
4686
  config.release_allowed_local_path_roots
4452
4687
  end
4453
4688
 
4689
+ def family_local_path_root_for(family_root)
4690
+ return config.family_local_path_root if File.expand_path(family_root) == File.expand_path(config.root)
4691
+
4692
+ relative = Pathname.new(config.family_local_path_root).relative_path_from(Pathname.new(config.root))
4693
+ File.expand_path(relative, family_root)
4694
+ end
4695
+
4454
4696
  def release_allowed_local_path_env_names
4455
4697
  names = config.release_allowed_local_path_env_names
4456
4698
  names << "K_JEM_TEMPLATING" if preserve_monorepo_template_context?
4457
4699
  names.uniq
4458
4700
  end
4459
4701
 
4460
- def release_local_path_policy_env
4461
- roots = release_allowed_local_path_roots
4702
+ def release_local_path_policy_env(family_root: config.root)
4703
+ roots = release_allowed_local_path_roots.map do |root|
4704
+ if File.expand_path(family_root) == File.expand_path(config.root)
4705
+ root
4706
+ else
4707
+ relative = Pathname.new(root).relative_path_from(Pathname.new(config.root))
4708
+ File.expand_path(relative, family_root)
4709
+ end
4710
+ end
4462
4711
  env_names = release_allowed_local_path_env_names
4463
4712
  return {} if roots.empty? && env_names.empty?
4464
4713
 
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.81
4
+ version: 1.2.83
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -91,7 +91,7 @@ dependencies:
91
91
  requirements:
92
92
  - - ">="
93
93
  - !ruby/object:Gem::Version
94
- version: 3.0.27
94
+ version: 3.0.30
95
95
  - - "<"
96
96
  - !ruby/object:Gem::Version
97
97
  version: 4.0.0
@@ -101,7 +101,7 @@ dependencies:
101
101
  requirements:
102
102
  - - ">="
103
103
  - !ruby/object:Gem::Version
104
- version: 3.0.27
104
+ version: 3.0.30
105
105
  - - "<"
106
106
  - !ruby/object:Gem::Version
107
107
  version: 4.0.0
@@ -441,10 +441,10 @@ licenses:
441
441
  - AGPL-3.0-only
442
442
  metadata:
443
443
  homepage_uri: https://kettle-family.galtzo.com
444
- source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.81
445
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.81/CHANGELOG.md
444
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.83
445
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.83/CHANGELOG.md
446
446
  bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
447
- documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.81
447
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.83
448
448
  funding_uri: https://github.com/sponsors/pboling
449
449
  wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
450
450
  news_uri: https://www.railsbling.com/tags/kettle-family
metadata.gz.sig CHANGED
Binary file