kettle-family 0.2.7 → 1.0.1

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: 3dfb2d02f39f7c5b6e0bbf8398440cdce3300490cab3db8aad780b0d4f2b2b23
4
- data.tar.gz: 3354f6c528b63eaee745d87438fb41b21777d51d0accf30c1d270ac61189db96
3
+ metadata.gz: ddbeefcf7d7d90e52b0fadb3f09358c14baaa3eade9b03685e36868bd608e810
4
+ data.tar.gz: a75ce0508f27ba21ee30cf7a23fb95b97479ce1f6f03242a0fcc3210b2d2092f
5
5
  SHA512:
6
- metadata.gz: 2bf468aac31e154c72514ef15100393038244ea081cf4c3d2ee48369e140919edf273029cca70d500dd3f999e9d14cd7165f85560aa63662f1a3c1cacd9761fe
7
- data.tar.gz: 613218aa97433a66acb95849775523a38749267e7fcbf493998def269ccaadabe15d59d9d91f76a08dd436dcf2f9f73540a40372cf38a062e12dbc9c69e28d20
6
+ metadata.gz: '02850c92673ac9c330561be7e9b7cba733683aa952312cdf17bab8a299e4dbcd002ee9f75c5f08cd68c4650dcfea57399e04713523890822a50ce6278bf0536a'
7
+ data.tar.gz: a4b1e30e093fb889d26755250bc035243436a2e272288575991b9fcb83003288b4cb665363633711b20e4c7e1ce13103c7cd038d1b0e721dbd78a805af3ec4c9
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -28,8 +28,95 @@ Please file a bug if you notice a violation of semantic versioning.
28
28
 
29
29
  ### Fixed
30
30
 
31
+ - Generated HEAD and runtime dependency HEAD CI workflows no longer include
32
+ JRuby or TruffleRuby jobs for this MRI-only gem.
33
+
31
34
  ### Security
32
35
 
36
+ ## [1.0.1] - 2026-07-20
37
+
38
+ - TAG: [v1.0.1][1.0.1t]
39
+ - COVERAGE: 95.44% -- 2534/2655 lines in 23 files
40
+ - BRANCH COVERAGE: 77.89% -- 877/1126 branches in 23 files
41
+ - 29.10% documented
42
+
43
+ ### Added
44
+
45
+ - `kettle-family release-state` now includes an `ahead` column counting commits
46
+ from the latest release tag to the local default branch when available.
47
+ - `kettle-family release` now accepts `--skip-remotes` and forwards the
48
+ comma-separated remote skip list to member `kettle-release` runs.
49
+ - `kettle-family --only` now accepts release-state tokens `unreleased`,
50
+ `prepared`, and `pending`; multiple tokens are combined with logical AND.
51
+ - `kettle-family template` now accepts `--verbose` and forwards verbose mode to
52
+ member `kettle-jem` runs instead of forcing quiet JSON output.
53
+
54
+ - `kettle-family template` now runs `kettle-jem prepare` before full templating
55
+ for Kettle Jem-powered members so templating-only dependency bootstraps, such
56
+ as parser packages, are available before the full template command loads.
57
+
58
+ - `kettle-family template` now uses `kettle-jem --events` as its default
59
+ templating interface, including verbose and single-job runs, and streams
60
+ newline-delimited JSON template phase, recipe, post-apply, command-step,
61
+ diagnostic, and summary events as member-prefixed progress lines.
62
+
63
+ ### Deprecated
64
+
65
+ - `kettle-family bump-version` is now deprecated in favor of `kettle-family bump`.
66
+
67
+ ### Fixed
68
+
69
+ - The templating prepare phase now disables only the implicit family local path
70
+ environment variable unless it was explicitly provided, avoiding stale local
71
+ Gemfile activation failures before the prepare payload can refresh generated
72
+ modular Gemfiles.
73
+ - The templating prepare phase now runs outside each member's Bundler context so
74
+ it can repair stale generated Gemfiles before Bundler evaluates them.
75
+
76
+ - `kettle-family` template preparation now handles custom non-`kettle-jem`
77
+ template commands without treating no-op dependency preparation as failure.
78
+ - `kettle-family release-state` now counts `ahead` from the release tag to the
79
+ checked-out member `HEAD`.
80
+ - Generated docs now retain the YARD `_index.html` content wrapper after
81
+ regeneration with the shared YARD postprocessing stack.
82
+
83
+ ## [1.0.0] - 2026-07-17
84
+
85
+ - TAG: [v1.0.0][1.0.0t]
86
+ - COVERAGE: 95.22% -- 2370/2489 lines in 23 files
87
+ - BRANCH COVERAGE: 76.87% -- 801/1042 branches in 23 files
88
+ - 29.29% documented
89
+
90
+ ### Added
91
+
92
+ - `kettle-family release` now accepts `--ci-workflows` and forwards the
93
+ comma-separated workflow subset to member `kettle-release` runs.
94
+
95
+ ### Changed
96
+
97
+ - Promoted the gems that provide built-in `kettle-family` workflow commands to
98
+ runtime dependencies: `kettle-dev` for release/changelog/SHA-pin/version
99
+ tooling and `kettle-test` for test runs.
100
+ - Moved the `kettle-jem` templating provider to the templating Gemfile while
101
+ the next `kettle-jem` release depends on unreleased `kettle-family` fixes.
102
+ - Raised the runtime Ruby floor to 4.0.0.
103
+
104
+ - kettle-jem-template-20260716-001 - Shim gemspec manifests now include
105
+ `LICENSE.md` instead of nonexistent `LICENSE.txt`.
106
+ - kettle-jem-template-20260716-002 - Generated gemspec manifests now ship fewer
107
+ repository-only files by default to reduce downstream distro packaging churn.
108
+
109
+ ### Fixed
110
+
111
+ - Root-mode family changelog release commands now pass the configured family
112
+ name to `kettle-changelog`, allowing shared root changelogs to run from
113
+ repositories that do not have a root gemspec.
114
+ - `kettle-family bump-version` now recognizes exact same-version family
115
+ dependencies written as `= #{spec.version}` instead of failing with a
116
+ misleading ambiguous dependency error.
117
+ - `kettle-family release --ci-workflows` now validates workflow names before
118
+ forwarding them to shell-backed `kettle-release` commands.
119
+
33
120
  ## [0.2.7] - 2026-07-15
34
121
 
35
122
  - TAG: [v0.2.7][0.2.7t]
@@ -699,7 +786,11 @@ Please file a bug if you notice a violation of semantic versioning.
699
786
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
700
787
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
701
788
 
702
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v0.2.7...HEAD
789
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.0.1...HEAD
790
+ [1.0.1]: https://github.com/kettle-dev/kettle-family/compare/v1.0.0...v1.0.1
791
+ [1.0.1t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.0.1
792
+ [1.0.0]: https://github.com/kettle-dev/kettle-family/compare/v0.2.7...v1.0.0
793
+ [1.0.0t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.0.0
703
794
  [0.2.7]: https://github.com/kettle-dev/kettle-family/compare/v0.2.6...v0.2.7
704
795
  [0.2.7t]: https://github.com/kettle-dev/kettle-family/releases/tag/v0.2.7
705
796
  [0.2.6]: https://github.com/kettle-dev/kettle-family/compare/v0.2.5...v0.2.6
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # 👩‍👩‍👧‍👧 Kettle::Family
4
4
 
5
- [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: AGPL-3.0-only][📄license-img]][📄license] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
5
+ [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: AGPL-3.0-only][📄license-img]][📄license] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
6
6
 
7
7
  `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][✉️discord-invite], as I may have missed the [discord notification][✉️discord-invite].
8
8
 
@@ -44,10 +44,7 @@ while RubyGems MFA prompts remain interactive.
44
44
 
45
45
  | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
46
46
  |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
47
- | Works with JRuby | [![JRuby 10.0 Compat][💎jruby-10.0i]][🚎jruby-10.0-wf] [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf]|
48
- | Works with Truffle Ruby | [![Truffle Ruby 24.2 Compat][💎truby-24.2i]][🚎truby-24.2-wf] [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎truby-25.0-wf] [![Truffle Ruby 33.0 Compat][💎truby-33.0i]][🚎truby-33.0-wf] [![Truffle Ruby current Compat][💎truby-c-i]][🚎9-t-wf] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf]|
49
47
  | Works with MRI Ruby 4 | [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]|
50
- | Works with MRI Ruby 3 | [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎ruby-3.2-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎ruby-3.3-wf] [![Ruby 3.4 Compat][💎ruby-3.4i]][🚎ruby-3.4-wf]|
51
48
  | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
52
49
  | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
53
50
  | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] |
@@ -58,8 +55,8 @@ while RubyGems MFA prompts remain interactive.
58
55
 
59
56
  ### Compatibility
60
57
 
61
- Compatible with MRI Ruby 3.2.0+, and concordant releases of JRuby, and TruffleRuby.
62
- CI workflows and Appraisals are generated for MRI Ruby 3.2.0+.
58
+ Compatible with MRI Ruby 4.0.0+, and concordant releases of JRuby, and TruffleRuby.
59
+ CI workflows and Appraisals are generated for MRI Ruby 4.0.0+.
63
60
  This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
64
61
  may be higher than the gem's runtime compatibility floor when legacy Rubies are
65
62
  not practical for the current toolchain.
@@ -214,12 +211,17 @@ changelog:
214
211
 
215
212
  release:
216
213
  env:
217
- KETTLE_RB_DEV: false
214
+ KETTLE_DEV_DEV: false
218
215
  family_changelog:
219
216
  enabled: true
220
217
  command: bundle exec kettle-changelog
221
218
  ```
222
219
 
220
+ For `changelog.mode: root`, release commands pass `K_CHANGELOG_GEM_NAME` as the
221
+ configured family name and `K_CHANGELOG_VERSION_FILE` when `version_file` is
222
+ configured, so `kettle-changelog` can operate from a repository root without a
223
+ root gemspec.
224
+
223
225
  For a flat repository that releases from multiple long-lived branches, list the
224
226
  release branches under `release.target_branches`. The branch list is processed
225
227
  in order. Each branch must be clean enough for `git checkout`, and each branch
@@ -271,8 +273,28 @@ kettle-family release-state
271
273
  ```
272
274
 
273
275
  The release-state report lists each gem's current `version.rb`, latest published
274
- release, latest versioned `CHANGELOG.md` section, and whether pending changelog
275
- work exists in either `Unreleased` or an unpublished prepared release section.
276
+ release, latest versioned `CHANGELOG.md` section, whether pending changelog work
277
+ exists in either `Unreleased` or an unpublished prepared release section, and
278
+ how many commits the current branch is ahead of the latest release tag.
279
+
280
+ Use release-state tokens with `--only` to select gems by state instead of by
281
+ name. Multiple tokens are combined with logical AND, so this selects only gems
282
+ that are both unreleased and pending. Status tokens cannot be mixed with member
283
+ names in the same `--only` value.
284
+
285
+ ```console
286
+ kettle-family release-state --only pending
287
+ kettle-family release-state --only unreleased,prepared
288
+ kettle-family release --execute --only unreleased,pending
289
+ ```
290
+
291
+ The supported release-state tokens are:
292
+
293
+ | Token | Meaning |
294
+ |-------|---------|
295
+ | `unreleased` | The current `version.rb` is not the latest published gem version. |
296
+ | `prepared` | The changelog already has a versioned section for the current `version.rb`. |
297
+ | `pending` | The member has unreleased changelog work or an unpublished prepared release. |
276
298
 
277
299
  Plan or update GitHub Actions workflow SHA pins across the selected family
278
300
  members:
@@ -289,6 +311,15 @@ Run release prep/build phases without publishing:
289
311
  kettle-family release --execute
290
312
  ```
291
313
 
314
+ When a remote mirror is temporarily unavailable, skip it for the underlying
315
+ `kettle-release` fetch/parity gate instead of removing the remote from each
316
+ member repository:
317
+
318
+ ```console
319
+ kettle-family release --execute --publish --skip-remotes cb
320
+ kettle-family release --execute --publish --skip-remotes cb,mirror2
321
+ ```
322
+
292
323
  Publish through `kettle-release`. A full publish first runs the
293
324
  `kettle-pre-release` gate, then prompts once for the gem signing key password
294
325
  and leaves RubyGems MFA prompts interactive:
@@ -319,6 +350,61 @@ If you intentionally need to continue after CI failures, opt in explicitly:
319
350
  kettle-family release --publish --execute --continue-ci-failures
320
351
  ```
321
352
 
353
+ Bump aligned member versions with `bump`. The older `bump-version` command still
354
+ works as a deprecated alias.
355
+
356
+ ```console
357
+ kettle-family bump --execute --only pending patch
358
+ kettle-family bump --execute --only unreleased minor
359
+ ```
360
+
361
+ Run `kettle-jem` templating across the selected family members. Planning shows
362
+ the commands that would run; `--execute` runs them. Executed templating defaults
363
+ to a parallel job count based on CPU cores, capped for readability, and can be
364
+ overridden with `--jobs`.
365
+
366
+ ```console
367
+ kettle-family template
368
+ kettle-family template --execute --jobs 4
369
+ kettle-family template --execute --only kettle-family
370
+ ```
371
+
372
+ Templating uses `kettle-jem --events` as the default child interface, so
373
+ executed runs stream member-prefixed progress while still keeping the final
374
+ family report. Progress marks include:
375
+
376
+ | Mark | Meaning |
377
+ |------|---------|
378
+ | `>` | A phase or command step started. |
379
+ | `.` | A phase, recipe, or step completed without changing files. |
380
+ | `*` | A recipe or step changed files. |
381
+ | `!` | A diagnostic was emitted. |
382
+ | `F` | A phase or step failed. |
383
+ | `done` | The member summary was emitted. |
384
+
385
+ Example progress:
386
+
387
+ ```text
388
+ templating 1 member with 1 job:
389
+ [kettle-family] > recipes
390
+ [kettle-family] * Gemfile
391
+ [kettle-family] * post_apply:git_hooks_executable
392
+ [kettle-family] done 2 files changed
393
+ .
394
+ template summary: 1/1 members ok, 2 files changed
395
+ ```
396
+
397
+ Use `--verbose` when you need `kettle-jem` verbose diagnostics layered on top of
398
+ the event stream. Environment overrides pass through to every member workflow
399
+ command, which is useful when templating against local unreleased dependencies.
400
+
401
+ ```console
402
+ kettle-family template --execute --verbose --jobs 1
403
+ kettle-family template --execute \
404
+ --env K_JEM_TEMPLATING=true \
405
+ --env STRUCTUREDMERGE_DEV=/home/me/src/structuredmerge/ruby/gems
406
+ ```
407
+
322
408
  ## 🔐 Security
323
409
 
324
410
  See [SECURITY.md][🔐security].
@@ -384,7 +470,7 @@ For most applications, prefer the [Pessimistic Version Constraint][📌pvc] with
384
470
  For example:
385
471
 
386
472
  ```ruby
387
- spec.add_dependency("kettle-family", "~> 0.0")
473
+ spec.add_dependency("kettle-family", "~> 1.0")
388
474
  ```
389
475
 
390
476
  <details markdown="1">
@@ -539,23 +625,12 @@ Thanks for RTFM. ☺️
539
625
  [🏀codecovi]: https://codecov.io/gh/kettle-dev/kettle-family/graph/badge.svg
540
626
  [🏀coveralls]: https://coveralls.io/github/kettle-dev/kettle-family?branch=main
541
627
  [🏀coveralls-img]: https://coveralls.io/repos/github/kettle-dev/kettle-family/badge.svg?branch=main
542
- [🚎ruby-3.2-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/ruby-3.2.yml
543
- [🚎ruby-3.3-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/ruby-3.3.yml
544
- [🚎ruby-3.4-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/ruby-3.4.yml
545
- [🚎jruby-10.0-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/jruby-10.0.yml
546
- [🚎truby-24.2-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/truffleruby-24.2.yml
547
- [🚎truby-25.0-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/truffleruby-25.0.yml
548
- [🚎truby-33.0-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/truffleruby-33.0.yml
549
628
  [🚎2-cov-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/coverage.yml
550
629
  [🚎2-cov-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/coverage.yml/badge.svg
551
630
  [🚎3-hd-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/heads.yml
552
631
  [🚎3-hd-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/heads.yml/badge.svg
553
632
  [🚎5-st-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/style.yml
554
633
  [🚎5-st-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/style.yml/badge.svg
555
- [🚎9-t-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/truffle.yml
556
- [🚎9-t-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/truffle.yml/badge.svg
557
- [🚎10-j-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/jruby.yml
558
- [🚎10-j-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/jruby.yml/badge.svg
559
634
  [🚎11-c-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/current.yml
560
635
  [🚎11-c-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/current.yml/badge.svg
561
636
  [🚎12-crh-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/dep-heads.yml
@@ -564,19 +639,8 @@ Thanks for RTFM. ☺️
564
639
  [🚎13-🔒️-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/locked_deps.yml/badge.svg
565
640
  [🚎14-🔓️-wf]: https://github.com/kettle-dev/kettle-family/actions/workflows/unlocked_deps.yml
566
641
  [🚎14-🔓️-wfi]: https://github.com/kettle-dev/kettle-family/actions/workflows/unlocked_deps.yml/badge.svg
567
- [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
568
- [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
569
- [💎ruby-3.4i]: https://img.shields.io/badge/Ruby-3.4-CC342D?style=for-the-badge&logo=ruby&logoColor=white
570
642
  [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
571
643
  [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
572
- [💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
573
- [💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
574
- [💎truby-33.0i]: https://img.shields.io/badge/Truffle_Ruby-33.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
575
- [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
576
- [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
577
- [💎jruby-10.0i]: https://img.shields.io/badge/JRuby-10.0-FBE742?style=for-the-badge&logo=ruby&logoColor=red
578
- [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
579
- [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
580
644
  [🤝gh-issues]: https://github.com/kettle-dev/kettle-family/issues
581
645
  [🤝gh-pulls]: https://github.com/kettle-dev/kettle-family/pulls
582
646
  [🤝gl-issues]: https://gitlab.com/kettle-dev/kettle-family/-/issues
@@ -603,7 +667,7 @@ Thanks for RTFM. ☺️
603
667
  [📌gitmoji]: https://gitmoji.dev
604
668
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
605
669
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
606
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-2.460-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
670
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-2.655-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
607
671
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
608
672
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
609
673
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -10,7 +10,7 @@ module Kettle
10
10
  class CLI < CommandKit::Command
11
11
  include CommandKit::Commands
12
12
 
13
- COMMANDS = %w[discover plan report metadata check test lint docs template gha-sha-pins bup bupb bex install bump-version add-changelog release push pull up branch-lanes release-state].freeze
13
+ COMMANDS = %w[discover plan report metadata check test lint docs template gha-sha-pins bup bupb bex install bump bump-version add-changelog release push pull up branch-lanes release-state].freeze
14
14
  WORKFLOW_COMMANDS = %w[check test lint docs template gha-sha-pins bup bupb bex release push pull up].freeze
15
15
 
16
16
  command_name "kettle-family"
@@ -37,7 +37,7 @@ module Kettle
37
37
 
38
38
  module SelectionOptions
39
39
  def self.included(base)
40
- base.option :only, value: {type: String, usage: "MEMBERS"}, desc: "Select comma-separated members"
40
+ base.option :only, value: {type: String, usage: "MEMBERS"}, desc: "Select comma-separated members, or release-state tokens: unreleased, prepared, pending"
41
41
  base.option :exclude, value: {type: String, usage: "MEMBERS"}, desc: "Exclude comma-separated members"
42
42
  base.option :start_at, long: "--start-at", value: {type: String, usage: "MEMBER[@BRANCH]"}, desc: "Select from member through the end of order"
43
43
  end
@@ -65,6 +65,7 @@ module Kettle
65
65
  module WorkflowOptions
66
66
  def self.included(base)
67
67
  base.option :debug, desc: "Preserve debug environment for workflow commands"
68
+ base.option :verbose, desc: "Pass verbose mode through to supported workflow commands"
68
69
  base.option :jobs, value: {type: Integer, usage: "N"}, desc: "Parallel jobs for supported executed workflows"
69
70
  base.option :env, value: {type: String, usage: "KEY=VALUE"}, desc: "Override an environment variable for each member workflow command" do |value|
70
71
  parse_env_override(value, workflow_env)
@@ -134,6 +135,7 @@ module Kettle
134
135
  report: options[:report],
135
136
  execute: truthy_option?(:execute),
136
137
  debug: truthy_option?(:debug),
138
+ verbose: truthy_option?(:verbose),
137
139
  jobs: options[:jobs],
138
140
  workflow_env: workflow_env,
139
141
  changelog_section: nil,
@@ -146,7 +148,9 @@ module Kettle
146
148
  release_skip_steps: nil,
147
149
  release_local_ci: false,
148
150
  release_continue_ci_failures: false,
151
+ release_ci_workflows: nil,
149
152
  release_skip_bundle_audit: false,
153
+ release_skip_remotes: nil,
150
154
  accept: true,
151
155
  tag: false,
152
156
  push: false,
@@ -352,11 +356,11 @@ module Kettle
352
356
  end
353
357
  end
354
358
 
355
- class BumpVersion < BaseCommand
359
+ class Bump < BaseCommand
356
360
  include ExecutionOptions
357
361
  include CommitOptions
358
362
 
359
- command_name "bump-version"
363
+ command_name "bump"
360
364
  usage "[options] VERSION|major|minor|patch|pre"
361
365
  description "Check, plan, or execute family version alignment."
362
366
  argument :target_version, required: false, usage: "VERSION|major|minor|patch|pre", desc: "Version or bump target"
@@ -365,9 +369,31 @@ module Kettle
365
369
  option :from, value: {type: String, usage: "VERSION"}, desc: "Require selected members to currently match VERSION"
366
370
 
367
371
  def run(target_version = nil)
368
- raise Error, "bump-version requires VERSION, major, minor, patch, or pre" unless target_version
372
+ raise Error, "#{workflow_command_name} requires VERSION, major, minor, patch, or pre" unless target_version
373
+
374
+ run_family(workflow_command_name, target_version: target_version, from_version: options[:from])
375
+ end
376
+
377
+ private
378
+
379
+ def workflow_command_name
380
+ "bump"
381
+ end
382
+ end
383
+
384
+ class BumpVersion < Bump
385
+ command_name "bump-version"
386
+ description "Deprecated alias for bump."
387
+
388
+ def run(target_version = nil)
389
+ stderr.puts("kettle-family: bump-version is deprecated; use bump instead.")
390
+ super
391
+ end
392
+
393
+ private
369
394
 
370
- run_family("bump-version", target_version: target_version, from_version: options[:from])
395
+ def workflow_command_name
396
+ "bump-version"
371
397
  end
372
398
  end
373
399
 
@@ -404,7 +430,9 @@ module Kettle
404
430
  option :skip_steps, long: "--skip-steps", value: {type: String, usage: "LIST"}, desc: "Pass skip_steps=LIST through to kettle-release commands"
405
431
  option :local_ci, long: "--local-ci", desc: "Pass --local-ci through to kettle-release commands"
406
432
  option :continue_ci_failures, long: "--continue-ci-failures", desc: "Set K_RELEASE_CI_CONTINUE=true for release commands"
433
+ option :ci_workflows, long: "--ci-workflows", value: {type: String, usage: "LIST"}, desc: "Pass a comma-separated CI workflow monitor subset through to kettle-release commands"
407
434
  option :skip_bundle_audit, long: "--skip-bundle-audit", desc: "Skip bundle:audit/update during release rake checks"
435
+ option :skip_remotes, long: "--skip-remotes", value: {type: String, usage: "LIST"}, desc: "Pass a comma-separated git remote skip list through to kettle-release commands"
408
436
  option :no_auto_floors, long: "--no-auto-floors", desc: "Do not raise family dependency floors between member releases" do
409
437
  options[:no_auto_floors] = true
410
438
  end
@@ -424,7 +452,9 @@ module Kettle
424
452
  release_skip_steps: options[:skip_steps],
425
453
  release_local_ci: truthy_option?(:local_ci),
426
454
  release_continue_ci_failures: truthy_option?(:continue_ci_failures),
455
+ release_ci_workflows: options[:ci_workflows],
427
456
  release_skip_bundle_audit: truthy_option?(:skip_bundle_audit),
457
+ release_skip_remotes: options[:skip_remotes],
428
458
  release_auto_dependency_floors: !truthy_option?(:no_auto_floors),
429
459
  accept: !options.key?(:accept) || options[:accept],
430
460
  tag: truthy_option?(:tag),
@@ -465,6 +495,7 @@ module Kettle
465
495
  command Bupb
466
496
  command Bex
467
497
  command Install
498
+ command Bump
468
499
  command BumpVersion
469
500
  command AddChangelog
470
501
  command Release
@@ -511,7 +542,8 @@ module Kettle
511
542
  else
512
543
  Orderer.new(members: members, mode: config.order_mode, hints: config.order_hints).ordered
513
544
  end
514
- selected = Selection.new(members: ordered).apply(only: options[:only], exclude: options[:exclude], start_at: start_at.member)
545
+ release_state_results = release_state_results_for_selection(config: config, members: ordered, only: options[:only])
546
+ selected = Selection.new(members: ordered, release_state_results: release_state_results).apply(only: options[:only], exclude: options[:exclude], start_at: start_at.member)
515
547
  result_members = selected
516
548
  results = command_results(command: command, config: config, members: result_members, options: options, start_at: start_at)
517
549
  Report.new(
@@ -539,8 +571,14 @@ module Kettle
539
571
  command_results_for_current_branch(command: command, config: config, members: members, options: options, start_at: start_at)
540
572
  end
541
573
 
574
+ def release_state_results_for_selection(config:, members:, only:)
575
+ return nil unless only.to_s.split(",").map(&:strip).any? { |token| Selection.status_token?(token) }
576
+
577
+ ReleaseStateCheck.new(config: config, members: members).results
578
+ end
579
+
542
580
  def command_results_for_current_branch(command:, config:, members:, options:, start_at: StartAt.new(nil, nil))
543
- return bump_version_results(members: members, options: options) if command == "bump-version"
581
+ return bump_version_results(members: members, options: options, phase: command) if %w[bump bump-version].include?(command)
544
582
  return add_changelog_results(members: members, options: options) if command == "add-changelog"
545
583
  return branch_lane_results(config: config, members: members) if command == "branch-lanes"
546
584
  return release_state_results(config: config, members: members) if command == "release-state"
@@ -562,12 +600,15 @@ module Kettle
562
600
  skip_steps: options[:release_skip_steps],
563
601
  local_ci: options[:release_local_ci],
564
602
  continue_ci_failures: options[:release_continue_ci_failures],
603
+ ci_workflows: options[:release_ci_workflows],
565
604
  skip_bundle_audit: options[:release_skip_bundle_audit],
605
+ skip_remotes: options[:release_skip_remotes],
566
606
  auto_dependency_floors: options[:release_auto_dependency_floors],
567
607
  gha_sha_pins_upgrade: options[:gha_sha_pins_upgrade],
568
608
  gha_sha_pins_check: options[:check],
569
609
  env_overrides: options[:workflow_env],
570
610
  debug: options[:debug],
611
+ verbose: options[:verbose],
571
612
  jobs: options[:jobs],
572
613
  progress_io: progress_io(command, options),
573
614
  bup_args: options[:bup_args],
@@ -589,14 +630,14 @@ module Kettle
589
630
  return false if config.release_target_branches.empty?
590
631
  return false if command == "release-state"
591
632
  return false if command == "branch-lanes"
592
- return false unless WORKFLOW_COMMANDS.include?(command) || %w[bump-version install add-changelog].include?(command)
633
+ return false unless WORKFLOW_COMMANDS.include?(command) || %w[bump bump-version install add-changelog].include?(command)
593
634
 
594
635
  !WORKFLOW_COMMANDS.include?(command)
595
636
  end
596
637
 
597
638
  def member_local_branch_target_command?(command, config, members)
598
639
  return false if !config.release_target_branches.empty?
599
- return false unless %w[bump-version install add-changelog].include?(command)
640
+ return false unless %w[bump bump-version install add-changelog].include?(command)
600
641
 
601
642
  members.any? { |member| member_release_config(member: member, config: config) }
602
643
  end
@@ -682,14 +723,15 @@ module Kettle
682
723
  StartAt.new(member, branch)
683
724
  end
684
725
 
685
- def bump_version_results(members:, options:)
726
+ def bump_version_results(members:, options:, phase:)
686
727
  require_relative "version_bump"
687
728
 
688
729
  results = VersionBump.new(
689
730
  members: members,
690
731
  target_version: options[:target_version],
691
732
  from_version: options[:from_version],
692
- mode: bump_version_mode(options)
733
+ mode: bump_version_mode(options),
734
+ phase: phase
693
735
  ).results
694
736
  return results if options[:check] || !options[:commit]
695
737
  return results unless results.all?(&:ok?)
@@ -111,7 +111,7 @@ module Kettle
111
111
  @otp_coordinator = otp_coordinator
112
112
  end
113
113
 
114
- def call(member:, phase:, command:, env: {}, interactive: false)
114
+ def call(member:, phase:, command:, env: {}, interactive: false, stdout_line_handler: nil)
115
115
  argv = command_argv(member: member, command: command, env: env)
116
116
  process_env = process_env(member: member, env: env)
117
117
  spawn_options = process_options
@@ -120,6 +120,8 @@ module Kettle
120
120
  started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
121
121
  stdout, stderr, status = if interactive
122
122
  run_interactive(env: process_env, argv: argv, chdir: member.root, member_name: member.name, process_options: spawn_options)
123
+ elsif stdout_line_handler
124
+ run_streaming(env: process_env, argv: argv, chdir: member.root, process_options: spawn_options, stdout_line_handler: stdout_line_handler)
123
125
  else
124
126
  Open3.capture3(process_env, *argv, chdir: member.root, **spawn_options)
125
127
  end
@@ -145,6 +147,41 @@ module Kettle
145
147
 
146
148
  attr_reader :execute, :accept, :gem_signing_password, :otp_coordinator
147
149
 
150
+ def run_streaming(env:, argv:, chdir:, process_options:, stdout_line_handler:)
151
+ captured_stdout = +""
152
+ captured_stderr = +""
153
+ stdout_line_buffer = +""
154
+ status = nil
155
+ Open3.popen3(env, *argv, chdir: chdir, **process_options) do |_input, output, error, wait_thread|
156
+ readers = [output, error]
157
+ until readers.empty?
158
+ ready = IO.select(readers)
159
+ ready.first.each do |reader|
160
+ if reader.equal?(output)
161
+ chunk = reader.readpartial(1024)
162
+ captured_stdout << chunk
163
+ stdout_line_buffer = stream_stdout_lines(stdout_line_buffer, chunk, stdout_line_handler)
164
+ else
165
+ captured_stderr << reader.readpartial(1024)
166
+ end
167
+ rescue EOFError
168
+ readers.delete(reader)
169
+ end
170
+ end
171
+ stdout_line_handler.call(stdout_line_buffer) unless stdout_line_buffer.empty?
172
+ status = wait_thread.value
173
+ end
174
+ [captured_stdout, captured_stderr, status]
175
+ end
176
+
177
+ def stream_stdout_lines(buffer, chunk, handler)
178
+ pending = buffer + chunk
179
+ lines = pending.lines
180
+ remainder = pending.end_with?("\n") ? +"" : lines.pop.to_s
181
+ lines.each { |line| handler.call(line.chomp) }
182
+ remainder
183
+ end
184
+
148
185
  def run_interactive(env:, argv:, chdir:, member_name:, process_options:)
149
186
  return run_interactive_pty(env: env, argv: argv, chdir: chdir, member_name: member_name, process_options: process_options) if pty_available?
150
187
 
@@ -167,9 +167,11 @@ module Kettle
167
167
  end
168
168
 
169
169
  def changelog_env
170
- return {} unless changelog_version_file
170
+ env = {}
171
+ env["K_CHANGELOG_VERSION_FILE"] = changelog_version_file.to_s if changelog_version_file
172
+ env["K_CHANGELOG_GEM_NAME"] = family_name.to_s if shared_changelog?
171
173
 
172
- {"K_CHANGELOG_VERSION_FILE" => changelog_version_file.to_s}
174
+ env
173
175
  end
174
176
 
175
177
  def template_command
@@ -276,9 +278,9 @@ module Kettle
276
278
  def default_release_disable_local_path_env
277
279
  local_envs = %w[
278
280
  K_JEM_TEMPLATING
279
- SMORG_RB_DEV
281
+ STRUCTUREDMERGE_DEV
280
282
  TSLP_DEV
281
- KETTLE_RB_DEV
283
+ KETTLE_DEV_DEV
282
284
  RUBOCOP_LTS_DEV
283
285
  PBOLING_DEV
284
286
  GALTZO_FLOSS_DEV