Precompilation breaking on heroku, works locally

2019-09-06 08:37发布

问题:

I did some restructuring of our less files. Everything works locally (e.g. rake assets:precompile), but on Heroku my push fails with the following:

Running: rake assets:precompile
       adding placeholder
       rake aborted!
       Less::ParseError: variable @brand-primary is undefined
       (in /tmp/build_24298d78-579f-44a3-ae43-c4d82b9dde9d/app/assets/stylesheets/lectures/lectures.less)
       at /tmp/build_24298d78-579f-44a3-ae43-c4d82b9dde9d/vendor/bundle/ruby/2.1.0/gems/less-2.5.1/lib/less/js/lib/less/parser.js:604:31

After much poking around, I decided to remove the import statement for the offending file (lectures.less) to see what breaks next. With the change committed and pushed to Github, I tried pushing again to Heroku, and got the exact same error -- the precompilation is now breaking on a file that shouldn't be imported any more.

Details pasted below; anyone got any tips? I've tried both heroku run rake assets:clean and heroku run rake tmp:clear, but I didn't expect them to work anyway.

My application.css is barebones:

...
 * You're free to add application-wide styles to this file and they'll appear at the top of the
 * compiled file, but it's generally better to create a new file per style scope.
 *
 *= require main
 */

PREVIOUSLY I was requiring the lectures file and some others in application.css, but moved it into the main.less.

My main.less has the rest of the imports:

@import "settings";
@import "variables";
...
@import "lectures/lectures.less";
...

Relevant environment settings:

development.rb

config.assets.precompile                           += %w( admin.js admin.css )
config.less.dumpLineNumbers                        = 'all'
config.assets.debug                                = true
config.serve_static_assets = true
config.assets.compile = true
config.assets.raise_runtime_errors                 = true

staging.rb

config.assets.precompile += %w( admin.js admin.css )
config.serve_static_assets = true
config.assets.compile = false
config.assets.digest = true
config.assets.version = '1.0'

relevant gems:

ruby '2.1.2'
gem 'rails', '>= 4'
gem 'less-rails', github: 'metaskills/less-rails'

回答1:

We appeared to have fixed the issue by bumping the config.assets.version setting in production.rb, e.g.

- config.assets.version = '1.0'
+ config.assets.version = '1.1'

It's not clear in the slightest to me why heroku didn't recognize the changes and why heroku run rake assets:clean didn't do it, but there you go.

EDIT ################# It's been a while since this, and to keep from having the issue on a regular basis, we wound up tying the version # to our commit sha. Something like this:

whatever.rb

heroku = Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
$asset_version = heroku.get_releases(ENV["HEROKU_APP_NAME"]).body[-1]["commit"]

production.rb

config.assets.version = $asset_version