Created
December 10, 2011 20:12
-
-
Save dblock/1456181 to your computer and use it in GitHub Desktop.
Upload assets to S3, preserve two most recent versions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :assets do | |
# uploads assets to s3 under assets/githash, deletes stale assets | |
task :uploadToS3, [ :to ] => :environment do |t, args| | |
from = File.join(Rails.root, 'public/assets') | |
to = args[:to] | |
hash = (`git rev-parse --short HEAD` || "").chomp | |
logger.info("[#{Time.now}] fetching keys from #{to}") | |
existing_objects_hash = {} | |
existing_assets_hash = {} | |
s3i.incrementally_list_bucket(to, prefix: "assets/") do |response| | |
response[:contents].each do |existing_object| | |
existing_objects_hash[existing_object[:key]] = existing_object | |
previous_asset_hash = existing_object[:key].split('/')[1] | |
existing_assets_hash[previous_asset_hash] ||= DateTime.parse(existing_object[:last_modified]) | |
end | |
end | |
logger.info("[#{Time.now}] #{existing_assets_hash.count} existing asset(s)") | |
previous_hash = nil | |
existing_assets_hash.each_pair do |asset_hash, last_modified| | |
logger.info(" #{asset_hash} => #{last_modified}") | |
previous_hash = asset_hash unless (previous_hash and existing_assets_hash[previous_hash] > last_modified) | |
end | |
logger.info("[#{Time.now}] keeping #{previous_hash}") if previous_hash | |
logger.info("[#{Time.now}] copying from #{from} to s3:#{to} @ #{hash}") | |
Dir.glob(from + "/**/*").each do |entry| | |
next if File::directory?(entry) | |
File.open(entry) do |entry_file| | |
content_options = {} | |
content_type = MIME::Types.type_for(entry)[0] | |
content_options['x-amz-acl'] = 'public-read' | |
if entry.ends_with?('.gz') | |
uncompressed_entry = entry[0..-4] | |
entry = "#{uncompressed_entry}.cgz" | |
content_type = MIME::Types.type_for(uncompressed_entry)[0] | |
content_options['content-encoding'] = 'gzip' | |
end | |
content_options['content-type'] = content_type.to_s | |
key = 'assets/' | |
key += (hash + '/') if hash | |
key += entry.slice(from.length + 1, entry.length - from.length - 1) | |
existing_objects_hash.delete(key) | |
logger.info("[#{Time.now}] uploading #{key} (#{content_type})") | |
s3i.put(to, key, entry_file, content_options) | |
end | |
end | |
existing_objects_hash.keys.each do |key| | |
next if previous_hash and key.start_with?("assets/#{previous_hash}/") | |
puts "deleting #{key}" | |
s3i.delete(to, key) | |
end | |
end | |
namespace :push do | |
task :to_staging => [ :environment, :assets ] do | |
Rake::Task["assets:uploadToS3"].execute({ to: 'staging-bucket' }) | |
end | |
task :to_production => [ :environment, :assets ] do | |
Rake::Task["assets:uploadToS3"].execute({ to: 'production-bucket' }) | |
end | |
task :to_heroku => [ :environment, :assets ] do | |
s3_bucket = Heroku::Config['S3_BUCKET'] | |
raise "missing S3_BUCKET in heroku config" if (s3_bucket.nil?) | |
Rake::Task["assets:uploadToS3"].execute({ to: s3_bucket }) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment