Keeping locally precompiled assets out of the way on Heroku

With the Rails 3.1 Asset Pipeline, there’s the rake assets:precompile command which precompiles assets into public/assets along with a manifest.yml file which rails uses to put the paths to the assets in its templates. Precompiling generates a few files, which can clutter commit logs if they’re committed. For this reason I might add public/assets to my .gitignore and build them on the server, rather than committing them to git and uploading them. Or, if the server had trouble compiling them, I might precompile them locally, and scp them up rather than committing them to git, because they can make a lot of noise in my git logs.

On Heroku, though, git is the only way to deploy. So if I’m having trouble having heroku precompile them, I need to commit them and push them via git. This could clutter up my commit log.

There is a way around this, though: use a branch! If I create a branch just for heroku, and just commit them to the branch, I can keep my commit logs free of changes to public/assets.

Here is a sketch of this process:

  1. Add public/assets to my .gitignore and commit it
  2. Create a heroku branch with git checkout -b heroku
  3. remove public/assets from my .gitignore and commit it. This just affects my heroku branch.
  4. Run RAILS_ENV=production rake assets:precompile there.
  5. Run git add . and git commit -m 'precompile assets' to commit the files to my heroku branch
  6. Run git push heroku heroku:master to push my heroku branch to heroku as master (heroku only uses the master branch)
  7. Run git checkout master and continue development on my master branch.

A deploy rake script could be used to automate this.

The heroku branch wouldn’t need to be pushed to github, because it doesn’t contain any information that can’t be regenerated. The only reason the history would need to be preserved is so it can be cleanly pushed to the heroku app. Fortunately, if the local repo was lost, it’s possible to pull from the heroku repository. Heroku shouldn’t be used as a place to store git repositories because the lifecycle for a heroku app is often different than that of a repository. For this purpose, though, the usefulness of the old assets commits is tied to the life of the Heroku app so it works out well.

6 Replies to “Keeping locally precompiled assets out of the way on Heroku”

  1. How do you go about pushing after editing the master branch? Do you checkout the heroku branch and merge? Wouldn’t that overwrite the .gitignore?

    Thanks

  2. What if you just removed public/assets from the master branch. Then do like you mentioned: create a heroku branch, pre-compile assets on that branch, commit those files to that branch, then push that branch to heroku master. Then you wouldn’t need to mess with the .gitignore and it should work seamlessly to merge changes from master into the heroku branch. Or am I missing something?, because I’m trying to do the same thing.

  3. Just stumbled across this, a really useful idea, thanks! I’m wondering if it’s possible to rebase the heroku deployment branch each time (instead of recreating the branch) so that you carry forward old versions of the precompiled assets, as is recommended in the asset pipeline guide…

  4. I solve this problem by using Subversion for version control and Git for deployment. However, I still find managing compiled assets with Git a little problematic, particularly after running rake assets:clean. This forces some housekeeping in the Git repository but I have not yet found a command for removing deleted files, on mass.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.