Capistrano + Rails: Automatically skipping asset compilation when assets have not changed

In medium-sized to large Rails applications, asset compilation can take several minutes. In order to speed up deployment, asset precompilation can be skipped. This card automates the process.

Capistrano 3

namespace :deploy do
  
  desc 'Automatically skip asset compile if possible'
  task :auto_skip_assets do
    asset_locations = %r(^(Gemfile\.lock|app/assets|lib/assets|vendor/asset))

    revisions = []
    on roles :app do
      within current_path do
        revisions << capture(:cat, 'REVISION').strip
      end
    end

    # Never skip asset compile when servers are running on different code
    next if revisions.uniq.length > 1

    changed_files = `git diff --name-only #{revisions.first}`.split
    if changed_files.grep(asset_locations).none?
      puts Airbrussh::Colors.green('** Assets have not changed since last deploy.')
      invoke 'deploy:skip_assets'
    end
  end

  desc 'Skip asset compile'
  task :skip_assets do
    puts Airbrussh::Colors.yellow('** Skipping asset compile.')
    Rake::Task['deploy:assets:precompile'].clear_actions
  end

end

To use this for all stages, add this line to your Capfile:

before 'deploy:starting', 'deploy:auto_skip_assets'

I have been using this in production successfully. To activate it for staging only, put that line into config/deploy/staging.rb instead.

Note that skip_assets is a separate task, so you'll still be able to skip assets manually.

Dominik Schöler over 3 years ago
This website uses short-lived cookies to improve usability.
Accept or learn more