Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Precompilation fails on Heroku #29

Merged
merged 1 commit into from
Mar 29, 2012
Merged

Precompilation fails on Heroku #29

merged 1 commit into from
Mar 29, 2012

Conversation

jwhitley
Copy link
Owner

Hi,

Heroku requires this line for deployment: config.assets.initialize_on_precompile = false

It causes rake assets:precompile to fail. Here is the trace:

** Invoke assets:precompile (first_time)
** Invoke requirejs:precompile:stage1 (first_time)
** Invoke requirejs:test_node (first_time)
** Execute requirejs:test_node
** Invoke requirejs:precompile:prepare_source (first_time)
** Invoke requirejs:setup (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute requirejs:setup
** Invoke requirejs:clean (first_time)
** Invoke requirejs:setup 
** Execute requirejs:clean
** Invoke requirejs:assets:keep_js (first_time)
** Invoke requirejs:setup 
** Execute requirejs:assets:keep_js
** Execute requirejs:precompile:prepare_source
** Invoke requirejs:precompile:generate_rjs_driver (first_time)
** Invoke requirejs:setup 
** Execute requirejs:precompile:generate_rjs_driver
** Invoke requirejs:precompile:run_rjs (first_time)
** Invoke requirejs:setup 
** Invoke requirejs:test_node 
** Execute requirejs:precompile:run_rjs
** Execute requirejs:precompile:stage1
** Execute assets:precompile
/Users/kalema/.rvm/rubies/ruby-1.9.2-p290/bin/ruby /Users/kalema/.rvm/gems/ruby-1.9.2-p290/bin/rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets --trace
** Invoke assets:precompile:all (first_time)
** Execute assets:precompile:all
** Invoke assets:precompile:primary (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke tmp:cache:clear (first_time)
** Execute tmp:cache:clear
** Invoke requirejs:precompile:stage2 (first_time)
** Invoke requirejs:precompile:digestify_and_compress (first_time)
** Invoke requirejs:setup (first_time)
** Invoke environment (first_time)
** Execute environment
rake aborted!
Application has been already initialized.
~/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/application.rb:95:in `initialize!'
~/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/railtie/configurable.rb:30:in `method_missing'
~/Sites/Perso/Recruitee/Site/www_app/config/environment.rb:5:in `<top (required)>'
~/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in `require'
~/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in `block in require'
~/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:225:in `load_dependency'
~/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in `require'
~/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/application.rb:83:in `require_environment!'
~/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/application.rb:193:in `block (2 levels) in initialize_tasks'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:176:in `block in invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:157:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:176:in `block in invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:157:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:176:in `block in invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:157:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:176:in `block in invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:174:in `invoke_prerequisites'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:157:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:144:in `invoke'
~/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.1.3/lib/sprockets/assets.rake:56:in `block (3 levels) in <top (required)>'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:144:in `invoke'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:116:in `invoke_task'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block (2 levels) in top_level'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block in top_level'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:88:in `top_level'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:66:in `block in run'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:63:in `run'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/bin/rake:33:in `<top (required)>'
~/.rvm/gems/ruby-1.9.2-p290/bin/rake:19:in `load'
~/.rvm/gems/ruby-1.9.2-p290/bin/rake:19:in `<main>'
Tasks: TOP => assets:precompile:primary => requirejs:precompile:stage2 => requirejs:precompile:digestify_and_compress => requirejs:setup => environment
rake aborted!
Command failed with status (1): [/Users/kalema/.rvm/rubies/ruby-1.9.2-p290/...]
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/file_utils.rb:53:in `block in create_shell_runner'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `call'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `sh'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `sh'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/file_utils.rb:80:in `ruby'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `ruby'
~/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.1.3/lib/sprockets/assets.rake:9:in `ruby_rake_task'
~/.rvm/gems/ruby-1.9.2-p290/gems/requirejs-rails-0.5.3/lib/tasks/requirejs-rails_tasks.rake:46:in `invoke_or_reboot_rake_task'
~/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.1.3/lib/sprockets/assets.rake:25:in `block (2 levels) in <top (required)>'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
~/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/task.rb:144:in `invoke'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:116:in `invoke_task'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block (2 levels) in top_level'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `each'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block in top_level'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:88:in `top_level'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:66:in `block in run'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/application.rb:63:in `run'
~/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/bin/rake:33:in `<top (required)>'
~/.rvm/gems/ruby-1.9.2-p290/bin/rake:19:in `load'
~/.rvm/gems/ruby-1.9.2-p290/bin/rake:19:in `<main>'
Tasks: TOP => assets:precompile

@benbabics
Copy link

I'm also having the same issue. The only thing that works for me is to change initialize_on_precompile to true:
config.assets.initialize_on_precompile = true

This will mean we have to precompile locally and deal with conflicts instead of compiling on heroku. :(

Any help is much appreciated. :)

-Ben

@karellm
Copy link
Contributor Author

karellm commented Jan 26, 2012

This is the workaround I use for now. If it helps anyone, here is the command to use locally:
RAILS_ENV=production bundle exec rake assets:precompile

Then commit the changes to Heroku (that will skip precompilation).

@jwhitley
Copy link
Owner

At this point, compiling on Heroku does not appear to be an option. config.assets.initialize_on_precompile = false is inimical to this gem's integration into the asset pipeline.

Currently, requirejs:setup depends on environment, which is where the story ends in the exception above. If I remove the dependency on environment, the asset build instead blows up when Rails.application.assets turns out to be nil. Game over; the require.js asset build requires that we have access to Rails' Sprockets instance.

@benbabics, you can avoid conflicts with the workaround from @karellm. In short, never commit built assets for any branch except a dedicated Heroku-deployment branch. Keep a deploy branch that's the pipeline for deployments to Heroku. deploy is effectively a one-way branch: code goes in, but is NEVER pulled out. When master is ready to go live, use a rake task that switches to the deploy branch, runs assets:clean to blow away all precompiled asset files, pulls from master, then builds and commits the updated assets. Then deploy is ready for push to Heroku, ala:

git push heroku deploy:master

Likewise, if you use a CI server you could configure it to automatically update deploy from master as described above for any successful build.

I'm leaving this issue open until workaround(s) are better documented in the README and/or the wiki.

@jwhitley
Copy link
Owner

I need to switch to other tasks right now, but I'm going to dig into this again tomorrow for a bit. Rails' source code claims that when precompilation is occuring and config.assets.initialize_on_precompile is set to false that Sprockets should still be allowed to initialize. If that's the case, then I should be able to somehow get a valid Sprockets::Environment instance to use.

Of course, even if I can work around that problem, Heroku itself is another matter. The elephant in the corner is whether a useful version of node is sitting around on PATH when slug compilation happens on Heroku. The r.js build code very much depends on node, so just depending on ExecJS isn't a solution.

@karellm
Copy link
Contributor Author

karellm commented Jan 30, 2012

Thanks for your help on this.

Heroku can compile using your plugin (it allows node app). Everything was working fine up until I started using devise in my routes.

Strangely the asset precompilation loads the routes and it was causing a database error on Heroku because the devise line in my routes was calling the db.

So if there is no call to the db whatsoever during the asset:precompile it will work on Heroku. If for some reason there is a call to the db, then it will fail and you'll need to precompile locally.

@jwhitley
Copy link
Owner

Heroku can compile using your plugin (it allows node app). Everything was working fine up until I started using devise in my routes.

That's great. I have an app that I'm planning to push to Heroku, so it's good to know that the gem works there. I'll have a look tomorrow and see if I can sort out how the rake task can pick up the Sprockets::Environment instance without hitting the "Application has already been initialized" error. It's odd that that error is only triggered with initialize_on_precompile = false.

@JustinLove
Copy link
Contributor

I found a hacky workaround to duplicate-init issue. Put this at bottom of your Rakefile

ENV['RAILS_GROUPS'] = nil # trick asset rake file into shelling out

Sprockets will shell out to a new rake process if either RAILS_GROUPS or RAILS_ENV is empty. It will start from scratch so the processes init isn't duplicate. After the rakefile loads config/application we shouldn't need RAILS_GROUPS any more.

Building with `config.assets.initialize_on_precompile = false` now
works.  This enables building on Heroku, builds with Devise, etc.
jwhitley added a commit that referenced this pull request Mar 29, 2012
Fix precompilation problems on Heroku
@jwhitley jwhitley merged commit bbc42a9 into master Mar 29, 2012
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants