サーバ間に差異があると意図どおりに動かない可能性があるのでおすすめできない(追記2参照)
capistranoのでデプロイをするとdeploy:assets:precompile
を走らせてassetsのコンパイルをしてくれるけど、毎回assetsに変更があるわけではない。なので変更がない場合にはprecompileを行わないように手を加える。
config/deploy/assets.rb:
namespace :deploy do namespace :assets do desc <<-DESC Run the asset precompilation rake task. You can specify the full path \ to the rake executable by setting the rake variable. You can also \ specify additional environment variables to pass to rake via the \ asset_env variable. The defaults are: set :rake, "rake" set :rails_env, "production" set :asset_env, "RAILS_GROUPS=assets" If no changes are found in app/assets, vendor/assets, and Gemfile.lock, the precompilation will be skipped. DESC task :precompile, :roles => lambda { assets_role }, :except => { :no_release => true } do begin from = source.next_revision(current_revision) rescue # Fail at first-time deploy because of current/REVISION absence err_no = true end if err_no || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ Gemfile.lock | wc -l").to_i > 0 do_precompile else logger.info "Skipping asset pre-compilation because there were no asset changes" end end desc <<-DESC [internal] This task is a copy of original deploy:assets:precompile. DESC task :do_precompile, :roles => lambda { assets_role }, :except => { :no_release => true } do # オリジナルのdeploy:assets:precompile の内容を持ってくる # https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy/assets.rb#L61 end end end
config/deploy.rb:
load "config/deploy/assets.rb"
これでapp/assets
、vendor/assets
、Gemfile.lock
に変更がある場合にだけprecompileを行なってくれる。Gemfile.lockも見ているのは、gemによってはassetsを提供するものがあるから。
ちなみにいくつか同じ意図のコードを見たけど、どれもprecompileを実行する=rake assets:precompile
を実行するとなっているところばかりだった。けど、capistranoのdeploy:assets:precompile
はmanifestファイルのコピーなどもやっているみたいなので、ここでは元々のタスクをdo_precompile
として利用している。*1
参考
追記
追記2
capture
は一つのサーバ*2にしか確認しに行かないので、あとからサーバを追加した場合にそれだけprecompileされないということが発生する。
記述ルールを作ればいいのかもしれないけど、忘れられる可能性があるのでおすすめできない。