kettle-family 0.1.10 → 0.1.11

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: 703c624ada4b7494a0a038c8a1e909c45a09b3172b581a81863f12eec6f747ce
4
- data.tar.gz: 7a71da9d94bd1945ccb091d16b6b0f6b537ff33ad00f6b42805e82cbf443a25e
3
+ metadata.gz: ce5e205f14b0d680ee20770b52bbe6567440d355f192b60df5ea5432539301df
4
+ data.tar.gz: a4b1746b3d74bd7a7ed27f08489476fb29edc9f54d118e213c5ca825f1fd3adc
5
5
  SHA512:
6
- metadata.gz: 2eceaf1a932d83e3d2ca0c4f6498fed8232735702d6454043521df1e9df48d18d92495adb3827b1fa2e5632126a64dfaabb4bcad9a01922d0eb226d8cb845161
7
- data.tar.gz: a7f8a0e30d55c3d7b75dfaed30e03ec0ba30fbc74ea6f09d321a7355ac998a4fcaa9947d4a66028ab59a06ed8a348d468ec835cb71f18ba2652c09d4f4b31b87
6
+ metadata.gz: 82ec83f5b90a6a18db54ff704a8e1387a19d674db03a6087e08afeedeab1dbf071788a6d4182a262377bd60df38f93c936ead0b3cf23efc1c0645981a956277b
7
+ data.tar.gz: c65192a2a1461b648a02dd67fbb2eacba8e01425e92c5cdbfe1b28e3a49af671a9d5a8498de7903ea4cb199ed9be8e29dcc54d5b50af9f226336a9c4a60cc25b
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,27 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [0.1.11] - 2026-06-23
34
+
35
+ - TAG: [v0.1.11][0.1.11t]
36
+ - COVERAGE: 94.51% -- 1342/1420 lines in 20 files
37
+ - BRANCH COVERAGE: 76.59% -- 458/598 branches in 20 files
38
+ - 40.40% documented
39
+
40
+ ### Fixed
41
+
42
+ - Release reports now label plain `release` as build-only mode and
43
+ `release --publish` as publish mode, making it clear when the workflow will
44
+ run `kettle-release`.
45
+ - Branch-stack release workflows now reuse the cached gem signing password in
46
+ member-local child workflows, avoiding a second signing prompt for the same
47
+ family run.
48
+ - Release workflows now cache gem signing passwords for signed build commands,
49
+ even when publishing is not enabled.
50
+ - Release workflows now normalize configured lockfiles before readiness checks
51
+ with local path dependency environment variables disabled, then commit any
52
+ resulting lockfile changes.
53
+
33
54
  ## [0.1.10] - 2026-06-23
34
55
 
35
56
  - TAG: [v0.1.10][0.1.10t]
@@ -253,7 +274,11 @@ Please file a bug if you notice a violation of semantic versioning.
253
274
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
254
275
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
255
276
 
256
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v0.1.10...HEAD
277
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v0.1.11...HEAD
278
+ [0.1.12]: https://github.com/kettle-dev/kettle-family/compare/v0.1.11...v0.1.12
279
+ [0.1.12t]: https://github.com/kettle-dev/kettle-family/releases/tag/v0.1.12
280
+ [0.1.11]: https://github.com/kettle-dev/kettle-family/compare/v0.1.10...v0.1.11
281
+ [0.1.11t]: https://github.com/kettle-dev/kettle-family/releases/tag/v0.1.11
257
282
  [0.1.10]: https://github.com/kettle-dev/kettle-family/compare/v0.1.9...v0.1.10
258
283
  [0.1.10t]: https://github.com/kettle-dev/kettle-family/releases/tag/v0.1.10
259
284
  [0.1.9]: https://github.com/kettle-dev/kettle-family/compare/v0.1.8...v0.1.9
data/README.md CHANGED
@@ -562,7 +562,7 @@ Thanks for RTFM. ☺️
562
562
  [📌gitmoji]: https://gitmoji.dev
563
563
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
564
564
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
565
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-1.378-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
565
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-1.420-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
566
566
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
567
567
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
568
568
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -177,6 +177,7 @@ module Kettle
177
177
  branch_lanes: config.branch_lanes,
178
178
  release_target_branches: config.release_target_branches,
179
179
  member_release_target_branches: member_release_target_branches(members: selected, config: config),
180
+ release_mode: release_mode(command: command, options: options),
180
181
  command: command,
181
182
  results: results
182
183
  )
@@ -332,6 +333,12 @@ module Kettle
332
333
  ReleaseStateCheck.new(config: config, members: members).results
333
334
  end
334
335
 
336
+ def release_mode(command:, options:)
337
+ return unless command == "release"
338
+
339
+ options[:publish] ? "publish" : "build-only"
340
+ end
341
+
335
342
  def member_release_target_branches(members:, config:)
336
343
  members.each_with_object({}) do |member, memo|
337
344
  member_config = member_local_release_config(member: member, config: config)
@@ -168,6 +168,22 @@ module Kettle
168
168
  fetch_path("template", "normalize_lockfiles_command") || "bundle lock"
169
169
  end
170
170
 
171
+ def release_normalize_lockfiles?
172
+ configured = fetch_path("release", "normalize_lockfiles")
173
+ return configured unless configured.nil?
174
+
175
+ normalize_lockfiles?
176
+ end
177
+
178
+ def release_normalize_lockfiles_command
179
+ fetch_path("release", "normalize_lockfiles_command") || normalize_lockfiles_command
180
+ end
181
+
182
+ def release_disable_local_path_env
183
+ configured = fetch_path("release", "disable_local_path_env")
184
+ Array(configured || default_release_disable_local_path_env)
185
+ end
186
+
171
187
  def install_local_dependencies
172
188
  paths = fetch_path("install", "local_dependencies") || fetch_path("local_dependencies") || []
173
189
  Array(paths).map do |entry|
@@ -214,6 +230,19 @@ module Kettle
214
230
 
215
231
  private
216
232
 
233
+ def default_release_disable_local_path_env
234
+ %w[
235
+ K_JEM_TEMPLATING
236
+ SMORG_RB_DEV
237
+ TREE_SITTER_LANGUAGE_PACK_DEV
238
+ KETTLE_RB_DEV
239
+ RUBOCOP_LTS_DEV
240
+ PBOLING_DEV
241
+ GALTZO_FLOSS_DEV
242
+ UR_BRAIN_DEV
243
+ ]
244
+ end
245
+
217
246
  def expand_config_relative_path(value)
218
247
  text = value.to_s
219
248
  return text if text.start_with?("/")
@@ -5,9 +5,9 @@ require "json"
5
5
  module Kettle
6
6
  module Family
7
7
  class Report
8
- attr_reader :family_name, :family_mode, :order_mode, :members, :selected_members, :config_path, :command, :results, :branch_lanes, :release_target_branches, :member_release_target_branches
8
+ attr_reader :family_name, :family_mode, :order_mode, :members, :selected_members, :config_path, :command, :results, :branch_lanes, :release_target_branches, :member_release_target_branches, :release_mode
9
9
 
10
- def initialize(family_name:, order_mode:, members:, selected_members:, config_path:, family_mode: nil, branch_lanes: {}, release_target_branches: [], member_release_target_branches: {}, command: nil, results: [])
10
+ def initialize(family_name:, order_mode:, members:, selected_members:, config_path:, family_mode: nil, branch_lanes: {}, release_target_branches: [], member_release_target_branches: {}, release_mode: nil, command: nil, results: [])
11
11
  @family_name = family_name
12
12
  @family_mode = family_mode
13
13
  @order_mode = order_mode
@@ -19,6 +19,7 @@ module Kettle
19
19
  @branch_lanes = branch_lanes
20
20
  @release_target_branches = release_target_branches
21
21
  @member_release_target_branches = member_release_target_branches
22
+ @release_mode = release_mode
22
23
  end
23
24
 
24
25
  def to_h
@@ -32,6 +33,7 @@ module Kettle
32
33
  "branch_lanes" => branch_lanes,
33
34
  "release_target_branches" => release_target_branches,
34
35
  "member_release_target_branches" => member_release_target_branches,
36
+ "release_mode" => release_mode,
35
37
  "command" => command,
36
38
  "results" => results.map(&:to_h),
37
39
  "resume_hint" => resume_hint
@@ -48,6 +50,7 @@ module Kettle
48
50
  lines << "config: #{config_path || "none"}"
49
51
  lines << "order: #{order_mode}"
50
52
  lines << "command: #{command}" if command
53
+ lines << "release mode: #{release_mode}" if release_mode
51
54
  lines << "release targets: #{release_target_branches.join(", ")}" unless release_target_branches.empty?
52
55
  append_member_release_targets(lines)
53
56
  lines << "members:"
@@ -3,7 +3,7 @@
3
3
  module Kettle
4
4
  module Family
5
5
  module Version
6
- VERSION = "0.1.10"
6
+ VERSION = "0.1.11"
7
7
  end
8
8
  VERSION = Version::VERSION # Traditional Constant Location
9
9
  end
@@ -15,7 +15,7 @@ module Kettle
15
15
  "docs" => "bundle exec rake yard"
16
16
  }.freeze
17
17
 
18
- def initialize(command:, config:, members:, execute: false, commit: true, allow_dirty: false, publish: false, push: false, tag: false, start_step: nil, local_ci: false, continue_ci_failures: false, env_overrides: {})
18
+ def initialize(command:, config:, members:, execute: false, commit: true, allow_dirty: false, publish: false, push: false, tag: false, start_step: nil, local_ci: false, continue_ci_failures: false, env_overrides: {}, gem_signing_password: nil)
19
19
  @command = command
20
20
  @config = config
21
21
  @members = members
@@ -29,11 +29,11 @@ module Kettle
29
29
  @local_ci = local_ci
30
30
  @continue_ci_failures = continue_ci_failures
31
31
  @env_overrides = env_overrides
32
- @gem_signing_password = nil
32
+ @gem_signing_password = gem_signing_password
33
33
  end
34
34
 
35
35
  def results
36
- prompt_for_gem_signing_password if command == "release" && execute && publish && gem_signing_required?
36
+ prompt_for_gem_signing_password if command == "release" && execute && release_signing_prompt_required?
37
37
  return branch_target_results unless config.release_target_branches.empty?
38
38
  return member_local_branch_target_results if member_local_branch_targets?
39
39
 
@@ -134,7 +134,8 @@ module Kettle
134
134
  start_step: start_step,
135
135
  local_ci: local_ci,
136
136
  continue_ci_failures: continue_ci_failures,
137
- env_overrides: env_overrides
137
+ env_overrides: env_overrides,
138
+ gem_signing_password: @gem_signing_password
138
139
  )
139
140
  end
140
141
 
@@ -150,6 +151,14 @@ module Kettle
150
151
  next
151
152
  end
152
153
 
154
+ if config.release_normalize_lockfiles?
155
+ normalize_release_lockfiles(member: member, runner: runner, memo: memo)
156
+ break memo unless memo.last&.ok?
157
+
158
+ commit_normalized_lockfiles(branch_members: [member], runner: runner, memo: memo, reason: "release")
159
+ break memo unless memo.last&.ok?
160
+ end
161
+
153
162
  append_release_internal_checks(member: member, memo: memo)
154
163
  break memo unless memo.last(2).all?(&:ok?)
155
164
 
@@ -158,7 +167,7 @@ module Kettle
158
167
  phase: release_phase,
159
168
  command: release_command,
160
169
  env: release_env,
161
- interactive: publish
170
+ interactive: release_command_interactive?
162
171
  )
163
172
  break memo unless memo.last.ok?
164
173
 
@@ -225,6 +234,10 @@ module Kettle
225
234
  kettle_release_command?(command) ? append_kettle_release_args(command) : command
226
235
  end
227
236
 
237
+ def release_command_interactive?
238
+ publish || !!@gem_signing_password
239
+ end
240
+
228
241
  def kettle_release_command?(command)
229
242
  case command
230
243
  when Array
@@ -292,11 +305,25 @@ module Kettle
292
305
  !ENV.fetch("SKIP_GEM_SIGNING", "").casecmp("true").zero?
293
306
  end
294
307
 
308
+ def release_signing_prompt_required?
309
+ return false unless gem_signing_required?
310
+ return true if publish
311
+
312
+ members.any? { |member| signed_gemspec?(member) }
313
+ end
314
+
315
+ def signed_gemspec?(member)
316
+ return false unless member.gemspec_path && File.file?(member.gemspec_path)
317
+
318
+ content = File.read(member.gemspec_path)
319
+ content.include?("signing_key") || content.include?("cert_chain")
320
+ end
321
+
295
322
  def prompt_for_gem_signing_password
296
323
  return if @gem_signing_password
297
324
 
298
325
  print("Gem signing key password (cached for this family release; MFA prompts still remain interactive): ")
299
- @gem_signing_password = if $stdin.respond_to?(:noecho)
326
+ @gem_signing_password = if $stdin.respond_to?(:noecho) && $stdin.tty?
300
327
  $stdin.noecho(&:gets)&.chomp
301
328
  else
302
329
  $stdin.gets&.chomp
@@ -361,8 +388,23 @@ module Kettle
361
388
  memo << result
362
389
  end
363
390
 
364
- def commit_normalized_lockfiles(branch_members:, runner:, memo:)
365
- return unless command == "template" && config.normalize_lockfiles? && commit
391
+ def normalize_release_lockfiles(member:, runner:, memo:)
392
+ result = runner.call(
393
+ member: member,
394
+ phase: "release_normalize_lockfiles",
395
+ command: config.release_normalize_lockfiles_command,
396
+ env: release_lockfile_env
397
+ )
398
+ memo << result
399
+ end
400
+
401
+ def release_lockfile_env
402
+ release_env.merge(config.release_disable_local_path_env.to_h { |key| [key, "false"] })
403
+ end
404
+
405
+ def commit_normalized_lockfiles(branch_members:, runner:, memo:, reason: command)
406
+ return unless commit
407
+ return unless commit_normalized_lockfiles?(reason)
366
408
 
367
409
  branch_members.each do |member|
368
410
  result = runner.call(
@@ -380,6 +422,17 @@ module Kettle
380
422
  end
381
423
  end
382
424
 
425
+ def commit_normalized_lockfiles?(reason)
426
+ case reason
427
+ when "template"
428
+ config.normalize_lockfiles?
429
+ when "release"
430
+ config.release_normalize_lockfiles?
431
+ else
432
+ false
433
+ end
434
+ end
435
+
383
436
  def family_member
384
437
  Member.new(
385
438
  name: config.family_name,
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: 0.1.10
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -309,10 +309,10 @@ licenses:
309
309
  - AGPL-3.0-only
310
310
  metadata:
311
311
  homepage_uri: https://kettle-family.galtzo.com
312
- source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v0.1.10
313
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v0.1.10/CHANGELOG.md
312
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v0.1.11
313
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v0.1.11/CHANGELOG.md
314
314
  bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
315
- documentation_uri: https://www.rubydoc.info/gems/kettle-family/0.1.10
315
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/0.1.11
316
316
  funding_uri: https://github.com/sponsors/pboling
317
317
  wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
318
318
  news_uri: https://www.railsbling.com/tags/kettle-family
metadata.gz.sig CHANGED
Binary file