heroku / heroku-buildpack-ruby

Heroku's buildpack for Ruby applications.
MIT License
785 stars 1.87k forks source link

ruby required for compiling webpack assets in rails build, missing from nodejs buildpack and stack 22 #1433

Open neontuna opened 3 months ago

neontuna commented 3 months ago

I'm not sure whether to open this here or under the nodejs buildpack but the removal of system ruby from Heroku Stack 22 is causing issues.

I'm in the middle of upgrading our Rails app from 6 to 7, and from Ruby 2.7 to 3.3. Part of this has meant a switch to jsbundling-rails, propshaft, and webpack 5. We use the rails-erb-loader, specifically for generating rails route helpers in JS.

rails-erb-loader requires ruby (or rails runner) to run. I have the nodejs buildpack listed before ruby in the Heroku config (so I can specify node version) and because of this when Yarn runs the compile step, ruby is missing. This causes the compile to fail

remote: /usr/bin/env: ‘ruby’: No such file or directory

For now I'll be downgrading to stack 20 but I don't see a way to fix this. It would be nice if we could just reinstall system ruby on stack 22.

/edit

actually, that's not going to work either - because system ruby on stack 20 is 2.7. So yeah... this is a real pickle for us :/

edmorley commented 2 months ago

@neontuna Hi! Even if system Ruby were available, presumably rails-erb-loader needs not only Ruby but the app dependencies too (depending on what the erb templates import from your app)? And as such just having system Ruby wouldn't be sufficient on its own, but instead the whole Ruby buildpack step needs to have run. (Plus as you note, the system Ruby version is typically different from the Ruby version that will be installed by the Ruby buildpack, so having two different Ruby versions being used within the build doesn't sound ideal, even if rails-erb-loader was compatible with system Ruby.)

To break this circular dependency (the Node build step requiring Ruby, and the Ruby build step requiring Node), what about skipping the webpack compile during the execution of the Node.js buildpack and instead running it as a step after the Ruby buildpack?

ie:

  1. Let the Node.js buildpack install Node, Yarn, dependencies etc
  2. The Ruby buildpack runs
  3. Then have the webpack compile / yarn build run (either by hooking into the assets precompile task the Ruby buildpack runs automatically, or else using a buildpack like https://github.com/weibeld/heroku-buildpack-run or https://github.com/heroku/heroku-buildpack-inline)