Summary
The Makefile + image already declare Ruby support (HAS_RUBY, rubocop, rspec, reek), but a real-world Rails project (Rails 7.1, Ruby 3.2) cannot use make check without significant setup gymnastics. Two distinct gaps surfaced when wholesale-syncing the reference Makefile into a downstream Rails consumer:
- Image ships Ruby 3.1.2 — too old to parse Gemfiles that use the
windows platform alias (introduced in Bundler shipped with Ruby 3.2).
reek and (likely) rubocop defaults scan vendor/bundle/ — generates tens of thousands of warnings and runs for minutes against installed gem code.
Both are blocking adoption for any Rails 7+ project.
Gap 1 — Image Ruby version (3.1.2) too old for modern Gemfiles
Reproduce
In a downstream project with a typical Rails 7.1 Gemfile:
# Gemfile
group :development, :test do
gem 'debug', platforms: %i[mri windows]
end
Run make test against ghcr.io/devrail-dev/dev-toolchain:v1:
Actual
Bundler::GemfileError:
`windows` is not a valid platform. The available options are: [:ruby, :ruby_18, ...,
:mri, ..., :mswin, ..., :mingw, ..., :x64_mingw, ...]
_test exits non-zero in 341ms. RSpec never runs.
Why
Image: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) (verified via docker run --rm ghcr.io/devrail-dev/dev-toolchain:v1 ruby --version).
Bundler shipped with Ruby 3.1.x does not recognize the windows platform alias, which was added in a later Bundler release (shipped with Ruby 3.2+). Modern Rails generators emit platforms: %i[mri windows] in the default Gemfile, so any Rails 7+ project using rails new will hit this immediately.
Suggested fix
Bump the base image (or COPY layer) to Ruby 3.2+. Confirm in CI by adding a smoke test that runs bundle install against a Gemfile containing the windows platform tag.
Gap 2 — reek (and probably rubocop) defaults scan vendor/bundle/
Reproduce
In a downstream project with .devrail.yml declaring languages: [ruby] and a typical vendor/bundle/ from bundle install --path vendor/bundle:
Actual
... 73,742 total warnings ...
vendor/bundle/ruby/3.2.0/gems/zeitwerk-2.7.5/lib/zeitwerk/registry.rb -- 4 warnings:
[4]:IrresponsibleModule: Zeitwerk::Registry has no descriptive comment
[53]:NestedIterators: ...
[48]:TooManyStatements: ...
...
{"target":"lint","status":"fail","duration_ms":245518,
"languages":["ruby"],"failed":["ruby:rubocop","ruby:reek"]}
_lint runs for 245 seconds and reports 73K+ warnings — almost all from gems in vendor/bundle/ (Zeitwerk, ActiveSupport, etc.), not the project's own code.
Why
The current internal targets call reek (and per the same pattern, rubocop) against . with no exclusions and no path scope. Rails projects conventionally restrict linting to app lib spec (and sometimes config bin). Without that, every gem's source code is treated as project code.
A downstream .reek.yml / .rubocop.yml could exclude vendor/, but two reasons that's not a clean solution:
- Most consumers never look at the upstream Makefile and won't know they need to add this config.
- Even with the config, the runtime is still wasted enumerating thousands of files.
Suggested fix
Default the Ruby lint/format scope to a sensible Rails-shaped path set, with an override hook:
RUBY_PATHS ?= app lib spec
# in _lint:
rubocop $(RUBY_PATHS) || ...
reek $(RUBY_PATHS) || ...
Or, alternatively, default to . but always exclude vendor/, node_modules/, tmp/, log/, and .git/ — matching the pattern already used in _lint for bash (-not -path './vendor/*').
The bash branch already does this:
sh_files=$$(find . -name '*.sh' -not -path './.git/*' -not -path './vendor/*' -not -path './node_modules/*' 2>/dev/null);
The Ruby branch needs the equivalent.
Combined impact
A consumer following README.md and dropping languages: [ruby] into .devrail.yml will see make check fail catastrophically on a fresh Rails project:
_test: Bundler error; RSpec never runs
_lint: 245s of noise, 73K warnings, exit 1
_format, _security: likely the same scope issue
This is currently being worked around in at least one downstream project by leaving the Makefile pinned to an older DevRail vintage that predates Ruby support entirely. That defeats the value proposition.
Repro environment
- Image:
ghcr.io/devrail-dev/dev-toolchain:v1 (whatever :v1 resolves to as of 2026-04-25)
- Host: Linux 6.19 / Docker 28.x
- Downstream project: Rails 7.1, Ruby 3.2, RSpec 3.13, RuboCop 1.85, standard
vendor/bundle layout
Happy to provide a minimal reproducer repo if useful.
Suggested acceptance criteria
Summary
The Makefile + image already declare Ruby support (
HAS_RUBY,rubocop,rspec,reek), but a real-world Rails project (Rails 7.1, Ruby 3.2) cannot usemake checkwithout significant setup gymnastics. Two distinct gaps surfaced when wholesale-syncing the reference Makefile into a downstream Rails consumer:windowsplatform alias (introduced in Bundler shipped with Ruby 3.2).reekand (likely)rubocopdefaults scanvendor/bundle/— generates tens of thousands of warnings and runs for minutes against installed gem code.Both are blocking adoption for any Rails 7+ project.
Gap 1 — Image Ruby version (3.1.2) too old for modern Gemfiles
Reproduce
In a downstream project with a typical Rails 7.1 Gemfile:
Run
make testagainstghcr.io/devrail-dev/dev-toolchain:v1:Actual
_testexits non-zero in 341ms. RSpec never runs.Why
Image:
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a)(verified viadocker run --rm ghcr.io/devrail-dev/dev-toolchain:v1 ruby --version).Bundler shipped with Ruby 3.1.x does not recognize the
windowsplatform alias, which was added in a later Bundler release (shipped with Ruby 3.2+). Modern Rails generators emitplatforms: %i[mri windows]in the default Gemfile, so any Rails 7+ project usingrails newwill hit this immediately.Suggested fix
Bump the base image (or COPY layer) to Ruby 3.2+. Confirm in CI by adding a smoke test that runs
bundle installagainst a Gemfile containing thewindowsplatform tag.Gap 2 —
reek(and probablyrubocop) defaults scanvendor/bundle/Reproduce
In a downstream project with
.devrail.ymldeclaringlanguages: [ruby]and a typicalvendor/bundle/frombundle install --path vendor/bundle:Actual
_lintruns for 245 seconds and reports 73K+ warnings — almost all from gems invendor/bundle/(Zeitwerk, ActiveSupport, etc.), not the project's own code.Why
The current internal targets call
reek(and per the same pattern,rubocop) against.with no exclusions and no path scope. Rails projects conventionally restrict linting toapp lib spec(and sometimesconfig bin). Without that, every gem's source code is treated as project code.A downstream
.reek.yml/.rubocop.ymlcould excludevendor/, but two reasons that's not a clean solution:Suggested fix
Default the Ruby lint/format scope to a sensible Rails-shaped path set, with an override hook:
Or, alternatively, default to
.but always excludevendor/,node_modules/,tmp/,log/, and.git/— matching the pattern already used in_lintfor bash (-not -path './vendor/*').The bash branch already does this:
The Ruby branch needs the equivalent.
Combined impact
A consumer following
README.mdand droppinglanguages: [ruby]into.devrail.ymlwill seemake checkfail catastrophically on a fresh Rails project:_test: Bundler error; RSpec never runs_lint: 245s of noise, 73K warnings, exit 1_format,_security: likely the same scope issueThis is currently being worked around in at least one downstream project by leaving the Makefile pinned to an older DevRail vintage that predates Ruby support entirely. That defeats the value proposition.
Repro environment
ghcr.io/devrail-dev/dev-toolchain:v1(whatever:v1resolves to as of 2026-04-25)vendor/bundlelayoutHappy to provide a minimal reproducer repo if useful.
Suggested acceptance criteria
_lintRuby branch scopesrubocop/reekto project paths (or excludesvendor/,node_modules/,tmp/,log/,.git/)_format,_securityRuby branches use the same scope as_lintwindowsplatform) confirmsmake checkpasses