Skip to content

Instantly share code, notes, and snippets.

@amw
Created January 1, 2016 22:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amw/895ff841e71b800f255f to your computer and use it in GitHub Desktop.
Save amw/895ff841e71b800f255f to your computer and use it in GitHub Desktop.
Capistrano task to verify that asset digests are the same on all hosts
# lib/capistrano/tasks/assets.rake
require "concurrent/hash"
# This task tests that hash digests of generated JS and CSS files are the same on every
# asset server. This should always be the case if Sprockets and Uglifier do their job
# well, but I've once had a problem with that. Once bitten, twice shy.
#
# We do not send compiled CSS&JS files to our asset servers, instead we're asking the
# servers to compile and minify them from source. If the process varies between servers
# and the files come out with different hash digests then one web server might send users
# to files that do not exist on the other causing 404 HTTP errors.
#
# See this issue for more details:
#
# https://github.com/rails/sprockets/issues/74
namespace :deploy do
desc "Verifies that asset digests match on all hosts"
task :verify_manifests do
results = Concurrent::Hash.new
on release_roles(fetch(:assets_roles)) do |host|
path = detect_manifest_path
digest = capture :ruby,
"-r", "json",
"-r", "digest",
"-e", "'manifest = JSON.load(File.read(ARGV.first))'",
"-e", "'items = manifest[\"assets\"].values.join(\"\\n\")'",
"-e", "'puts Digest::SHA256.hexdigest items'",
path
results[host.hostname] = digest
end
next if results.size < 2
next if results.values.uniq.size < 2
msg = "Generated assets differ between hosts"
warn msg
raise msg
end
end
after "deploy:normalize_assets", "deploy:verify_manifests"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment