Skip to content

Instantly share code, notes, and snippets.

@listenrightmeow
Last active February 14, 2017 06:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save listenrightmeow/3278894 to your computer and use it in GitHub Desktop.
Save listenrightmeow/3278894 to your computer and use it in GitHub Desktop.
Rails 3 asset pipeline deploy task with s3 and cloudfront support
namespace :assets do
desc 'Precompile assets and upload to S3'
task :sync => :environment do
assets = build_asset_dir
raise 'asset directory is empty: aborting' unless assets.size > 1
invalid_files = build_assets assets
delete_old_assets assets
invalidate_files invalid_files unless invalid_files.empty?
end
private
def aws
@aws ||= Rails.application.config.aws.marshal_dump.deep_symbolize_keys[Rails.env.to_sym]
end
def bucket
@bucket ||= fog.directories.get("#{aws[:bucket]}")
end
def fog
@fog ||= Fog::Storage.new :provider => 'AWS', :aws_access_key_id => "#{aws[:access_key]}", :aws_secret_access_key => "#{aws[:secret]}", region: 'us-west-1'
end
def build_assets assets
invalid_files = []
assets.each do |file, etag|
case etag
when :directory
puts "Directory - #{file}"
bucket.files.create(key: file, public: true)
when bucket.files.get(file).try(:etag)
puts "Skipping - #{file} (identical)"
else
invalid_files << "/#{file}"
puts "Uploading - #{file}"
bucket.files.create(key: file, public: true, body: File.open("#{Rails.root}/public/#{file}"), cache_control: "max-age=#{6.month.to_i}, public", expires: "#{6.month.from_now.httpdate}")
end
end
invalid_files
end
def build_asset_dir
Dir.chdir("#{Rails.root}/public") do
FileList['assets', 'assets/**/*'].inject({}) do |hash, path|
if File.directory? path
hash.update("#{path}/" => :directory)
else
hash.update(path => OpenSSL::Digest::MD5.hexdigest(File.read(path)))
end
end
end
end
def delete_old_assets assets
bucket.files.each do |file|
unless assets.has_key? file.key
puts "Removing #{file.key} (deleted asset)"
file.destroy
end
end
end
def invalidate_files invalid_files
cdn = Fog::CDN.new({
:provider => 'AWS',
:aws_access_key_id => "#{aws[:access_key]}",
:aws_secret_access_key => "#{aws[:secret]}"
})
request = cdn.post_invalidation("#{aws[:cloudfront_distribution]}", invalid_files)
puts "Invalidation : #{request.body}"
end
end
namespace :heroku do
desc "Deploy to Heroku"
task :deploy do
Rake::Task['assets:precompile'].clear
Rake::Task["assets:upload"].invoke
Rake::Task["heroku:push"].invoke
end
desc "Push master branch to heroku remote"
task :push do
puts "[Deploying] Heroku"
`git push production master`
end
end
group :assets do
gem 'yui-compressor'
gem 'uglifier', '>= 1.0.3'
end
gem 'heroku'
gem 'fog'
rake heroku:deploy
/Users/mdyer/.rvm/rubies/ruby-1.9.3-head/bin/ruby /Users/mdyer/.rvm/gems/ruby-1.9.3-head@global/bin/rake assets:clean:all RAILS_ENV=production RAILS_GROUPS=assets
rm -rf /Users/mdyer/Sites/v3/public/assets
/Users/mdyer/.rvm/rubies/ruby-1.9.3-head/bin/ruby /Users/mdyer/.rvm/gems/ruby-1.9.3-head@global/bin/rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets
Directory - downloads/
Skipping - downloads/resume.pdf (identical)
Directory - ui/
Directory - ui/fonts/
Directory - ui/fonts/depot/
Skipping - ui/fonts/depot/depotnewweb-bd.eot (identical)
Skipping - ui/fonts/depot/depotnewweb-bd.svg (identical)
Skipping - ui/fonts/depot/depotnewweb-lt.eot (identical)
Skipping - ui/fonts/depot/depotnewweb-lt.svg (identical)
Skipping - ui/fonts/depot/depotnewweb-md.eot (identical)
Skipping - ui/fonts/depot/depotnewweb-md.svg (identical)
Directory - ui/images/
Directory - ui/images/common/
Skipping - ui/images/common/background.png (identical)
Skipping - ui/images/common/favicon.png (identical)
Skipping - ui/images/common/logo.png (identical)
Skipping - ui/images/common/tile.png (identical)
Directory - ui/images/logos/
Skipping - ui/images/logos/boars.png (identical)
Skipping - ui/images/logos/cbs.png (identical)
Skipping - ui/images/logos/colonna.png (identical)
Skipping - ui/images/logos/cracked.png (identical)
Skipping - ui/images/logos/cuenotes.png (identical)
Skipping - ui/images/logos/dealer.png (identical)
Skipping - ui/images/logos/donfrancisco.png (identical)
Skipping - ui/images/logos/ehow.png (identical)
Skipping - ui/images/logos/gameon.png (identical)
Skipping - ui/images/logos/laane.png (identical)
Skipping - ui/images/logos/lexus.png (identical)
Skipping - ui/images/logos/momentfeed.png (identical)
Skipping - ui/images/logos/typef.png (identical)
Skipping - ui/images/logos/universal.png (identical)
Skipping - ui/images/logos/wendys.png (identical)
Directory - ui/images/tiles/
Skipping - ui/images/tiles/universal.png (identical)
No invalid files. Cloudfront invalidation not required.
[Deploying] Heroku
Counting objects: 19, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (10/10), 985 bytes, done.
Total 10 (delta 5), reused 0 (delta 0)
-----> Heroku receiving push
-----> Ruby/Rails app detected
-----> Using Ruby version: ruby-1.9.3
-----> Installing dependencies using Bundler version 1.2.0.rc
Running: bundle install --without development:test --path vendor/bundle --binstubs bin/ --deployment
Using rake (0.9.2.2)
Using Platform (0.4.0)
Using open4 (1.3.0)
Using POpen4 (0.1.4)
Using i18n (0.6.0)
Using multi_json (1.3.6)
Using activesupport (3.2.6)
Using builder (3.0.0)
Using activemodel (3.2.6)
Using erubis (2.7.0)
Using journey (1.0.4)
Using rack (1.4.1)
Using rack-cache (1.2)
Using rack-test (0.6.1)
Using hike (1.2.1)
Using tilt (1.3.3)
Using sprockets (2.1.3)
Using actionpack (3.2.6)
Using mime-types (1.19)
Using polyglot (0.3.3)
Using treetop (1.4.10)
Using mail (2.4.4)
Using actionmailer (3.2.6)
Using active_attr (0.6.0)
Using arel (3.0.2)
Using tzinfo (0.3.33)
Using activerecord (3.2.6)
Using activeresource (3.2.6)
Using addressable (2.2.8)
Using daemons (1.1.8)
Using dalli (2.1.0)
Using eventmachine (0.12.10)
Using excon (0.14.3)
Using execjs (1.4.0)
Using formatador (0.2.3)
Using net-ssh (2.5.2)
Using net-scp (1.0.4)
Using nokogiri (1.5.5)
Using ruby-hmac (0.4.0)
Using fog (1.5.0)
Using heroku-api (0.2.7)
Using launchy (2.1.0)
Using netrc (0.7.5)
Using rest-client (1.6.7)
Using rubyzip (0.9.9)
Using heroku (2.28.10)
Using json (1.7.4)
Using rack-ssl (1.3.2)
Using bundler (1.2.0.rc)
Using rdoc (3.12)
Using thor (0.15.4)
Using railties (3.2.6)
Using rails (3.2.6)
Using sendgrid-rails (2.0.2)
Using thin (1.4.1)
Using uglifier (1.2.6)
Using yui-compressor (0.9.6)
Your bundle is complete! It was installed into ./vendor/bundle
Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
Asset precompilation completed (37.55s)
-----> Rails plugin injection
Injecting rails_log_stdout
Injecting rails3_serve_static_assets
-----> Discovering process types
Procfile declares types -> web
Default types for Ruby/Rails -> console, rake, worker
-----> Compiled slug size is 26.0MB
-----> Launching... done, v38
http://n9nemedia.herokuapp.com deployed to Heroku
To git@heroku.com:n9nemedia.git
e8df540..7812c9b master -> master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment