Идея состоит в том, что если вы не меняете свои активы, вам не нужно каждый раз перекомпилировать их:
Это решение , которое Бен Кертис предлагает для развертывания сgit:
namespace :deploy do
namespace :assets do
task :precompile, :roles => :web, :except => { :no_release => true } do
from = source.next_revision(current_revision)
if releases.length <= 1 || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
else
logger.info "Skipping asset pre-compilation because there were no asset changes"
end
end
end
end
Вот еще один подход, основанный на возрасте ресурса (https://gist.github.com/2784462):
set :max_asset_age, 2 ## Set asset age in minutes to test modified date against.
after "deploy:finalize_update", "deploy:assets:determine_modified_assets", "deploy:assets:conditionally_precompile"
namespace :deploy do
namespace :assets do
desc "Figure out modified assets."
task :determine_modified_assets, :roles => assets_role, :except => { :no_release => true } do
set :updated_assets, capture("find #{latest_release}/app/assets -type d -name .git -prune -o -mmin -#{max_asset_age} -type f -print", :except => { :no_release => true }).split
end
desc "Remove callback for asset precompiling unless assets were updated in most recent git commit."
task :conditionally_precompile, :roles => assets_role, :except => { :no_release => true } do
if(updated_assets.empty?)
callback = callbacks[:after].find{|c| c.source == "deploy:assets:precompile" }
callbacks[:after].delete(callback)
logger.info("Skipping asset precompiling, no updated assets.")
else
logger.info("#{updated_assets.length} updated assets. Will precompile.")
end
end
end
end
Если вы предпочитаете прекомпилировать свои ресурсы локально, вы можете использовать эту задачу:
namespace :deploy do
namespace :assets do
desc 'Run the precompile task locally and rsync with shared'
task :precompile, :roles => :web, :except => { :no_release => true } do
from = source.next_revision(current_revision)
if releases.length <= 1 || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
%x{bundle exec rake assets:precompile}
%x{rsync --recursive --times --rsh=ssh --compress --human-readable --progress public/assets #{user}@#{host}:#{shared_path}}
%x{bundle exec rake assets:clean}
else
logger.info 'Skipping asset pre-compilation because there were no asset changes'
end
end
end
end
Другим интересным подходом может быть использование git hook . Например, вы можете добавить этот код в .git/hooks/pre-commit
, который проверяет, есть ли различия в файлах ресурсов ив конечном итоге прекомпилирует их и добавляет в текущий коммит.
#!/bin/bash
# source rvm and .rvmrc if present
[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"
[ -s "$PWD/.rvmrc" ] && . "$PWD/.rvmrc"
# precompile assets if any have been updated
if git diff-index --name-only HEAD | egrep '^app/assets' >/dev/null ; then
echo 'Precompiling assets...'
rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets
git add public/assets/*
fi
Если вы решите использовать этот подход, вам, вероятно, придется изменить config/environments/development.rb
, добавив:
config.assets.prefix = '/assets_dev'
, чтобыв процессе разработки вы не будете обслуживать предварительно скомпилированные активы.