kettle-family 1.2.57 → 1.2.58

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: 52aa49a65290b1653f400046c8d546cc2df665a4bdc84caf8b0340263d1cb690
4
- data.tar.gz: e24c1ec35cfe71dbbad12d18c58a9f8ef9806074bf4047e615012791d0559c99
3
+ metadata.gz: 34d40e983c125c689f16bf8ca75d566190006c61796efd6c403ed341df8f067b
4
+ data.tar.gz: 118ebf6ca455659ed4b0789b5fed52f301c4bf89990ced82f5ea64ead678712e
5
5
  SHA512:
6
- metadata.gz: 0f33b6e0dac6143695041e5ca5de53dff3855b7bbfbbbe3750426dc140171464d4ae5ee0f97a42636362fed3ace79ff20e82320b72a16030003a2847ec1d4f15
7
- data.tar.gz: d65b31d38b3585bed66c85499e97f98f0f0a6998a55cb73b167a991f0cd111af482399d44b1c64d3dbf838932b0b96b3e26a9ac0a806bc496b167926661a4cc6
6
+ metadata.gz: 2dce07e1ffe8a539914a1916278e530a38dbed599672f49360e4d97ec49e48496860d61812c0bee3fccd980ec867dbdd7371ffc406a793ac9e4c0c70a5f7e86c
7
+ data.tar.gz: a0c7eec1e7992797dc59d459bda064302e93353ae66c7239182c2a16f4515fc15f3a3f48463d7b5a076b0a1679d58d08c9ebc05e603d2d196afbd52af670fc14
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,17 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.2.58] - 2026-08-23
34
+
35
+ - TAG: [v1.2.58][1.2.58t]
36
+ - COVERAGE: 93.50% -- 5354/5726 lines in 33 files
37
+ - BRANCH COVERAGE: 76.29% -- 2169/2843 branches in 33 files
38
+ - 29.78% documented
39
+
40
+ ### Added
41
+
42
+ - Family releases support member-scoped CI fast recovery and an explicit global remote-CI bypass.
43
+
33
44
  ## [1.2.57] - 2026-08-23
34
45
 
35
46
  - TAG: [v1.2.57][1.2.57t]
@@ -2142,7 +2153,9 @@ Please file a bug if you notice a violation of semantic versioning.
2142
2153
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
2143
2154
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
2144
2155
 
2145
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.57...HEAD
2156
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.58...HEAD
2157
+ [1.2.58]: https://github.com/kettle-dev/kettle-family/compare/v1.2.57...v1.2.58
2158
+ [1.2.58t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.58
2146
2159
  [1.2.57]: https://github.com/kettle-dev/kettle-family/compare/v1.2.56...v1.2.57
2147
2160
  [1.2.57t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.57
2148
2161
  [1.2.56]: https://github.com/kettle-dev/kettle-family/compare/v1.2.55...v1.2.56
data/README.md CHANGED
@@ -432,6 +432,26 @@ and leaves RubyGems MFA prompts interactive by default:
432
432
  kettle-family release --publish --execute
433
433
  ```
434
434
 
435
+ Use named recovery modes when a publish wave has already prepared a member:
436
+
437
+ ```console
438
+ kettle-family release --publish --execute --fast-recovery retry-ci --fast-recovery-members gem_name
439
+ kettle-family release --publish --execute --fast-recovery skip-ci --fast-recovery-members gem_name
440
+ ```
441
+
442
+ `retry-ci` resumes the named members at CI monitoring; `skip-ci` bypasses that
443
+ monitor and continues with the merge and publish steps. Both modes are intended
444
+ only for the same release commit. They apply only to the named members, so other
445
+ members continue their normal release flow. To run every selected member from
446
+ step 0 while skipping remote CI monitoring, use `--skip-ci` instead:
447
+
448
+ ```console
449
+ kettle-family release --publish --execute --skip-ci
450
+ ```
451
+
452
+ The existing `--continue-ci-failures` option still monitors CI and only changes
453
+ whether a failed result blocks the release; it does not skip CI monitoring.
454
+
435
455
  By default, family publish runs pass `--yes` to configured `kettle-changelog`
436
456
  family changelog commands and child `kettle-release` commands. Use
437
457
  `--no-accept` when you want each child command to ask its own confirmation
@@ -836,7 +856,7 @@ Thanks for RTFM. ☺️
836
856
  [📌gitmoji]: https://gitmoji.dev
837
857
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
838
858
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
839
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-5.667-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
859
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-5.726-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
840
860
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
841
861
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
842
862
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -160,6 +160,9 @@ module Kettle
160
160
  publish: false,
161
161
  release_start_step: nil,
162
162
  release_skip_steps: nil,
163
+ release_fast_recovery: nil,
164
+ release_fast_recovery_members: nil,
165
+ release_skip_ci: false,
163
166
  release_skip_changelog: false,
164
167
  release_local_ci: false,
165
168
  release_continue_ci_failures: false,
@@ -520,6 +523,9 @@ module Kettle
520
523
  end
521
524
  option :start_step, long: "--start-step", value: {type: Integer, usage: "N"}, desc: "Pass start_step=N through to kettle-release commands"
522
525
  option :skip_steps, long: "--skip-steps", value: {type: String, usage: "LIST"}, desc: "Pass skip_steps=LIST through to kettle-release commands"
526
+ option :fast_recovery, long: "--fast-recovery", value: {type: String, usage: "MODE"}, desc: "Recover selected CI failures with retry-ci or skip-ci"
527
+ option :fast_recovery_members, long: "--fast-recovery-members", value: {type: String, usage: "MEMBERS"}, desc: "Limit fast recovery to comma-separated selected members"
528
+ option :skip_ci, long: "--skip-ci", desc: "Skip remote CI monitoring for every selected member while running from step 0"
523
529
  option :skip_changelog, long: "--skip-changelog", desc: "Run pre-release gates and specs, but skip kettle-changelog"
524
530
  option :local_ci, long: "--local-ci", desc: "Pass --local-ci through to kettle-release commands"
525
531
  option :continue_ci_failures, long: "--continue-ci-failures", desc: "Set K_RELEASE_CI_CONTINUE=true for release commands"
@@ -545,6 +551,9 @@ module Kettle
545
551
  publish: truthy_option?(:publish),
546
552
  release_start_step: options[:start_step],
547
553
  release_skip_steps: options[:skip_steps],
554
+ release_fast_recovery: options[:fast_recovery],
555
+ release_fast_recovery_members: options[:fast_recovery_members],
556
+ release_skip_ci: truthy_option?(:skip_ci),
548
557
  release_skip_changelog: truthy_option?(:skip_changelog),
549
558
  release_local_ci: truthy_option?(:local_ci),
550
559
  release_continue_ci_failures: truthy_option?(:continue_ci_failures),
@@ -817,6 +826,9 @@ module Kettle
817
826
  tag: options[:tag],
818
827
  start_step: options[:release_start_step],
819
828
  skip_steps: options[:release_skip_steps],
829
+ fast_recovery: options[:release_fast_recovery],
830
+ fast_recovery_members: options[:release_fast_recovery_members],
831
+ skip_ci: options[:release_skip_ci],
820
832
  skip_changelog: options[:release_skip_changelog],
821
833
  local_ci: options[:release_local_ci],
822
834
  continue_ci_failures: options[:release_continue_ci_failures],
@@ -915,6 +927,18 @@ module Kettle
915
927
  start_label = start_at.branch ? "#{start_at.member}@#{start_at.branch}" : start_at.member
916
928
  stdout.puts(" start: #{start_label}") if start_at.member
917
929
  stdout.puts(" members: #{members.map(&:name).join(", ")}")
930
+ if options[:release_fast_recovery]
931
+ fast_members = options[:release_fast_recovery_members] || "selected members"
932
+ stdout.puts(" fast recovery: #{options[:release_fast_recovery]} (#{fast_members})")
933
+ recovery_warning = if options[:release_fast_recovery].to_s.tr("_", "-") == "retry-ci"
934
+ "fast recovery resumes the named members at CI monitoring; use only for the same release commit"
935
+ else
936
+ "fast recovery bypasses CI monitoring for the named members; use only for the same release commit"
937
+ end
938
+ stdout.puts(" warning: #{recovery_warning}")
939
+ elsif options[:release_skip_ci]
940
+ stdout.puts(" warning: remote CI monitoring is skipped for every selected member")
941
+ end
918
942
  stdout.flush
919
943
  countdown_before_execution
920
944
  end
@@ -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.57"
8
+ VERSION = "1.2.58"
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:, family_members: nil, 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)
105
+ def initialize(command:, config:, members:, family_members: nil, execute: false, accept: true, commit: true, allow_dirty: false, autostash: 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, 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
@@ -117,6 +117,19 @@ module Kettle
117
117
  @tag = tag
118
118
  @start_step = start_step
119
119
  @skip_steps = skip_steps
120
+ @fast_recovery = normalize_fast_recovery(fast_recovery, publish: publish)
121
+ if (@fast_recovery || skip_ci) && !kettle_release_command?(raw_release_command)
122
+ raise Error, "named CI recovery requires a kettle-release publish command"
123
+ end
124
+ raise Error, "--skip-ci requires --publish" if skip_ci && !publish
125
+ if @fast_recovery && (start_step || (skip_steps && !skip_steps.to_s.empty?) || skip_ci)
126
+ raise Error, "--fast-recovery cannot be combined with --start-step, --skip-steps, or --skip-ci"
127
+ end
128
+ if fast_recovery_members_given?(fast_recovery_members) && !@fast_recovery
129
+ raise Error, "--fast-recovery-members requires --fast-recovery"
130
+ end
131
+ @fast_recovery_members = normalize_fast_recovery_members(fast_recovery_members)
132
+ @skip_ci = !!skip_ci
120
133
  @skip_changelog = !!skip_changelog
121
134
  @local_ci = local_ci
122
135
  @continue_ci_failures = continue_ci_failures
@@ -186,7 +199,7 @@ module Kettle
186
199
  execute && release_command_delegates_secrets_to_kettle_release?
187
200
  end
188
201
 
189
- attr_reader :command, :config, :members, :family_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
202
+ attr_reader :command, :config, :members, :family_members, :execute, :accept, :commit, :allow_dirty, :autostash, :publish, :push, :tag, :start_step, :skip_steps, :fast_recovery, :fast_recovery_members, :skip_ci, :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
190
203
 
191
204
  def template_with_worktree_sync_results
192
205
  runner = command_runner
@@ -1096,6 +1109,9 @@ module Kettle
1096
1109
  tag: tag,
1097
1110
  start_step: start_step,
1098
1111
  skip_steps: skip_steps,
1112
+ fast_recovery: fast_recovery,
1113
+ fast_recovery_members: fast_recovery_members,
1114
+ skip_ci: skip_ci,
1099
1115
  skip_changelog: skip_changelog,
1100
1116
  local_ci: local_ci,
1101
1117
  continue_ci_failures: continue_ci_failures,
@@ -1286,7 +1302,7 @@ module Kettle
1286
1302
  release_result = runner.call(
1287
1303
  member: member,
1288
1304
  phase: release_phase,
1289
- command: release_command,
1305
+ command: release_command_for(member),
1290
1306
  env: release_env_for_member(member),
1291
1307
  interactive: release_command_interactive?,
1292
1308
  stdout_line_handler: release_event_line_handler(member, progress: progress),
@@ -1915,7 +1931,7 @@ module Kettle
1915
1931
  CommandResult.new(
1916
1932
  member_name: member.name,
1917
1933
  phase: release_phase,
1918
- command: release_command,
1934
+ command: release_command_for(member),
1919
1935
  workdir: member.root,
1920
1936
  status: nil,
1921
1937
  success: true,
@@ -2032,8 +2048,12 @@ module Kettle
2032
2048
  end
2033
2049
 
2034
2050
  def release_command
2051
+ release_command_for(nil)
2052
+ end
2053
+
2054
+ def release_command_for(member)
2035
2055
  command = raw_release_command
2036
- kettle_release_command?(command) ? append_kettle_release_args(command) : command
2056
+ kettle_release_command?(command) ? append_kettle_release_args(command, member: member) : command
2037
2057
  end
2038
2058
 
2039
2059
  def family_changelog_command
@@ -2077,11 +2097,13 @@ module Kettle
2077
2097
  end
2078
2098
  end
2079
2099
 
2080
- def append_kettle_release_args(command)
2100
+ def append_kettle_release_args(command, member: nil)
2081
2101
  command = replace_kettle_release_provider(command) if @release_secrets_broker
2082
2102
  args = []
2083
- args << "start_step=#{start_step}" if start_step
2084
- args << "skip_steps=#{skip_steps}" if skip_steps && !skip_steps.to_s.empty?
2103
+ effective_start_step = release_start_step_for(member)
2104
+ effective_skip_steps = release_skip_steps_for(member)
2105
+ args << "start_step=#{effective_start_step}" if effective_start_step
2106
+ args << "skip_steps=#{effective_skip_steps}" unless effective_skip_steps.empty?
2085
2107
  args << "--skip-changelog" if skip_changelog
2086
2108
  args << "--ci-workflows=#{ci_workflows}" if ci_workflows && !ci_workflows.to_s.empty?
2087
2109
  args << "--local-ci" if local_ci
@@ -2099,6 +2121,25 @@ module Kettle
2099
2121
  command.is_a?(Array) ? [*command, *args] : "#{command} #{args.join(" ")}"
2100
2122
  end
2101
2123
 
2124
+ def release_start_step_for(member)
2125
+ return start_step unless fast_recovery_for?(member)
2126
+
2127
+ (fast_recovery == "retry-ci") ? 10 : 11
2128
+ end
2129
+
2130
+ def release_skip_steps_for(_member)
2131
+ steps = Array(skip_steps).flat_map { |entry| entry.to_s.split(",") }.map(&:strip).reject(&:empty?)
2132
+ steps << "10" if skip_ci
2133
+ steps.uniq.join(",")
2134
+ end
2135
+
2136
+ def fast_recovery_for?(member)
2137
+ return false unless fast_recovery
2138
+ return false unless member
2139
+
2140
+ fast_recovery_members.include?(member.name)
2141
+ end
2142
+
2102
2143
  def replace_kettle_release_provider(command)
2103
2144
  case command
2104
2145
  when Array
@@ -2129,6 +2170,43 @@ module Kettle
2129
2170
  workflows.join(",")
2130
2171
  end
2131
2172
 
2173
+ def normalize_fast_recovery(value, publish:)
2174
+ return nil if value.nil? || value.to_s.strip.empty?
2175
+ raise Error, "--fast-recovery requires --publish" unless publish
2176
+
2177
+ mode = value.to_s.strip.downcase.tr("_", "-")
2178
+ return mode if %w[retry-ci skip-ci].include?(mode)
2179
+
2180
+ raise Error, "invalid --fast-recovery value #{value.inspect}; use retry-ci or skip-ci"
2181
+ end
2182
+
2183
+ def normalize_fast_recovery_members(value)
2184
+ return [] unless fast_recovery
2185
+
2186
+ names = if value.nil? || value.to_s.strip.empty?
2187
+ members.map(&:name)
2188
+ else
2189
+ value.to_s.split(",").map(&:strip).reject(&:empty?).uniq
2190
+ end
2191
+ raise Error, "--fast-recovery-members requires at least one member" if names.empty?
2192
+
2193
+ known = family_members.map(&:name)
2194
+ unknown = names - known
2195
+ raise Error, "unknown fast recovery member(s): #{unknown.join(", ")}" unless unknown.empty?
2196
+
2197
+ selected = members.map(&:name)
2198
+ unselected = names - selected
2199
+ unless unselected.empty?
2200
+ raise Error, "fast recovery member(s) must be selected: #{unselected.join(", ")}"
2201
+ end
2202
+
2203
+ names
2204
+ end
2205
+
2206
+ def fast_recovery_members_given?(value)
2207
+ Array(value).flat_map { |entry| entry.to_s.split(",") }.map(&:strip).reject(&:empty?).any?
2208
+ end
2209
+
2132
2210
  def validate_remote_list(value, option_name)
2133
2211
  return nil if value.nil?
2134
2212
 
data.tar.gz.sig CHANGED
@@ -1,2 +1 @@
1
- 'a*��G��ߠ��\�-xv�O%E]��9ָ����?��lɒ�٪�#&�ԁ�h}f�n4�^ �cn�����Yj��o��;=sd2�1`&\�ܩs&��}.`�~�+\�C���"u�}��N�0n��ymI�‘9:�r���W���Đ��Z�0� ���P��Uw%4�qnZsچ*ӣ\!)Ӎ5CX�<QW,c��̆���d]����d���`ߤJ%��.�}&�RcTn�����~�S��
2
- Z���[I�>h��V�����R��gG���)�[y���W� �k�J
1
+ r�%��k���������
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.57
4
+ version: 1.2.58
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -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.57
365
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.57/CHANGELOG.md
364
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.58
365
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.58/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.57
367
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.58
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