https://github.com/kettle-dev/kettle-dev
🍲 Setup a complete rake & dev harness for Ruby development; tasks for coverage, GHA console, linting, debugging, etc.
https://github.com/kettle-dev/kettle-dev
ruby rubygem template
Last synced: 2 days ago
JSON representation
🍲 Setup a complete rake & dev harness for Ruby development; tasks for coverage, GHA console, linting, debugging, etc.
- Host: GitHub
- URL: https://github.com/kettle-dev/kettle-dev
- Owner: kettle-dev
- License: other
- Created: 2025-08-21T23:49:45.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2026-06-09T10:01:44.000Z (3 days ago)
- Last Synced: 2026-06-09T11:18:24.364Z (3 days ago)
- Topics: ruby, rubygem, template
- Language: Ruby
- Homepage: https://kettle-dev.galtzo.com/
- Size: 5.98 MB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
- Citation: CITATION.cff
- Security: SECURITY.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# 🍲 Kettle::Dev
[![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]
`if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][✉️discord-invite], as I may have missed the [discord notification][✉️discord-invite].
---
`if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️
I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
Kettle::Dev is the development, CI, changelog, and release harness used by
kettle-rb gems. It installs rake tasks when loaded from a project's `Rakefile`,
and it ships command-line tools for changelog preparation, release automation,
multi-forge git remotes, commit-message hooks, and Open Collective README
updates.
Add it to a gem's development dependencies, then load the rake integration:
```ruby
# Gemfile
group :development, :test do
gem "kettle-dev", require: false
end
```
```ruby
# Rakefile
require "kettle/dev"
```
For RSpec projects, use the matching test harness from
[kettle-test](https://github.com/kettle-rb/kettle-test):
```ruby
require "kettle/test/rspec"
```
Project setup and template refreshes are now owned by
[kettle-jem](https://github.com/kettle-rb/kettle-jem), not kettle-dev:
```console
gem install kettle-jem
kettle-jem setup
```
Once a project is wired, the normal local development loop is:
```console
bin/rake
bin/rake rubocop_gradual:autocorrect
bin/rake yard
```
And the maintainer release flow is:
```console
bin/kettle-pre-release
bin/kettle-changelog
bin/kettle-release
```
### What kettle-dev provides
- Rake task loading from `require "kettle/dev"`.
- RuboCop Gradual, Reek, YARD, appraisal, local CI, benchmark, and coverage task wiring.
- `kettle-changelog` for moving Unreleased changelog notes into a versioned release section with coverage and documentation stats.
- `kettle-release` for the canonical kettle-rb release flow.
- `kettle-pre-release` for release readiness checks.
- `kettle-dvcs` for normalizing GitHub, GitLab, Codeberg, and aggregate remotes.
- `kettle-commit-msg` for shared commit-message hook behavior.
- `kettle-readme-backers` for Open Collective README sections.
- `kettle-dev-setup` as a deprecated compatibility executable that exits with instructions to use kettle-jem.
## 💡 Info you can shake a stick at
| Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Works with JRuby | [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎jruby-9.2-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎jruby-9.3-wf]
[![JRuby 9.4 Compat][💎jruby-9.4i]][🚎jruby-9.4-wf] [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf]|
| Works with Truffle Ruby | [![Truffle Ruby 22.3 Compat][💎truby-22.3i]][🚎truby-22.3-wf] [![Truffle Ruby 23.0 Compat][💎truby-23.0i]][🚎truby-23.0-wf] [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎truby-23.1-wf]
[![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 current Compat][💎truby-c-i]][🚎9-t-wf]|
| Works with MRI Ruby 4 | [![Ruby 4.0 Compat][💎ruby-4.0i]][🚎11-c-wf] [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]|
| Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎ruby-3.0-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎ruby-3.1-wf] [![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]|
| Works with MRI Ruby 2 | [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎ruby-2.4-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎ruby-2.5-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎ruby-2.6-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎ruby-2.7-wf]|
| 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] |
| 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] |
| 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] |
| Compliance | [![License: AGPL-3.0-only][📄license-img]][📄license] [![Apache license compatibility: Category X][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
| Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
| Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼♂️devto-img]][💖💁🏼♂️devto] |
| `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼♂️aboutme-img]][💖💁🏼♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] |
### Compatibility
Compatible with MRI Ruby 2.4.0+, and concordant releases of JRuby, and TruffleRuby.
CI workflows and Appraisals are generated for MRI Ruby 2.4+.
This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
may be higher than the gem's runtime compatibility floor when legacy Rubies are
not practical for the current toolchain.
| 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
|------------------------------------------------|--------------------------------------------------------|
| 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
### Federated DVCS
Find this repo on federated forges (Coming soon!)
| Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
|-------------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
| 🧪 [kettle-dev/kettle-dev on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
| 🧊 [kettle-dev/kettle-dev on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
| 🐙 [kettle-dev/kettle-dev on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
| 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
[gh-discussions]: https://github.com/kettle-dev/kettle-dev/discussions
### Enterprise Support [](https://tidelift.com/subscription/pkg/rubygems-kettle-dev?utm_source=rubygems-kettle-dev&utm_medium=referral&utm_campaign=readme)
Available as part of the Tidelift Subscription.
Need enterprise-level guarantees?
The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
[![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]
- 💡Subscribe for support guarantees covering _all_ your FLOSS dependencies
- 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
- 💡Tidelift pays maintainers to maintain the software you depend on!
📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers
Alternatively:
- [![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]
## ✨ Installation
Install the gem and add to the application's Gemfile by executing:
```console
bundle add kettle-dev
```
If bundler is not being used to manage dependencies, install the gem by executing:
```console
gem install kettle-dev
```
## ⚙️ Configuration
Kettle-dev has two integration surfaces:
- Executable scripts in `exe/`, or binstubs generated from them, can run when
`kettle-dev` is installed and loadable.
- Rake tasks are registered by adding `kettle-dev` to the project's development
dependencies and requiring `kettle/dev` from the project's `Rakefile`.
```ruby
group :development, :test do
gem "kettle-dev", require: false
end
```
```ruby
require "kettle/dev"
```
### RSpec
This gem integrates tightly with [kettle-test](https://github.com/kettle-rb/kettle-test).
```ruby
require "kettle/test/rspec"
# ... any other config you need to do.
# NOTE: Gemfiles for older rubies (< 2.7) won't have kettle-soup-cover.
# The rescue LoadError handles that scenario.
begin
require "kettle-soup-cover"
require "simplecov" if Kettle::Soup::Cover::DO_COV # `.simplecov` is run here!
rescue LoadError => error
# check the error message, and re-raise if not what is expected
raise error unless error.message.include?("kettle")
end
# This gem (or app)
require "gem-under-test"
```
### Rakefile
Add to your `Rakefile`:
```ruby
require "kettle/dev"
```
This loads the kettle-dev rake task set. Current project setup and template
refreshes should be run through kettle-jem:
```console
gem install kettle-jem
kettle-jem setup
```
`kettle-dev-setup` is still shipped for compatibility, but it now exits with a
message explaining that setup and templating moved to kettle-jem.
Useful registered tasks include:
- `rubocop_gradual:autocorrect` and `rubocop_gradual:check`
- `reek` and `reek:update`
- `yard`
- `appraisal:install`, `appraisal:generate`, `appraisal:update`, and `appraisal:reset`
- `ci:act`
- `bench`
- `kettle:jem:template` and `kettle:jem:selftest`, when kettle-jem's task integration is available
Install binstubs when a project wants local `bin/kettle-*` commands:
```console
bundle binstubs kettle-dev --path bin
```
### Environment Variables
Below are the primary environment variables recognized by kettle-dev (and its integrated tools). Unless otherwise noted, set boolean values to the string "true" to enable.
General/runtime
- `DEBUG`: Enable extra internal logging for this library (default: false)
- `REQUIRE_BENCH`: Enable `require_bench` to profile requires (default: false)
- `CI`: When set to true, adjusts default rake tasks toward CI behavior
Coverage (kettle-soup-cover / SimpleCov)
- `K_SOUP_COV_DO`: Enable coverage collection (default: true in .envrc)
- `K_SOUP_COV_FORMATTERS`: Comma-separated list of formatters (html, xml, rcov, lcov, json, tty)
- `K_SOUP_COV_MIN_LINE`: Minimum line coverage threshold (integer, e.g., 100)
- `K_SOUP_COV_MIN_BRANCH`: Minimum branch coverage threshold (integer, e.g., 100)
- `K_SOUP_COV_MIN_HARD`: Fail the run if thresholds are not met (true/false)
- `K_SOUP_COV_MULTI_FORMATTERS`: Enable multiple formatters at once (true/false)
- `K_SOUP_COV_OPEN_BIN`: Path to browser opener for HTML (empty disables auto-open)
- `MAX_ROWS`: Limit console output rows for simplecov-console (e.g., 1)
Tip: When running a single spec file locally, you may want `K_SOUP_COV_MIN_HARD=false` to avoid failing thresholds for a partial run.
GitHub API and CI helpers
- `GITHUB_TOKEN` or `GH_TOKEN`: Token used by `ci:act` and release workflow checks to query GitHub Actions status at higher rate limits
- `GITLAB_TOKEN` or `GL_TOKEN`: Token used by `ci:act` and CI monitor to query GitLab pipeline status
Releasing and signing
- `SKIP_GEM_SIGNING`: If set, skip gem signing during build/release
- `GEM_CERT_USER`: Username for selecting your public cert in `certs/.pem` (defaults to $USER)
- `SOURCE_DATE_EPOCH`: Reproducible build timestamp. `kettle-release` will set this automatically for the session.
Git hooks and commit message helpers (exe/kettle-commit-msg)
- `GIT_HOOK_BRANCH_VALIDATE`: Branch name validation mode (e.g., `jira`) or `false` to disable
- `GIT_HOOK_FOOTER_APPEND`: Append a footer to commit messages when goalie allows (true/false)
- `GIT_HOOK_FOOTER_SENTINEL`: Required when footer append is enabled — a unique first-line sentinel to prevent duplicates
- `GIT_HOOK_FOOTER_APPEND_DEBUG`: Extra debug output in the footer template (true/false)
For a quick starting point, this repository’s `.envrc` shows sane defaults, and `.env.local` can override them locally.
## 🔧 Basic Usage
Common local workflows:
- `bundle exec rake` runs the curated default task set. Locally this favors
autocorrection where supported; with `CI=true` it favors check-only behavior.
- `bin/rspec` or `bundle exec rspec` runs specs.
- `K_SOUP_COV_MIN_HARD=false bin/rspec spec/path/to/file_spec.rb` is useful for
focused spec runs that should not fail whole-suite coverage thresholds.
- `bundle exec rake rubocop_gradual:autocorrect` applies gradual RuboCop fixes.
- `bundle exec rake rubocop_gradual:check` is the CI-friendly RuboCop Gradual task.
- `bundle exec rake reek` and `bundle exec rake reek:update` run or refresh Reek.
- `bundle exec rake yard` builds API documentation.
- `bundle exec rake appraisal:install` performs first-time Appraisal setup.
- `bundle exec rake appraisal:generate` regenerates Appraisal gemfiles.
- `bundle exec rake appraisal:update` updates Appraisal locks and applies gradual RuboCop autocorrect.
- `bundle exec rake appraisal:reset` removes Appraisal lockfiles below `gemfiles/`.
- `kettle-bump patch` bumps the current gem's patch version before running
`kettle-changelog`.
GitHub Actions local runner helper:
- `bundle exec rake ci:act` opens an interactive workflow selector using
`.github/workflows` and live CI status when tokens are available.
- `bundle exec rake ci:act[loc]` selects by short code.
- `bundle exec rake ci:act[locked_deps.yml]` selects by workflow filename.
- Set `GITHUB_TOKEN` or `GH_TOKEN` for GitHub Actions API status.
- Set `GITLAB_TOKEN` or `GL_TOKEN` for GitLab pipeline status.
Project automation and template refreshes:
- Use `kettle-jem setup` for first-time setup and `kettle-jem install` for
full template refreshes.
- When kettle-jem's rake integration is installed, run `bundle exec rake kettle:jem:template`
to refresh template-managed files.
- `kettle-dev-setup` is deprecated and intentionally exits with a migration
message pointing to kettle-jem.
### kettle-dvcs (normalize multi-forge remotes)
- Script: `exe/kettle-dvcs` (install binstubs for convenience: `bundle binstubs kettle-dev --path bin`)
- Purpose: Normalize git remotes across GitHub, GitLab, and Codeberg, and create an `all` remote that pushes to all and fetches only from your chosen origin.
- Assumptions: org and repo names are identical across forges.
Usage:
```console
kettle-dvcs [options] [ORG] [REPO]
```
Options:
- `--origin [github|gitlab|codeberg]` Which forge to use as `origin` (default: github)
- `--protocol [ssh|https]` URL style (default: ssh)
- `--github-name NAME` Remote name for GitHub when not origin (default: gh)
- `--gitlab-name NAME` Remote name for GitLab (default: gl)
- `--codeberg-name NAME` Remote name for Codeberg (default: cb)
- `--force` Non-interactive; accept defaults, and do not prompt for ORG/REPO
Examples:
- Default, interactive (infers ORG/REPO from an existing remote when possible):
```console
kettle-dvcs
```
- Non-interactive with explicit org/repo:
```console
kettle-dvcs --force my-org my-repo
```
- Use GitLab as origin and HTTPS URLs:
```console
kettle-dvcs --origin gitlab --protocol https my-org my-repo
```
What it does:
- Ensures remotes exist and have consistent URLs for each forge.
- Renames existing remotes when their URL already matches the desired target but their name does not (e.g., `gitlab` -\> `gl`).
- Creates/refreshes an `all` remote that:
- fetches only from your chosen `origin` forge.
- has pushurls configured for all three forges so `git push all ` updates all mirrors.
- Prints `git remote -v` at the end.
- Attempts to `git fetch` each forge remote to check availability:
- If all succeed, the README’s federated DVCS summary line has “(Coming soon\!)” removed.
- If any fail, the script prints import links to help you create a mirror on that forge.
### Releasing (maintainers)
- Script: `exe/kettle-release` (run as `kettle-release`)
- Purpose: guided release helper that:
- Runs `kettle-pre-release` before the numbered release steps on full releases, aborting before release setup if any pre-release gate fails.
- Runs sanity checks (`bin/setup`, `bin/rake`), confirms version/changelog, optionally updates Appraisals, regenerates docs via `bin/rake yard`, commits “🔖 Prepare release vX.Y.Z”.
- Optionally runs your CI locally with `act` before any push:
- Enable with env: `K_RELEASE_LOCAL_CI="true"` (run automatically) or `K_RELEASE_LOCAL_CI="ask"` (prompt \[Y/n\]).
- Select workflow with `K_RELEASE_LOCAL_CI_WORKFLOW` (with or without .yml/.yaml). Defaults to `locked_deps.yml` if present; otherwise the first workflow discovered.
- On failure, the release prep commit is soft-rolled-back (`git reset --soft HEAD^`) and the process aborts.
- Ensures trunk sync and rebases feature as needed, pushes, monitors GitHub Actions with a progress bar, and merges feature to trunk on success.
- Exports `SOURCE_DATE_EPOCH`, builds (optionally signed), creates gem checksums, and runs `bundle exec rake release` (prompts for signing key + RubyGems MFA OTP as needed).
- Options:
- `start_step` map (skip directly to a phase):
1. Verify Bundler \>= 2.7 (always runs; start at 1 to do everything)
2. Detect version; RubyGems sanity check; confirm CHANGELOG/version; sync copyright years; update badges/headers
3. Run bin/setup
4. Run bin/rake (default task)
5. Run bin/rake appraisal:update if Appraisals present, then bin/rake yard
6. Ensure git user configured; commit release prep
7. Optional local CI with `act` (controlled by `K_RELEASE_LOCAL_CI`)
8. Ensure trunk in sync across remotes; rebase feature as needed
9. Push current branch to remotes (or 'all' remote)
10. Monitor CI after push; abort on failures
11. Merge feature into trunk and push
12. Checkout trunk and pull latest
13. Gem signing checks/guidance (skip with `SKIP_GEM_SIGNING=true`)
14. Build gem (bundle exec rake build)
15. Release gem (bundle exec rake release)
16. Generate and validate checksums (`bin/gem_checksums`)
17. Push checksum commit
18. Create GitHub Release (requires `GITHUB_TOKEN`)
19. Push tags to remotes (final)
- Examples:
- After intermittent CI failure, restart from monitoring: `bundle exec kettle-release start_step=10`
- After fixing a failed pre-release gate, rerun from the top: `bundle exec kettle-release`
- Tips:
- The commit message helper `exe/kettle-commit-msg` prefers project-local `.git-hooks` (then falls back to `~/.git-hooks`).
- The goalie file `commit-subjects-goalie.txt` controls when a footer is appended; customize `footer-template.erb.txt` as you like.
### Changelog generator
- Script: `exe/kettle-bump` (run as `kettle-bump`)
- Purpose: Bumps the current single gem's `lib/**/version.rb` before changelog
preparation. It accepts an exact version or `major`, `minor`, or `patch`.
- Usage:
- `kettle-bump patch`
- `kettle-bump 1.2.4 --from 1.2.3`
- `kettle-bump minor --dry-run`
- `kettle-bump patch --check`
- Behavior:
- Writes by default; use `--dry-run` to preview or `--check` to fail when a
bump would change files.
- Updates literal `spec.version = "..."` assignments in the gemspec when
they match the current version. Dynamic gemspec versions are left alone.
- Uses the same `K_CHANGELOG_VERSION_FILE` override as `kettle-changelog`
when a project needs to point at a specific version file.
- Script: `exe/kettle-changelog` (run as `kettle-changelog`)
- Purpose: Generates a new CHANGELOG.md section for the current version read from `lib/**/version.rb`, moves notes from the Unreleased section, and updates comparison links.
- Prerequisites:
- `coverage/coverage.json` present (generate with: `K_SOUP_COV_FORMATTERS="json" bin/rspec`).
- `bin/rake yard` available, to compute documentation coverage.
- Usage:
- `kettle-changelog`
- Behavior:
- Reads version from the unique `lib/**/version.rb` in the project.
- Moves entries from the `[Unreleased]` section into a new `[#.#.#] - YYYY-MM-DD` section.
- Prepends 4 lines with TAG, line coverage, branch coverage, and percent documented.
- Converts any GitLab-style compare links at the bottom to GitHub style, adds new tag/compare links for the new release and a temporary tag reference `[X.Y.Zt]`.
### Pre-release checks
- Script: `exe/kettle-gha-sha-pins` (run as `kettle-gha-sha-pins`)
- Purpose: Validate and optionally update GitHub Actions `uses:` refs to pinned
SHAs and current allowed release versions.
- Usage:
- `kettle-gha-sha-pins`
- `kettle-gha-sha-pins --check`
- `kettle-gha-sha-pins --write --upgrade patch`
- Behavior:
- Human output shows discovery, workflow scan, and action-resolution progress
on STDERR, including per-action timing via `ruby-progressbar`, then prints
the final report on STDOUT.
- Action metadata is resolved with the GitHub REST API and cached per
`owner/repo` action so duplicate uses of the same action reuse one
resolution plan.
- The outdated summary reports newer releases even when `--upgrade patch` or
`--upgrade minor` limits the write target to a safer release line.
- JSON output keeps progress disabled by default so STDOUT remains parseable.
Use `--progress` to force progress or `--no-progress` to suppress it.
- `--check` exits non-zero when workflow action pins are stale or mutable and
prints a recommended `kettle-gha-sha-pins --write --upgrade patch` command.
- Script: `exe/kettle-pre-release` (run as `kettle-pre-release`)
- Purpose: Run a suite of pre-release validations to catch avoidable mistakes (resumable by check number).
- Usage:
- `kettle-pre-release [--check-num N]`
- Short option: `kettle-pre-release -cN`
- Options:
- `--check-num N` Start from check number N (default: 1)
- Checks:
- 1) Validate GitHub Actions workflow action refs with `kettle-gha-sha-pins --check`; if pins are stale, it prints an outdated-actions summary, exits non-zero, and recommends `kettle-gha-sha-pins --write --upgrade patch`.
- 2) Normalize Markdown image URLs.
- 3) Validate that all image URLs referenced by Markdown files resolve (HTTP HEAD).
### Commit message helper (git hook)
- Script: `exe/kettle-commit-msg` (run by git as `.git/hooks/commit-msg`)
- Purpose: Append a standardized footer and optionally enforce branch naming rules when configured.
- Usage:
- Git invokes this with the path to the commit message file: `kettle-commit-msg .git/COMMIT_EDITMSG`
- Install hook templates through kettle-jem setup/templating, then point git at the resulting hook path.
- Behavior:
- When `GIT_HOOK_BRANCH_VALIDATE=jira`, validates the current branch matches the pattern: `^(hotfix|bug|feature|candy)/[0-9]{8,}-…`.
- If it matches and the commit message lacks the numeric ID, appends `[][]`.
- Always invokes `Kettle::Dev::GitCommitFooter.render` to potentially append a footer if allowed by the goalie.
- Prefers project-local `.git-hooks` templates; falls back to `~/.git-hooks`.
- Environment:
- `GIT_HOOK_BRANCH_VALIDATE` Branch rule (e.g., `jira`) or `false` to disable.
- `GIT_HOOK_FOOTER_APPEND` Enable footer auto-append when goalie allows (true/false).
- `GIT_HOOK_FOOTER_SENTINEL` Required marker to avoid duplicate appends when enabled.
- `GIT_HOOK_FOOTER_APPEND_DEBUG` Extra debug output in the footer template (true/false).
### Project bootstrap installer
- Script: `exe/kettle-dev-setup` (run as `kettle-dev-setup`)
- Status: Deprecated compatibility shim.
- Purpose: Direct users to kettle-jem, which now owns setup and templating.
- Usage:
- `kettle-dev-setup`
- Behavior:
- Prints migration instructions.
- Exits non-zero.
- Does not modify the destination repository.
- Replacement:
- `gem install kettle-jem`
- `kettle-jem setup`
### Open Collective README updater
- Script: `exe/kettle-readme-backers` (run as `kettle-readme-backers`)
- Purpose: Updates README sections for Open Collective backers (individuals) and sponsors (organizations) by fetching live data from your collective.
- Tags updated in README.md (first match wins for backers):
- The default tag prefix is `OPENCOLLECTIVE`, and it is configurable:
- ENV: `KETTLE_DEV_BACKER_README_OSC_TAG="OPENCOLLECTIVE"`
- YAML (.opencollective.yml): `readme-osc-tag: "OPENCOLLECTIVE"`
- The resulting markers become: ` … `, ` … `, and ` … `.
- ENV overrides YAML.
- Backers (Individuals): ` … ` or ` … `
- Sponsors (Organizations): ` … `
- Handle resolution:
1. `OPENCOLLECTIVE_HANDLE` environment variable, if set
2. `opencollective.yml` in the project root (e.g., `collective: "kettle-rb"` in this repo)
- Usage:
- `exe/kettle-readme-backers`
- `OPENCOLLECTIVE_HANDLE=my-collective exe/kettle-readme-backers`
- Behavior:
- Writes to README.md only if content between the tags would change.
- If neither the backers nor sponsors tags are present, prints a helpful warning and exits with status 2.
- When there are no entries, inserts a friendly placeholder: "No backers yet. Be the first\!" or "No sponsors yet. Be the first\!".
- When updates are written and the repository is a git work tree, the script stages README.md and commits with a message thanking new backers and subscribers, including mentions for any newly added backers and subscribers (GitHub @handles when their website/profile is a github.com URL; otherwise their name).
- Customize the commit subject via env var: `KETTLE_README_BACKERS_COMMIT_SUBJECT="💸 Thanks 🙏 to our new backers 🎒 and subscribers 📜"`.
- Or via .opencollective.yml: set `readme-backers-commit-subject: "💸 Thanks 🙏 to our new backers 🎒 and subscribers 📜"`.
- Precedence: ENV overrides .opencollective.yml; if neither is set, a sensible default is used.
- Note: When used with the provided `.git-hooks`, the subject should start with a gitmoji character (see [gitmoji][📌gitmoji]).
- Tip:
- Run this locally before committing to keep your README current, or schedule it in CI to refresh periodically.
- It runs automatically on a once-a-week schedule by the .github/workflows/opencollective.yml workflow that is part of the kettle-jem template.
- Authentication requirement:
- When running in CI with the provided workflow, you must provide an organization-level Actions secret named `README_UPDATER_TOKEN`.
- Create it under your GitHub organization settings: `https://github.com/organizations//settings/secrets/actions`.
- The updater will look for `REPO` or `GITHUB_REPOSITORY` (both usually set by GitHub Actions) to infer `` for guidance.
- If `README_UPDATER_TOKEN` is missing, the tool prints a helpful error to STDERR and aborts, including a direct link to the expected org settings page.
## 🔐 Security
See [SECURITY.md][🔐security].
## 🤝 Contributing
If you need some ideas of where to help, you could work on adding more code coverage,
or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
or use the gem and think about how it could be better.
We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
### 🚀 Release Instructions
See [CONTRIBUTING.md][🤝contributing].
### Code Coverage
Coverage service badges
[![Coverage Graph][🏀codecov-g]][🏀codecov]
[![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
[![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
### 🪇 Code of Conduct
Everyone interacting with this project's codebases, issue trackers,
chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
## 🌈 Contributors
[![Contributors][🖐contributors-img]][🖐contributors]
Made with [contributors-img][🖐contrib-rocks].
Also see GitLab Contributors: [https://gitlab.com/kettle-dev/kettle-dev/-/graphs/main][🚎contributors-gl]
⭐️ Star History
## 📌 Versioning
This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
For most applications, prefer the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
For example:
```ruby
spec.add_dependency("kettle-dev", "~> 2.0")
```
📌 Is "Platform Support" part of the public API? More details inside.
Dropping support for a platform can be a breaking change for affected users.
If a release changes supported platforms, it should be called out clearly in the changelog and versioned with that impact in mind.
To get a better understanding of how SemVer is intended to work over a project's lifetime,
read this article from the creator of SemVer:
- ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
See [CHANGELOG.md][📌changelog] for a list of releases.
## 📄 License
The gem is available under the following license: [AGPL-3.0-only](AGPL-3.0-only.md).
See [LICENSE.md][📄license] for details.
If none of the available licenses suit your use case, please [contact us](mailto:floss@galtzo.com) to discuss a custom commercial license.
### © Copyright
See [LICENSE.md][📄license] for the official copyright notice.
Copyright holders
- Copyright (c) 2023, 2025-2026 Peter H. Boling
## 🤑 A request for help
Maintainers have teeth and need to pay their dentists.
After getting laid off in an RIF in March, and encountering difficulty finding a new one,
I began spending most of my time building open source tools.
I'm hoping to be able to pay for my kids' health insurance this month,
so if you value the work I am doing, I need your support.
Please consider sponsoring me or the project.
To join the community or get help 👇️ Join the Discord.
[![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
To say "thanks!" ☝️ Join the Discord or 👇️ send money.
[![Sponsor kettle-dev/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
### Please give the project a star ⭐ ♥.
Many parts of this project are actively managed by a [kettle-jem](https://github.com/structuredmerge/structuredmerge-ruby/tree/main/gems/kettle-jem) smart template utilizing [StructuredMerge.org](https://structuredmerge.org) merge contracts.
Thanks for RTFM. ☺️
[⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
[⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611
[⛳liberapay]: https://liberapay.com/pboling/donate
[🖇osc-all-img]: https://img.shields.io/opencollective/all/kettle-dev
[🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/kettle-dev
[🖇osc-backers-img]: https://img.shields.io/opencollective/backers/kettle-dev
[🖇osc-backers]: https://opencollective.com/kettle-dev#backer
[🖇osc-backers-i]: https://opencollective.com/kettle-dev/backers/badge.svg?style=flat
[🖇osc-sponsors]: https://opencollective.com/kettle-dev#sponsor
[🖇osc-sponsors-i]: https://opencollective.com/kettle-dev/sponsors/badge.svg?style=flat
[🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/kettle-dev?style=for-the-badge
[🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/kettle-dev?style=for-the-badge
[🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/kettle-dev?style=for-the-badge
[🖇osc]: https://opencollective.com/kettle-dev
[🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github
[🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github
[🖇sponsor]: https://github.com/sponsors/pboling
[🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
[🖇polar]: https://polar.sh/pboling
[🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
[🖇kofi]: https://ko-fi.com/pboling
[🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
[🖇patreon]: https://patreon.com/galtzo
[🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
[🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
[🖇buyme]: https://www.buymeacoffee.com/pboling
[🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
[🖇paypal-bottom-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A
[🖇paypal]: https://www.paypal.com/paypalme/peterboling
[🖇floss-funding.dev]: https://floss-funding.dev
[🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding
[✉️discord-invite]: https://discord.gg/3qme4XHNKN
[✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
[✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white
[✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
[✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
[⛳️gem-namespace]: https://github.com/kettle-dev/kettle-dev
[⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle::Dev-3C2D2D.svg?style=square&logo=ruby&logoColor=white
[⛳️gem-name]: https://bestgems.org/gems/kettle-dev
[⛳️name-img]: https://img.shields.io/badge/name-kettle--dev-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
[⛳️tag-img]: https://img.shields.io/github/tag/kettle-dev/kettle-dev.svg
[⛳️tag]: https://github.com/kettle-dev/kettle-dev/releases
[🚂maint-blog]: http://www.railsbling.com/tags/kettle-dev
[🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
[🚂maint-contact]: http://www.railsbling.com/contact
[🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red
[💖🖇linkedin]: http://www.linkedin.com/in/peterboling
[💖🖇linkedin-img]: https://img.shields.io/badge/LinkedIn-Profile-0B66C2?style=flat&logo=newjapanprowrestling
[💖✌️wellfound]: https://wellfound.com/u/peter-boling
[💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound
[💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
[💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
[💖🐘ruby-mast]: https://ruby.social/@galtzo
[💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo
[💖🦋bluesky]: https://bsky.app/profile/galtzo.com
[💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
[💖🌳linktree]: https://linktr.ee/galtzo
[💖🌳linktree-img]: https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree
[💖💁🏼♂️devto]: https://dev.to/galtzo
[💖💁🏼♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white
[💖💁🏼♂️aboutme]: https://about.me/peter.boling
[💖💁🏼♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white
[💖🧊berg]: https://codeberg.org/pboling
[💖🐙hub]: https://github.org/pboling
[💖🛖hut]: https://sr.ht/~galtzo/
[💖🧪lab]: https://gitlab.com/pboling
[👨🏼🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share
[👨🏼🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white
[👨🏼🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
[👨🏼🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white
[🏙️entsup-tidelift]: https://tidelift.com/subscription/pkg/rubygems-kettle-dev?utm_source=rubygems-kettle-dev&utm_medium=referral&utm_campaign=readme
[🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white
[🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar
[💁🏼♂️peterboling]: http://www.peterboling.com
[🚂railsbling]: http://www.railsbling.com
[📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
[📜src-gl]: https://gitlab.com/kettle-dev/kettle-dev
[📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue
[📜src-cb]: https://codeberg.org/kettle-dev/kettle-dev
[📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green
[📜src-gh]: https://github.com/kettle-dev/kettle-dev
[📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
[📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
[📜gl-wiki]: https://gitlab.com/kettle-dev/kettle-dev/-/wikis/home
[📜gh-wiki]: https://github.com/kettle-dev/kettle-dev/wiki
[📜gl-wiki-img]: https://img.shields.io/badge/wiki-gitlab-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white
[📜gh-wiki-img]: https://img.shields.io/badge/wiki-github-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
[👽dl-rank]: https://bestgems.org/gems/kettle-dev
[👽dl-ranki]: https://img.shields.io/gem/rd/kettle-dev.svg
[👽version]: https://bestgems.org/gems/kettle-dev
[👽versioni]: https://img.shields.io/gem/v/kettle-dev.svg
[🏀qlty-mnt]: https://qlty.sh/gh/kettle-dev/projects/kettle-dev
[🏀qlty-mnti]: https://qlty.sh/gh/kettle-dev/projects/kettle-dev/maintainability.svg
[🏀qlty-cov]: https://qlty.sh/gh/kettle-dev/projects/kettle-dev/metrics/code?sort=coverageRating
[🏀qlty-covi]: https://qlty.sh/gh/kettle-dev/projects/kettle-dev/coverage.svg
[🏀codecov]: https://codecov.io/gh/kettle-dev/kettle-dev
[🏀codecovi]: https://codecov.io/gh/kettle-dev/kettle-dev/graph/badge.svg
[🏀coveralls]: https://coveralls.io/github/kettle-dev/kettle-dev?branch=main
[🏀coveralls-img]: https://coveralls.io/repos/github/kettle-dev/kettle-dev/badge.svg?branch=main
[🚎ruby-2.4-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-2.4.yml
[🚎ruby-2.5-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-2.5.yml
[🚎ruby-2.6-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-2.6.yml
[🚎ruby-2.7-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-2.7.yml
[🚎ruby-3.0-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-3.0.yml
[🚎ruby-3.1-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-3.1.yml
[🚎ruby-3.2-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-3.2.yml
[🚎ruby-3.3-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-3.3.yml
[🚎ruby-3.4-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/ruby-3.4.yml
[🚎jruby-9.2-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/jruby-9.2.yml
[🚎jruby-9.3-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/jruby-9.3.yml
[🚎jruby-9.4-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/jruby-9.4.yml
[🚎truby-22.3-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffleruby-22.3.yml
[🚎truby-23.0-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffleruby-23.0.yml
[🚎truby-23.1-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffleruby-23.1.yml
[🚎truby-24.2-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffleruby-24.2.yml
[🚎truby-25.0-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffleruby-25.0.yml
[🚎2-cov-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/coverage.yml
[🚎2-cov-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/coverage.yml/badge.svg
[🚎3-hd-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/heads.yml
[🚎3-hd-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/heads.yml/badge.svg
[🚎5-st-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/style.yml
[🚎5-st-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/style.yml/badge.svg
[🚎9-t-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffle.yml
[🚎9-t-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/truffle.yml/badge.svg
[🚎10-j-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/jruby.yml
[🚎10-j-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/jruby.yml/badge.svg
[🚎11-c-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/current.yml
[🚎11-c-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/current.yml/badge.svg
[🚎12-crh-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/dep-heads.yml
[🚎12-crh-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/dep-heads.yml/badge.svg
[🚎13-🔒️-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/locked_deps.yml
[🚎13-🔒️-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/locked_deps.yml/badge.svg
[🚎14-🔓️-wf]: https://github.com/kettle-dev/kettle-dev/actions/workflows/unlocked_deps.yml
[🚎14-🔓️-wfi]: https://github.com/kettle-dev/kettle-dev/actions/workflows/unlocked_deps.yml/badge.svg
[💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-3.4i]: https://img.shields.io/badge/Ruby-3.4-CC342D?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-4.0i]: https://img.shields.io/badge/Ruby-4.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
[💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
[💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
[💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
[💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
[💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
[💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
[💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
[💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
[💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red
[💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red
[💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red
[💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
[💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
[🤝gh-issues]: https://github.com/kettle-dev/kettle-dev/issues
[🤝gh-pulls]: https://github.com/kettle-dev/kettle-dev/pulls
[🤝gl-issues]: https://gitlab.com/kettle-dev/kettle-dev/-/issues
[🤝gl-pulls]: https://gitlab.com/kettle-dev/kettle-dev/-/merge_requests
[🤝cb-issues]: https://codeberg.org/kettle-dev/kettle-dev/issues
[🤝cb-pulls]: https://codeberg.org/kettle-dev/kettle-dev/pulls
[🤝cb-donate]: https://donate.codeberg.org/
[🤝contributing]: https://github.com/kettle-dev/kettle-dev/blob/main/CONTRIBUTING.md
[🏀codecov-g]: https://codecov.io/gh/kettle-dev/kettle-dev/graph/badge.svg
[🖐contrib-rocks]: https://contrib.rocks
[🖐contributors]: https://github.com/kettle-dev/kettle-dev/graphs/contributors
[🖐contributors-img]: https://contrib.rocks/image?repo=kettle-dev/kettle-dev
[🚎contributors-gl]: https://gitlab.com/kettle-dev/kettle-dev/-/graphs/main
[🪇conduct]: https://github.com/kettle-dev/kettle-dev/blob/main/CODE_OF_CONDUCT.md
[🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg
[📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
[📌semver]: https://semver.org/spec/v2.0.0.html
[📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat
[📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
[📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
[📌changelog]: https://github.com/kettle-dev/kettle-dev/blob/main/CHANGELOG.md
[📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
[📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
[📌gitmoji]: https://gitmoji.dev
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.100-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
[🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
[📄license]: LICENSE.md
[📄license-ref]: AGPL-3.0-only.md
[📄license-img]: https://img.shields.io/badge/License-AGPL--3.0--only-259D6C.svg
[📄license-compat]: https://www.apache.org/legal/resolved.html#category-x
[📄license-compat-img]: https://img.shields.io/badge/Apache_Incompatible:_Category_X-%E2%9C%97-C0392B.svg?style=flat&logo=Apache
[📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
[📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat
[🚎yard-current]: http://rubydoc.info/gems/kettle-dev
[🚎yard-head]: https://kettle-dev.galtzo.com
[💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums
[💎SHA_checksums]: https://gitlab.com/kettle-dev/kettle-dev/-/tree/main/checksums
[💎rlts]: https://github.com/rubocop-lts/rubocop-lts
[💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
[💎appraisal2]: https://github.com/appraisal-rb/appraisal2
[💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
[💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
| Field | Value |
|---|---|
| Package | kettle-dev |
| Description | 🍲 Kettle::Dev is a meta tool from kettle-rb to streamline development and testing. Acts as a shim dependency, pulling in many other dependencies, to give you OOTB productivity with a RubyGem, or Ruby app project. Configures a complete set of Rake tasks, for all the libraries is brings in, so they arrive ready to go. Fund overlooked open source projects - bottom of stack, dev/test dependencies: floss-funding.dev |
| Homepage | https://github.com/kettle-dev/kettle-dev |
| Source | https://github.com/kettle-dev/kettle-dev/tree/v2.2.1 |
| License | `AGPL-3.0-only` |
| Funding | https://github.com/sponsors/pboling, https://issuehunt.io/u/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/kettle-dev, https://opencollective.com/kettle-rb, https://patreon.com/galtzo, https://polar.sh/pboling, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/kettle-dev, https://www.buymeacoffee.com/pboling |