Capistrano errors when upgrading an app to Rails 4.0

First, be sure you’re using Capistrano v2.15.4 or higher. There are some significant changes in Capistrano’s awareness of assets and how it manages precompilation.

Rails 4 changes how the asset manifest is handled. The manifest holds a list of all available assets. In Rails 3, this was generated as public/assets/manifest.yml. In Rails 4, it’s now a JSON file along with a fingerprint, eg: public/assets/manifest-9f745054f45f3f47968d59f1665c66be.json.

By itself, Rails handles this without any issue – including the upgrade from Rails 3.2 to 4.0.

However, Capistrano has some issues here which seem related to its attempt at intelligent cleanup of assets no longer being used.

If your upgrade to Rails 4 works the first time through, you’re probably fine. If there’s any kind of error, you may be left in a mixed up state that’s hard to recover from.

Two possible errors you may see from Capistrano.

1More than one asset manifest file was found in '/apps/some_app/shared/assets'.  If you are upgrading a Rails 3 application to Rails 4, follow these instructions: http://github.com/capistrano/capistrano/wiki/Upgrading-to-Rails-4#asset-pipeline
1lib/ruby/1.9.1/psych.rb:203:in `parse': (<unknown>): mapping values are not allowed in this context at line 1 column 6 (Psych::SyntaxError)

I found it easiest to login to the app server(s) and remove manifest*.{yml,json}.

Be warned, removing these files may make it difficult to rollback to a Rails 3.2 version of your app. In theory, you just need to rollback and then recompile the assets. In practice, I experienced some weird issues with bundler loading Rails 4 gems when it was supposed to be loading Rails 3.2 gems, making it impossible to regenerate the asset manifest. You may want to move those files aside instead of just removing them.

I ended up removing the current symlink along with the manifests which then allowed Rails 4 assets to finally build properly without any complaints from Capistrano:

1rm /apps/some_app/current /apps/some_app/shared/assets/manifest*.{yml,json}

You can remove current while the existing (Rails 3) app is still running. However, it’s possible assets will longer be served by your web frontend (apache, nginx, etc.) until the Rails 4 app successfully compiles assets and starts.

If you have any way of testing against a staging server (starting from the Rails 3.2 version of your app), I highly recommend it.

Also related:

tags: rails4, capistrano, rails