I try to create a simple heroku app which clones a git repository, invokes bundle install, a rake dist task and then uploads the created files to a GitHub repository. The build task of the cloned repository uses Rake Pipeline, which uses the execjs gem for building the binary.
I’ve created a sample app located at https://github.com/pangratz/github-uploader-test, which illustrates the problem. The directory structure of the application is the following:
/upload.rb
/project
Rakefile
Assetfile
Gemfile
Gemfile.lock
The app itself is a simple sinatra app with a get '/' route, which looks like this:
upload.rb
get '/' do
Dir.chdir "project" do
Bundler.with_clean_env do
system "bundle install"
system "bundle exec rake dist"
end
end
end
For demonstration purpose, the project folder simulates the cloned git repository. It contains a Rakefile, Assetfile, Gemfile and Gemfile.lock.
project/Rakefile
desc "Build"
task :dist do
Rake::Pipeline::Project.new("Assetfile").invoke
end
project/Assetfile
require "rake-pipeline-web-filters"
require "json"
require "uglifier"
require "execjs"
puts ExecJS.eval "'red yellow blue'.split(' ')"
project/Gemfile
source "http://rubygems.org"
gem "rake-pipeline", :git => "https://github.com/livingsocial/rake-pipeline.git"
gem "rake-pipeline-web-filters", :git => "https://github.com/wycats/rake-pipeline-web-filters.git"
gem "colored"
gem "uglifier", :git => "https://github.com/lautis/uglifier.git"
group :development do
gem "rack"
gem "rest-client"
gem "github_api"
gem "ember-docs", :git => "https://github.com/emberjs/docs-generator.git"
gem "kicker"
end
The invocation of bundle install seems to work. The problem is that rake dist is failing with the error Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes..
The heroku app itself is created with the option --stack cedar.
I’ve also created a route ‘/test’ which uses Execjs and this does not fail. So it seems
that there is a problem with the Bundler.with_clean_env and not finding the installed JavaScript Runtime …
upload.rb
get '/test' do
puts ExecJS.eval "'red yellow blue'.split(' ')"
end
I’ve opened an issue on Heroku and I could solve the issue. The problem was that the
Dir.chdir("project")in combination with theBundler.with_clean_envresulted in an invalidPATHwhich is needed to locate the JavaScript Runtime. Long story short, here is the working solution:A note on the solution: the
--without WATWATis needed because Heroku installs your app withbundle install --without development. Since the--withoutis remembered for successive calls, and the gems ofdevelopmentgroup are needed in theAssetfile, this option has to be overwritten. Using--without ''somehow doesn’t work so I’m using the nonexistent groupWATWATto include all groups in theGemfile.