From e013d20887416c064f7ca335ed362ce411ca426a Mon Sep 17 00:00:00 2001 From: aki Date: Sat, 20 Jun 2026 18:39:56 +0900 Subject: [PATCH 1/4] chore: drop EOL Ruby and Rails versions and bump to 0.16.0 Drop Ruby 3.1/3.2 and Rails 7.1 (all EOL as of today per endoflife.date) from the CI matrix and gemspec lower bounds. With the remaining Ruby all 3.3+, every Ruby x Rails combination is valid, so the matrix exclude block is no longer needed. Raising required_ruby_version is a breaking change for installs, so bump the minor version to 0.16.0. --- .github/workflows/rspec.yml | 11 ++--------- csb.gemspec | 4 ++-- gemfiles/rails71.gemfile | 5 ----- lib/csb/version.rb | 2 +- 4 files changed, 5 insertions(+), 17 deletions(-) delete mode 100644 gemfiles/rails71.gemfile diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ef5ad4c..a9f49ff 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -16,15 +16,8 @@ jobs: strategy: fail-fast: false matrix: - ruby: ["3.1", "3.2", "3.3", "3.4", "4.0"] - gemfile: ["rails71", "rails72", "rails80", "rails81"] - exclude: - # rails 8.0: support ruby 3.2+ - - ruby: "3.1" - gemfile: "rails80" - # rails 8.1: support ruby 3.2+ - - ruby: "3.1" - gemfile: "rails81" + ruby: ["3.3", "3.4", "4.0"] + gemfile: ["rails72", "rails80", "rails81"] steps: - uses: actions/checkout@v6 diff --git a/csb.gemspec b/csb.gemspec index aa482d7..b05902c 100644 --- a/csb.gemspec +++ b/csb.gemspec @@ -26,9 +26,9 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.required_ruby_version = '>= 3.1.0' + spec.required_ruby_version = '>= 3.3.0' - spec.add_dependency "rails", ">= 7.1.4" + spec.add_dependency "rails", ">= 7.2.0" spec.add_dependency "csv" spec.add_development_dependency "rake" diff --git a/gemfiles/rails71.gemfile b/gemfiles/rails71.gemfile deleted file mode 100644 index 65f1f08..0000000 --- a/gemfiles/rails71.gemfile +++ /dev/null @@ -1,5 +0,0 @@ -source "http://rubygems.org" - -gem 'rails', '~> 7.1.4' - -gemspec path: '../' diff --git a/lib/csb/version.rb b/lib/csb/version.rb index cfc0971..71520d5 100644 --- a/lib/csb/version.rb +++ b/lib/csb/version.rb @@ -1,3 +1,3 @@ module Csb - VERSION = '0.15.0' + VERSION = '0.16.0' end From 17eea89e4e061b01d5f6fa9069f6be591057f0c9 Mon Sep 17 00:00:00 2001 From: aki Date: Sat, 20 Jun 2026 18:40:00 +0900 Subject: [PATCH 2/4] chore: use https for rubygems source in gemfiles --- gemfiles/rails72.gemfile | 2 +- gemfiles/rails80.gemfile | 2 +- gemfiles/rails81.gemfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gemfiles/rails72.gemfile b/gemfiles/rails72.gemfile index 721906b..edc36fa 100644 --- a/gemfiles/rails72.gemfile +++ b/gemfiles/rails72.gemfile @@ -1,4 +1,4 @@ -source "http://rubygems.org" +source "https://rubygems.org" gem 'rails', '~> 7.2.0' diff --git a/gemfiles/rails80.gemfile b/gemfiles/rails80.gemfile index 82532f7..2cc44c5 100644 --- a/gemfiles/rails80.gemfile +++ b/gemfiles/rails80.gemfile @@ -1,4 +1,4 @@ -source "http://rubygems.org" +source "https://rubygems.org" gem 'rails', '~> 8.0.0' diff --git a/gemfiles/rails81.gemfile b/gemfiles/rails81.gemfile index c7a213c..4d934d2 100644 --- a/gemfiles/rails81.gemfile +++ b/gemfiles/rails81.gemfile @@ -1,4 +1,4 @@ -source "http://rubygems.org" +source "https://rubygems.org" gem 'rails', '~> 8.1.0' From 51f5f3a88341b901f46303175a41e7707a53bc2d Mon Sep 17 00:00:00 2001 From: aki Date: Sat, 20 Jun 2026 18:40:04 +0900 Subject: [PATCH 3/4] chore: add ruby-rails-ci-matrix skill --- .claude/skills/ruby-rails-ci-matrix/SKILL.md | 108 +++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 .claude/skills/ruby-rails-ci-matrix/SKILL.md diff --git a/.claude/skills/ruby-rails-ci-matrix/SKILL.md b/.claude/skills/ruby-rails-ci-matrix/SKILL.md new file mode 100644 index 0000000..a84a8d7 --- /dev/null +++ b/.claude/skills/ruby-rails-ci-matrix/SKILL.md @@ -0,0 +1,108 @@ +--- +description: Maintain the Ruby and Rails version matrix tested in CI for a Ruby gem. Use this when you need to remove EOL versions, add the latest supported versions, and update gemfiles and gemspec accordingly. Always use this for requests like 'remove unsupported Ruby/Rails versions', 'add the latest Rails', or 'update the CI matrix'. +license: MIT +metadata: + github-path: skills/ruby/ruby-rails-ci-matrix + github-ref: refs/heads/main + github-repo: https://github.com/aki77/skills + github-tree-sha: 59898557bcf3dd4e734ae3f25c8ab025a43341be +name: ruby-rails-ci-matrix +--- +# ruby-rails-ci-matrix + +Maintain the Ruby and Rails versions tested in CI for a Ruby gem that uses GitHub Actions matrix strategy with `gemfiles/railsXX.gemfile` and a gemspec. This skill keeps the test matrix aligned with the current support status. + +Remove EOL (End of Life) versions and add currently supported and latest stable versions. The gemfile, gemspec, and workflow YAML must be updated **in sync** — updating only one will break CI. + +## 1. Assess the Current State + +Before making any changes, read all three types of files involved. + +| File | What to check | +| --- | --- | +| `.github/workflows/*.yml` | `strategy.matrix.include` entries (`{ ruby:, gemfile: }`), `ruby/setup-ruby` version | +| `gemfiles/*.gemfile` | Per-Rails-version gemfiles — `source` URL and `gem 'rails', '~> X.Y.0'` | +| `*.gemspec` | `required_ruby_version` and the lower bound of `add_dependency "rails", ...` | + +Note that the `gemfile:` values in the matrix correspond 1:1 with `gemfiles/.gemfile`. + +## 2. Research EOL Status + +**Use today's date as the reference** and fetch the latest support information — do not rely on memory. + +- Ruby: +- Rails: + +If endoflife.date is unreachable, use WebSearch as a fallback. Confirm the following three things: + +1. EOL date for each version (including security support end date) — has it passed as of today? +2. Full list of currently supported versions +3. Latest stable releases (check whether a new major like Ruby 4.0 or Rails 8.1 has been released) + +> Ruby releases a new version every December with ~3 years 3 months of support. Rails 7.2+ receives 1 year of standard support and 2 years of security support. + +## 3. Decide What to Add and Remove + +- **Remove**: Ruby / Rails versions that are EOL (security support also ended) as of today. +- **Add**: Supported versions not yet in the matrix, plus the latest stable releases. +- **Keep**: Versions still under security support. For versions expiring within a few months, ask the user whether to keep them. +- Build the matrix as **each Rails version × the compatible Ruby versions**. Pay attention to compatibility — older Rails versions may not support the newest Ruby. + +## 4. Update Files + +Keep all three files consistent. **If you remove a gemfile, remove the matrix entry too** (and vice versa). + +### Workflow YAML Matrix + +Update the `include:` entries. Use short-form Ruby version strings (`"4.0"`) so `ruby/setup-ruby` automatically picks the latest patch. + +```yaml +strategy: + matrix: + include: + - { ruby: "3.3", gemfile: "rails72" } + - { ruby: "3.4", gemfile: "rails72" } + - { ruby: "4.0", gemfile: "rails72" } + - { ruby: "3.3", gemfile: "rails80" } + - { ruby: "3.4", gemfile: "rails80" } + - { ruby: "4.0", gemfile: "rails80" } + - { ruby: "3.3", gemfile: "rails81" } + - { ruby: "3.4", gemfile: "rails81" } + - { ruby: "4.0", gemfile: "rails81" } +``` + +### Create / Delete Gemfiles + +For a new Rails version, copy an existing gemfile and change only the `~> X.Y.0` constraint. + +```ruby +source "https://rubygems.org" + +gem 'rails', '~> 8.1.0' +gem 'sqlite3' + +gemspec path: '../' +``` + +Delete the gemfile for any Rails version being dropped. + +### Update gemspec Lower Bounds + +Update two lines to match the minimum supported versions. + +```ruby +spec.required_ruby_version = '>= 3.3.0' # minimum supported Ruby +spec.add_dependency "rails", ">= 7.2.0" # minimum supported Rails +``` + +## Notes + +- **Always use `https://rubygems.org`** as the `source` — fix any `http://` occurrences. +- **`ruby/setup-ruby@v1` and new majors**: For brand-new majors like Ruby 4.0, verify that setup-ruby already supports it (it usually does very quickly). +- **Raising `required_ruby_version` is a breaking change**. Users on the old Ruby version will no longer be able to install the gem, so a minor or major gem version bump is required at release time. Handle this in a separate PR / commit, not as part of this matrix update. + +## Pitfalls + +- **Forgetting to update the gemspec lower bounds** means the old Ruby/Rails version you removed from CI can still be `gem install`-ed, creating a mismatch between stated and actual support. +- **Updating only the gemfile or only the matrix** breaks CI — either a missing gemfile is referenced, or an unused gemfile is left behind. Always update both together. +- **Mixing unrelated changes** (e.g., fixing `http://` → `https://` sources) into the same commit as version removals obscures intent. Commit each logical unit separately. From 94c25ed160f65491c34f04703390d24592182852 Mon Sep 17 00:00:00 2001 From: aki Date: Sat, 20 Jun 2026 18:42:47 +0900 Subject: [PATCH 4/4] chore: exclude .claude directory from packaged gem --- csb.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csb.gemspec b/csb.gemspec index b05902c..6d98ed6 100644 --- a/csb.gemspec +++ b/csb.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|\.claude)/}) } end spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }