Skip to content

Instantly share code, notes, and snippets.

@daniel-nelson
Created January 17, 2013 20:05
Show Gist options
  • Save daniel-nelson/4559235 to your computer and use it in GitHub Desktop.
Save daniel-nelson/4559235 to your computer and use it in GitHub Desktop.
namespace :assets do
desc "move precompiled assets to S3"
task :move_to_s3 => :environment do
puts "finished precompiling. beginning transfer to s3..."
s3 = AWS::S3.new
bucket = s3.buckets[APP_CONFIG[:rails_assets_bucket]]
base_dir = Rails.root.join('public', 'assets').to_s + '/'
regexp_extensions = []
['js', 'css', 'html', 'png', 'jpg', 'jpeg', 'gif'].each do |ext|
regexp_extensions << "\\.#{ext}"
regexp_extensions << "\\.#{ext}\\.gz"
end
regexp = /-[a-z0-9]{32}(#{regexp_extensions.join('|')})$/
raise "environment specific key in asset pipeline" unless `grep -r --include=\*.{js,css,html} "ENVIRONMENT_SPECIFIC_KEY_IN_ASSET_PIPELINE" #{Rails.root.join('public', 'assets')}`.empty?
raise "private key exposed in asset pipeline" unless `grep -r --include=\*.{js,css,html} "PRIVATE_KEY_EXPOSED_IN_ASSET_PIPELINE" #{Rails.root.join('public', 'assets')}`.empty?
Dir[Rails.root.join('public', 'assets', '**/*.*')].each do |asset_file_path|
move_file_to_s3(regexp, bucket, base_dir, asset_file_path)
end
end
def move_file_to_s3(regexp, bucket, base_dir, asset_file_path, force_upload=false)
key = asset_file_path.sub(base_dir, '')
# the manifest is the map between resource and digest resource that Rails uses
# in the asset url helpers. don't upload it, and don't delete it
if key == 'manifest.yml'
File.rename(asset_file_path, File.dirname(asset_file_path) + "/#{Rails.env}_manifest.yml")
elsif key != "production_manifest.yml" && key != "staging_manifest.yml"
if key =~ regexp
if key =~ /\.js(\.gz)?/
content_type = 'application/javascript'
elsif key =~ /\.css(\.gz)?/
content_type = 'text/css'
elsif key =~ /\.html(\.gz)?/
content_type = 'text/html'
elsif key =~ /\.png(\.gz)?/
content_type = 'image/png'
elsif key =~ /\.je?pg(\.gz)?/
content_type = 'image/jpeg'
elsif key =~ /\.gif(\.gz)?/
content_type = 'image/gif'
else
content_type = nil
end
s3_object = bucket.objects["assets/#{key}"]
options = {
:file => asset_file_path,
:acl => :public_read,
:content_type => content_type,
:cache_control => 'public, max-age=31557600'
}
options[:content_encoding] = 'gzip' if key =~ /\.gz$/
if force_upload || !s3_object.exists?
puts "uploading #{key}"
s3_object.write(options)
else
puts "#{key} already exists"
end
end
# delete all files so they don't end up in the repository (don't use .gitignore because
# we need manifest.yml to be addded)
File.delete(asset_file_path)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment