Show Rakefile errors in Ruby deploys
Change effective on 05 December 2013
Add debug output to deploys using the Ruby build pack. There is no change in deploy functionality. To better understand this change it helps to look at prior behavior.
Previously the Ruby buildpack did not have a way to detect if there were errors in a Rakefile. It would detects if a task is available by executing the task with
$ rake assets:precompile --dry-run
This task can return a non zero status if the
assets:precompile task does not exist or if there is an error in the
Rakefile. Two common cause of errors in the
Rakefile are referencing a dependency not available in production such as
rspec or expecting an environment variable to be present. As we have no way of knowing which reason the command failed, we previously assumed it was because the task was not defined. The deploy would continue and we would not attempt to run
The previous behavior caused confusion when a developer accidentally introduced an error into their
Rakefile, causing their assets to not longer compile. In addition, they would see no debug output in the push and their app (minus the assets) would successfully deploy.
This fix changes the detection behavior by separating out the verification of a valid
Rakefile and the presence of tasks. Now if we detect that there is an error in the Rakefile we will emit the error and the backtrace for debugging purposes. When this happens we will not cancel the build, instead it will continue and the
assets:precompile task will be skipped unless you manually cancel the build (CTRL+C). This change preserves the prior behavior but adds debugging information and clarity around why your app is no longer compiling assets.
The decision to not error out when we find a Rakefile with an exception may be curious but this is done for compatibility reasons. The same build pack supports all Ruby deploys, not just Rails deploys. There are currently developers who do not intend for Heroku to run Rake tasks on their app and to them continuing with a deploy is the desired behavior. Changing this behavior would break their deploys.
If someone’s Rakefile is valid, and we detect
assets:precompile we will run it. If the
assets:precompile exists but the command fails we cancel the build. This is to prevent apps that require assets (almost all that have
assets:precompile declared) from going into production with non-functioning assets.
If you have an error in your Rakefile, you will see an output similar to this:
Could not detect rake tasks ensure you can run `$ bundle exec rake -P` against your app with no environment variables present and using the production group of your Gemfile. This may be intentional, if you expected rake tasks to be run cancel the build (CTRL+C) and fix the error then commit the fix: #...
To be clear, although you will see a backtrace your application will continue to deploy. You can stop it manually by running