kettle-family 1.1.5 → 1.1.6
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 +30 -1
- data/README.md +1 -1
- data/lib/kettle/family/command_runner.rb +95 -10
- data/lib/kettle/family/report.rb +27 -1
- data/lib/kettle/family/version.rb +1 -1
- data/lib/kettle/family/workflow.rb +9 -3
- 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: 98d4c89b4fe8c5b8dc01b6b16624771da61982b4393117243b8888ca0c34358f
|
|
4
|
+
data.tar.gz: b6e7db140bf96d05083d2fc9239b1721528c6f587563ecfe6313b9f936354b47
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e181e19e17b26a281ec9787dac2fdfcba5811107b35a3bd0fb943411df3d7e2c9aee10903ed846939353d5c7c344992d8397e241e2497a959151bf2742e9f4d
|
|
7
|
+
data.tar.gz: 155c75272299e2a04c342bcadbb4a6d07d9b7a86154e4c4c177074678cc6c07ed7dc44042ce695d1baed49ea918b57215060bf98e073fc89397f081de5245427
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,33 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [1.1.6] - 2026-07-25
|
|
34
|
+
|
|
35
|
+
- TAG: [v1.1.6][1.1.6t]
|
|
36
|
+
- COVERAGE: 95.19% -- 3084/3240 lines in 25 files
|
|
37
|
+
- BRANCH COVERAGE: 76.80% -- 1132/1474 branches in 25 files
|
|
38
|
+
- 28.68% documented
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Release summaries now count only members that reached a release terminal
|
|
43
|
+
phase as succeeded, so dependency-floor side effects do not appear as
|
|
44
|
+
published gems after an earlier failure.
|
|
45
|
+
- Dependency-floor lockfile refresh now uses checksum-aware Bundler locking
|
|
46
|
+
(`bundle lock --update ... --add-checksums`) before validating just-published
|
|
47
|
+
sibling floors, so missing or empty checksum entries still retry and fail
|
|
48
|
+
instead of being accepted.
|
|
49
|
+
- Interactive release commands now suppress consumed `kettle-release --events`
|
|
50
|
+
NDJSON lines from terminal output while keeping them captured for progress and
|
|
51
|
+
failure summaries.
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- kettle-jem-template-20260725-001 - Generated JRuby and TruffleRuby workflow
|
|
56
|
+
files now run when pull request head branches start with `feature/release`,
|
|
57
|
+
so release CI monitoring does not report intentionally skipped engine
|
|
58
|
+
workflows as failures.
|
|
59
|
+
|
|
33
60
|
## [1.1.5] - 2026-07-25
|
|
34
61
|
|
|
35
62
|
- TAG: [v1.1.5][1.1.5t]
|
|
@@ -986,7 +1013,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
986
1013
|
- Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
|
|
987
1014
|
- Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
|
|
988
1015
|
|
|
989
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.1.
|
|
1016
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.1.6...HEAD
|
|
1017
|
+
[1.1.6]: https://github.com/kettle-dev/kettle-family/compare/v1.1.5...v1.1.6
|
|
1018
|
+
[1.1.6t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.1.6
|
|
990
1019
|
[1.1.5]: https://github.com/kettle-dev/kettle-family/compare/v1.1.4...v1.1.5
|
|
991
1020
|
[1.1.5t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.1.5
|
|
992
1021
|
[1.1.4]: https://github.com/kettle-dev/kettle-family/compare/v1.1.3...v1.1.4
|
data/README.md
CHANGED
|
@@ -669,7 +669,7 @@ Thanks for RTFM. ☺️
|
|
|
669
669
|
[📌gitmoji]: https://gitmoji.dev
|
|
670
670
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
671
671
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
672
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.
|
|
672
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.240-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
673
673
|
[🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
|
|
674
674
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
675
675
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -119,7 +119,14 @@ module Kettle
|
|
|
119
119
|
|
|
120
120
|
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
121
121
|
stdout, stderr, status = if interactive
|
|
122
|
-
run_interactive(
|
|
122
|
+
run_interactive(
|
|
123
|
+
env: process_env,
|
|
124
|
+
argv: argv,
|
|
125
|
+
chdir: member.root,
|
|
126
|
+
member_name: member.name,
|
|
127
|
+
process_options: spawn_options,
|
|
128
|
+
stdout_line_handler: stdout_line_handler
|
|
129
|
+
)
|
|
123
130
|
elsif stdout_line_handler
|
|
124
131
|
run_streaming(env: process_env, argv: argv, chdir: member.root, process_options: spawn_options, stdout_line_handler: stdout_line_handler)
|
|
125
132
|
else
|
|
@@ -183,14 +190,31 @@ module Kettle
|
|
|
183
190
|
remainder
|
|
184
191
|
end
|
|
185
192
|
|
|
186
|
-
def run_interactive(env:, argv:, chdir:, member_name:, process_options:)
|
|
187
|
-
|
|
193
|
+
def run_interactive(env:, argv:, chdir:, member_name:, process_options:, stdout_line_handler:)
|
|
194
|
+
if pty_available?
|
|
195
|
+
return run_interactive_pty(
|
|
196
|
+
env: env,
|
|
197
|
+
argv: argv,
|
|
198
|
+
chdir: chdir,
|
|
199
|
+
member_name: member_name,
|
|
200
|
+
process_options: process_options,
|
|
201
|
+
stdout_line_handler: stdout_line_handler
|
|
202
|
+
)
|
|
203
|
+
end
|
|
188
204
|
|
|
189
|
-
run_interactive_open3(
|
|
205
|
+
run_interactive_open3(
|
|
206
|
+
env: env,
|
|
207
|
+
argv: argv,
|
|
208
|
+
chdir: chdir,
|
|
209
|
+
member_name: member_name,
|
|
210
|
+
process_options: process_options,
|
|
211
|
+
stdout_line_handler: stdout_line_handler
|
|
212
|
+
)
|
|
190
213
|
end
|
|
191
214
|
|
|
192
|
-
def run_interactive_pty(env:, argv:, chdir:, member_name:, process_options:)
|
|
215
|
+
def run_interactive_pty(env:, argv:, chdir:, member_name:, process_options:, stdout_line_handler:)
|
|
193
216
|
stdout = +""
|
|
217
|
+
stdout_line_buffer = +""
|
|
194
218
|
status = nil
|
|
195
219
|
PTY.spawn(env, *argv, chdir: chdir, **process_options) do |output, input, pid|
|
|
196
220
|
begin
|
|
@@ -202,7 +226,7 @@ module Kettle
|
|
|
202
226
|
if reader.equal?(output)
|
|
203
227
|
chunk = output.readpartial(1024)
|
|
204
228
|
stdout << chunk
|
|
205
|
-
|
|
229
|
+
stdout_line_buffer = print_interactive_stdout(stdout_line_buffer, chunk, stdout_line_handler)
|
|
206
230
|
handle_interactive_prompt(input, chunk, member_name: member_name)
|
|
207
231
|
else
|
|
208
232
|
input.write($stdin.readpartial(1024))
|
|
@@ -212,14 +236,16 @@ module Kettle
|
|
|
212
236
|
rescue Errno::EIO
|
|
213
237
|
# PTY raises EIO when the child process exits after closing the slave.
|
|
214
238
|
end
|
|
239
|
+
flush_interactive_stdout(stdout_line_buffer, stdout_line_handler)
|
|
215
240
|
_, status = Process.wait2(pid)
|
|
216
241
|
end
|
|
217
242
|
[stdout, "", status]
|
|
218
243
|
end
|
|
219
244
|
|
|
220
|
-
def run_interactive_open3(env:, argv:, chdir:, member_name:, process_options:)
|
|
245
|
+
def run_interactive_open3(env:, argv:, chdir:, member_name:, process_options:, stdout_line_handler:)
|
|
221
246
|
captured_stdout = +""
|
|
222
247
|
captured_stderr = +""
|
|
248
|
+
stdout_line_buffer = +""
|
|
223
249
|
status = nil
|
|
224
250
|
Open3.popen3(env, *argv, chdir: chdir, **process_options) do |input, output, error, wait_thread|
|
|
225
251
|
readers = [output, error]
|
|
@@ -230,27 +256,86 @@ module Kettle
|
|
|
230
256
|
if reader.equal?($stdin)
|
|
231
257
|
input.write($stdin.readpartial(1024))
|
|
232
258
|
else
|
|
233
|
-
read_interactive_stream(
|
|
259
|
+
stdout_line_buffer = read_interactive_stream(
|
|
260
|
+
reader,
|
|
261
|
+
output,
|
|
262
|
+
input,
|
|
263
|
+
captured_stdout,
|
|
264
|
+
captured_stderr,
|
|
265
|
+
readers,
|
|
266
|
+
member_name: member_name,
|
|
267
|
+
stdout_line_buffer: stdout_line_buffer,
|
|
268
|
+
stdout_line_handler: stdout_line_handler
|
|
269
|
+
)
|
|
234
270
|
end
|
|
235
271
|
end
|
|
236
272
|
end
|
|
273
|
+
flush_interactive_stdout(stdout_line_buffer, stdout_line_handler)
|
|
237
274
|
status = wait_thread.value
|
|
238
275
|
end
|
|
239
276
|
[captured_stdout, captured_stderr, status]
|
|
240
277
|
end
|
|
241
278
|
|
|
242
|
-
def read_interactive_stream(
|
|
279
|
+
def read_interactive_stream(
|
|
280
|
+
reader,
|
|
281
|
+
output,
|
|
282
|
+
input,
|
|
283
|
+
captured_stdout,
|
|
284
|
+
captured_stderr,
|
|
285
|
+
readers,
|
|
286
|
+
member_name:,
|
|
287
|
+
stdout_line_buffer:,
|
|
288
|
+
stdout_line_handler:
|
|
289
|
+
)
|
|
243
290
|
chunk = reader.readpartial(1024)
|
|
244
291
|
if reader.equal?(output)
|
|
245
292
|
captured_stdout << chunk
|
|
246
|
-
|
|
293
|
+
stdout_line_buffer = print_interactive_stdout(stdout_line_buffer, chunk, stdout_line_handler)
|
|
247
294
|
else
|
|
248
295
|
captured_stderr << chunk
|
|
249
296
|
$stderr.print(chunk)
|
|
250
297
|
end
|
|
251
298
|
handle_interactive_prompt(input, chunk, member_name: member_name)
|
|
299
|
+
stdout_line_buffer
|
|
252
300
|
rescue EOFError
|
|
253
301
|
readers.delete(reader)
|
|
302
|
+
stdout_line_buffer
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def print_interactive_stdout(buffer, chunk, stdout_line_handler)
|
|
306
|
+
return print_interactive_chunk(chunk) unless stdout_line_handler
|
|
307
|
+
|
|
308
|
+
pending = buffer + chunk
|
|
309
|
+
lines = pending.lines
|
|
310
|
+
remainder = pending.end_with?("\n") ? +"" : lines.pop.to_s
|
|
311
|
+
lines.each { |line| print_interactive_line(line, stdout_line_handler) }
|
|
312
|
+
return +"" if remainder.empty?
|
|
313
|
+
unless possible_event_line?(remainder)
|
|
314
|
+
$stdout.print(remainder)
|
|
315
|
+
return +""
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
remainder
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def flush_interactive_stdout(buffer, stdout_line_handler)
|
|
322
|
+
return if buffer.empty?
|
|
323
|
+
|
|
324
|
+
print_interactive_line(buffer, stdout_line_handler)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def print_interactive_chunk(chunk)
|
|
328
|
+
$stdout.print(chunk)
|
|
329
|
+
+""
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def print_interactive_line(line, stdout_line_handler)
|
|
333
|
+
consumed = possible_event_line?(line) && stdout_line_handler.call(line.chomp)
|
|
334
|
+
$stdout.print(line) unless consumed
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def possible_event_line?(line)
|
|
338
|
+
line.to_s.lstrip.start_with?("{")
|
|
254
339
|
end
|
|
255
340
|
|
|
256
341
|
def pty_available?
|
data/lib/kettle/family/report.rb
CHANGED
|
@@ -314,6 +314,8 @@ module Kettle
|
|
|
314
314
|
|
|
315
315
|
def summary_succeeded
|
|
316
316
|
selected_member_results.filter_map do |member_name, member_results|
|
|
317
|
+
next if member_results.empty?
|
|
318
|
+
member_results = summary_terminal_member_results(member_results)
|
|
317
319
|
next if member_results.empty?
|
|
318
320
|
next if member_results.any? { |result| !result.ok? }
|
|
319
321
|
next if member_results.all?(&:skipped)
|
|
@@ -324,6 +326,8 @@ module Kettle
|
|
|
324
326
|
|
|
325
327
|
def summary_skipped
|
|
326
328
|
selected_member_results.filter_map do |member_name, member_results|
|
|
329
|
+
next if member_results.empty?
|
|
330
|
+
member_results = summary_terminal_member_results(member_results)
|
|
327
331
|
next if member_results.empty?
|
|
328
332
|
next unless member_results.all?(&:skipped)
|
|
329
333
|
|
|
@@ -345,7 +349,7 @@ module Kettle
|
|
|
345
349
|
return [] unless member_result_command?
|
|
346
350
|
return [] if visible_results.empty?
|
|
347
351
|
|
|
348
|
-
ran =
|
|
352
|
+
ran = summary_ran_member_names
|
|
349
353
|
reason = pending_reason
|
|
350
354
|
(selected_names - ran).map do |member_name|
|
|
351
355
|
{
|
|
@@ -364,6 +368,28 @@ module Kettle
|
|
|
364
368
|
end
|
|
365
369
|
end
|
|
366
370
|
|
|
371
|
+
def summary_ran_member_names
|
|
372
|
+
return selected_member_results.keys unless command == "release"
|
|
373
|
+
|
|
374
|
+
failed = visible_results.reject(&:ok?).map(&:member_name)
|
|
375
|
+
terminal = selected_member_results.filter_map do |member_name, member_results|
|
|
376
|
+
member_name if member_results.any? { |result| release_terminal_result?(result) }
|
|
377
|
+
end
|
|
378
|
+
(failed + terminal).uniq
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def summary_terminal_member_results(member_results)
|
|
382
|
+
return member_results unless command == "release"
|
|
383
|
+
|
|
384
|
+
member_results.select { |result| release_terminal_result?(result) }
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def release_terminal_result?(result)
|
|
388
|
+
result.phase == "release_skip" ||
|
|
389
|
+
result.phase == "release_publish" ||
|
|
390
|
+
result.phase == "release_build"
|
|
391
|
+
end
|
|
392
|
+
|
|
367
393
|
def summary_list(values)
|
|
368
394
|
values.empty? ? "none" : values.join(", ")
|
|
369
395
|
end
|
|
@@ -623,7 +623,7 @@ module Kettle
|
|
|
623
623
|
result = runner.call(
|
|
624
624
|
member: member,
|
|
625
625
|
phase: "dependency_floor_lockfiles",
|
|
626
|
-
command:
|
|
626
|
+
command: dependency_floor_lockfile_command(released_members),
|
|
627
627
|
env: release_lockfile_env
|
|
628
628
|
)
|
|
629
629
|
validate_dependency_floor_lockfile_result(result: result, member: member, released_members: released_members) if result.ok?
|
|
@@ -659,6 +659,10 @@ module Kettle
|
|
|
659
659
|
end
|
|
660
660
|
end
|
|
661
661
|
|
|
662
|
+
def dependency_floor_lockfile_command(released_members)
|
|
663
|
+
["bundle", "lock", "--update", *released_members.map(&:name), "--add-checksums"]
|
|
664
|
+
end
|
|
665
|
+
|
|
662
666
|
def checksum_line_for(lockfile_source:, member:)
|
|
663
667
|
in_checksums = false
|
|
664
668
|
lockfile_source.each_line do |line|
|
|
@@ -1220,13 +1224,14 @@ module Kettle
|
|
|
1220
1224
|
|
|
1221
1225
|
lambda do |line|
|
|
1222
1226
|
event = parse_template_event(line)
|
|
1223
|
-
next unless event
|
|
1227
|
+
next false unless event
|
|
1224
1228
|
|
|
1225
1229
|
if verbose || debug
|
|
1226
1230
|
emit_template_event_progress(member, event)
|
|
1227
1231
|
else
|
|
1228
1232
|
emit_template_event_status(member, event, progress: progress)
|
|
1229
1233
|
end
|
|
1234
|
+
true
|
|
1230
1235
|
end
|
|
1231
1236
|
end
|
|
1232
1237
|
|
|
@@ -1236,13 +1241,14 @@ module Kettle
|
|
|
1236
1241
|
|
|
1237
1242
|
lambda do |line|
|
|
1238
1243
|
event = parse_template_event(line)
|
|
1239
|
-
next unless event
|
|
1244
|
+
next false unless event
|
|
1240
1245
|
|
|
1241
1246
|
if verbose || debug
|
|
1242
1247
|
emit_release_event_progress(member, event)
|
|
1243
1248
|
else
|
|
1244
1249
|
emit_release_event_status(member, event, progress: progress)
|
|
1245
1250
|
end
|
|
1251
|
+
true
|
|
1246
1252
|
end
|
|
1247
1253
|
end
|
|
1248
1254
|
|
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.1.
|
|
4
|
+
version: 1.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -319,10 +319,10 @@ licenses:
|
|
|
319
319
|
- AGPL-3.0-only
|
|
320
320
|
metadata:
|
|
321
321
|
homepage_uri: https://kettle-family.galtzo.com
|
|
322
|
-
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.1.
|
|
323
|
-
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.1.
|
|
322
|
+
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.1.6
|
|
323
|
+
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.1.6/CHANGELOG.md
|
|
324
324
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
|
|
325
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.1.
|
|
325
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.1.6
|
|
326
326
|
funding_uri: https://github.com/sponsors/pboling
|
|
327
327
|
wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
|
|
328
328
|
news_uri: https://www.railsbling.com/tags/kettle-family
|
metadata.gz.sig
CHANGED
|
Binary file
|