This week, I've been working on a side project with Andrés Mejía (@andmej) and for some really really sad reason Heroku is not working as expected (a simple git push should do the trick, but we're having a really weird issue).

At first, I thought it had something to do with the assets. Even-though Heroku has asset compiling tasks on their Cedar stack, it didn't really worked for us at first. So I just decided to create a small rake task to compile the assets and push them to Github.

The good thing about this rake task is that it will only push the assets. This means, that you'll need a clean git tree to run this task or it will die. This ensures that the automatic push won't commit any non-related change to the compilation of the assets.

Now, you only have to run rake assets:compile and sleep well at night. Here's the code. Hope it helps.

# https://gist.github.com/nhocki/1241135
namespace :assets do
  desc "Compile all the assets named in config.assets.precompile and push them"
  task :compile do
    AssetsCompiler.new.compile
  end

  class AssetsCompiler
    def compile
      ensure_clean_git
      removed_previous_assets
      compile_assets
      commit_compiled_assets
      push
    end

    def ensure_clean_git
      raise "Can't deploy without a clean git status." if git_dirty?
    end

    def removed_previous_assets
      run "bundle exec rake RAILS_ENV=production assets:clean"
    end

    def compile_assets
      run "bundle exec rake RAILS_ENV=production assets:precompile"
    end

    def commit_compiled_assets
      run "git add -u && git add . && git commit -am 'Compiled assets'"
    end

    def push
      run "git push"
    end

    private

    def run(command)
      puts "+ Running: #{command}"
      puts "-- #{system command}"
    end

    def git_dirty?
      `[[ $(git diff --shortstat 2> /dev/null | tail -n1) != "" ]]`
      dirty = $?.success?
    end
  end
end