kettle-family 1.3.26 → 1.3.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +16 -1
- data/README.md +1 -1
- data/lib/kettle/family/cli.rb +42 -6
- data/lib/kettle/family/report.rb +28 -9
- data/lib/kettle/family/selection.rb +24 -4
- data/lib/kettle/family/version.rb +1 -1
- data/lib/kettle/family/workflow.rb +27 -2
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68173e6324c65cec8417346451236a9cf2dd3d94fc4e91919676f0c611910042
|
|
4
|
+
data.tar.gz: 3579c4ad1ab8f299fd1225396c91e4b4c8ff51bfa8f81c6f73410ec1c4277a3c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47009c3a27af69f4225d2ca340357ee80481be9e37c4ff73393abf2e6816bce67d084b06f1faddf332e983f4e363de72d2b67bd83e9f910d437f203f7994fca9
|
|
7
|
+
data.tar.gz: bad1f7ecc474afec6feaf144b489f2f6d702cf9f3d1fa21b237bf6171324d4db4d8dae5034ab1f71678e505e27aa1d4862413185e52a1946ee7bbe7c5a0c3614
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,19 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [1.3.27] - 2026-10-20
|
|
34
|
+
|
|
35
|
+
- TAG: [v1.3.27][1.3.27t]
|
|
36
|
+
- COVERAGE: 93.04% -- 7460/8018 lines in 44 files
|
|
37
|
+
- BRANCH COVERAGE: 77.50% -- 2994/3863 branches in 44 files
|
|
38
|
+
- 37.45% documented
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Preserve branch identity in template reports and exact-branch resume hints, and support MEMBER@BRANCH selection and resume targets.
|
|
43
|
+
|
|
44
|
+
- Retry template preparation once when Bundler reports a cached gemspec evaluating to nil.
|
|
45
|
+
|
|
33
46
|
## [1.3.26] - 2026-10-20
|
|
34
47
|
|
|
35
48
|
- TAG: [v1.3.26][1.3.26t]
|
|
@@ -3165,7 +3178,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
3165
3178
|
- Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
|
|
3166
3179
|
- Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
|
|
3167
3180
|
|
|
3168
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.3.
|
|
3181
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.3.27...HEAD
|
|
3182
|
+
[1.3.27]: https://github.com/kettle-dev/kettle-family/compare/v1.3.26...v1.3.27
|
|
3183
|
+
[1.3.27t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.27
|
|
3169
3184
|
[1.3.26]: https://github.com/kettle-dev/kettle-family/compare/v1.3.25...v1.3.26
|
|
3170
3185
|
[1.3.26t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.3.26
|
|
3171
3186
|
[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-
|
|
1228
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-8.018-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
|
data/lib/kettle/family/cli.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
data/lib/kettle/family/report.rb
CHANGED
|
@@ -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
|
|
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
|
-
|
|
452
|
+
identity = result_identity(result)
|
|
453
|
+
next unless selected_identities.include?(identity)
|
|
447
454
|
|
|
448
|
-
memo[
|
|
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
|
|
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(
|
|
515
|
-
templated = selected_member_results.filter_map do |
|
|
516
|
-
|
|
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
|
|
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 =
|
|
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.
|
|
8
|
+
VERSION = "1.3.27"
|
|
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 =
|
|
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 = []
|
|
@@ -5595,6 +5600,13 @@ module Kettle
|
|
|
5595
5600
|
commit_normalized_lockfiles(branch_members: [member], runner: runner, memo: memo, reason: "reset", force: true)
|
|
5596
5601
|
end
|
|
5597
5602
|
|
|
5603
|
+
def transient_cached_gemspec_failure?(result)
|
|
5604
|
+
return false unless execute && result && !result.ok?
|
|
5605
|
+
|
|
5606
|
+
output = [result.stdout, result.stderr].join("\n")
|
|
5607
|
+
output.include?("Bundler::GemspecError") && output.match?(/isn't a Gem::Specification \(NilClass instead\)/)
|
|
5608
|
+
end
|
|
5609
|
+
|
|
5598
5610
|
def recoverable_bundle_failure?(result)
|
|
5599
5611
|
return false unless execute && !result.ok?
|
|
5600
5612
|
|
|
@@ -5794,6 +5806,19 @@ module Kettle
|
|
|
5794
5806
|
command: template_prepare_command(member),
|
|
5795
5807
|
env: template_prepare_env(wave_jobs: wave_jobs, member: member)
|
|
5796
5808
|
)
|
|
5809
|
+
if transient_cached_gemspec_failure?(result)
|
|
5810
|
+
sleep(TEMPLATE_GEMSPEC_RETRY_DELAY_SECONDS)
|
|
5811
|
+
retry_result = runner.call(
|
|
5812
|
+
member: member,
|
|
5813
|
+
phase: "prepare_template_dependencies_retry",
|
|
5814
|
+
command: template_prepare_command(member),
|
|
5815
|
+
env: template_prepare_env(wave_jobs: wave_jobs, member: member)
|
|
5816
|
+
)
|
|
5817
|
+
unless retry_result.ok?
|
|
5818
|
+
retry_result.stderr = [result.stderr, "Initial attempt failed with a transient cached-gemspec error.", retry_result.stderr].compact.reject(&:empty?).join("\n")
|
|
5819
|
+
end
|
|
5820
|
+
result = retry_result
|
|
5821
|
+
end
|
|
5797
5822
|
if recoverable_bundle_failure?(result)
|
|
5798
5823
|
recover_template_lockfiles(
|
|
5799
5824
|
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.
|
|
4
|
+
version: 1.3.27
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -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.
|
|
571
|
-
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.3.
|
|
570
|
+
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.3.27
|
|
571
|
+
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.3.27/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.
|
|
573
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.3.27
|
|
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
|