Skip to content

Ruby: full make check (rspec) for Rails projects needs BUNDLE_APP_CONFIG, test DB setup, and bundle exec wrapping #30

@matthew-on-git

Description

@matthew-on-git

Summary

Following up on #25 (resolved in v1.9.0 — Ruby 3.4 + RUBY_PATHS scoping) and the libyaml-dev fix in #28/#29 (resolved). With both shipped, bundle install now works inside the container against a Rails 7.1+ Gemfile. But make check still can't fully exercise rspec / rubocop / brakeman against a Rails project without three more adjustments.

Filing one combined issue rather than three small ones because they're all "what a Rails 7.1+ project needs to make make check actually mirror its CI."

Gap A — Container's BUNDLE_APP_CONFIG overrides project .bundle/config

The container exports BUNDLE_APP_CONFIG=/usr/local/bundle (so its bundled gems are findable). This overrides project-local .bundle/config. Result: a project that does bundle install --path vendor/bundle (the standard pattern for sandboxed bundles) — and stores BUNDLE_PATH: "vendor/bundle" in .bundle/config — has its setting silently ignored by the container. Bundler then can't find any gems and rspec exits before running anything.

Reproduce:

# In a Rails project with vendor/bundle populated
docker run --rm -v $(pwd):/workspace -w /workspace \
  ghcr.io/devrail-dev/dev-toolchain:v1 \
  bash -c 'bundle config | head -5; bundle exec rspec --version'

Actual:

path
Set via BUNDLE_PATH: "/usr/local/bundle"
...
bundler: failed to load command: rspec (/usr/local/bundle/bin/rspec)
Could not find rails-7.1.6, ...

Workaround a consumer can apply: add -e BUNDLE_APP_CONFIG=/workspace/.bundle to their DOCKER_RUN. But this is brittle — consumers won't know to do it and the failure mode is opaque.

Suggested upstream fix: the reference Makefile's DOCKER_RUN should set BUNDLE_APP_CONFIG=/workspace/.bundle (or unset it) when HAS_RUBY is detected, OR the container should not export it as a default and instead set BUNDLE_PATH per-invocation only when needed.

Gap B — _test for Ruby doesn't prepare the test database

The reference Makefile's _test Ruby branch calls rspec directly. But Rails specs need the test database migrated. A typical CI pipeline does:

script:
  - bundle exec rake db:migrate:reset RAILS_ENV=test
  - bundle exec rspec

Locally via make check, this fails — every spec that touches the DB errors out before assertions run. In tipsyhive's case ~228 spec failures all rooted in "test DB not migrated."

There's also the prerequisite that a test database exists — i.e., a Postgres service is running and reachable. CI provides this via services:. Locally, the consumer has to bring their own.

Suggested upstream fix: before invoking rspec, run bundle exec rails db:test:prepare (idempotent, fast when up-to-date). If a configured DATABASE_URL isn't reachable, fail with a clear "test database unreachable — start postgres" error rather than 200 spec errors. Document the postgres-running requirement in the README.

Gap C — rubocop / reek in the container vs project's Gemfile

The reference Makefile invokes rubocop (and reek) directly, using whatever's in the container PATH. But Rails projects pin specific rubocop/rubocop-rails/rubocop-rspec versions in their Gemfile, plus a project-local .rubocop.yml. CI runs bundle exec rubocop which uses the project's pinned versions.

When the dev-toolchain's rubocop differs from the project's, you get spurious lint diffs (different default cops, different inflection rules). For tipsyhive, the dev-toolchain's rubocop reports issues that CI's bundle-exec rubocop doesn't — because they're different versions with different rules enabled.

Suggested upstream fix: when HAS_RUBY is detected and a Gemfile is present, _lint and _format should prefer bundle exec rubocop over plain rubocop. Same for _security (bundle exec brakeman, bundle exec bundler-audit).

Combined impact

A consumer following the README and dropping languages: [ruby] into .devrail.yml for a typical Rails 7.1+ project will see:

  • make test: ~all specs fail (no DB)
  • make lint: spurious warnings vs CI (different rubocop version)
  • make format: same issue
  • make security: similar (brakeman version drift, bundler-audit env quirks)

The image works; the orchestration doesn't quite mirror what bundle exec + a real DB would.

Suggested combined acceptance criteria

  • DOCKER_RUN clears or rewrites BUNDLE_APP_CONFIG for Ruby projects
  • _test runs bundle exec rails db:test:prepare before rspec, with a clear error if DB unreachable
  • _lint/_format/_security prefer bundle exec when a Gemfile is present
  • CI smoke test that exercises a minimal Rails 7.1 project with a Postgres service through make check
  • README documents the postgres-service requirement for Rails projects
  • CHANGELOG entries

Repro environment

Why filing as one issue

Each gap individually is small; together they're the difference between "consumer copies Makefile and gets a CI-equivalent local check" and "consumer hits three errors in sequence and gives up." Cleaner to fix as a coordinated wave.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions