Skip to content

Instantly share code, notes, and snippets.

@shioyama
Last active June 24, 2020 13:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shioyama/251d3a747a60c829b764bdadaff033d0 to your computer and use it in GitHub Desktop.
Save shioyama/251d3a747a60c829b764bdadaff033d0 to your computer and use it in GitHub Desktop.
Sync files from Rails webpacker manifest.json to S3 asset bucket.
# Sync files from webpacker manifest.json to S3 asset bucket.
# Based on asset_sync but much simplified for this case.
#
# Requirements
#
# Add fog to Gemfile.
#
# Environment variables:
# - AWS_S3_ASSETS_BUCKET_NAME
# - AWS_S3_REGION
#
# Rails credentials yaml must have s3 access key id and secret:
#
# aws:
# s3_access_key_id: ...
# s3_secret_access_key: ...
#
namespace :webpacker do
desc 'Synchronize files in webpacker manifest.json to S3'
task :sync => :environment do
manifest_json = JSON.load(IO.read(Webpacker.config.public_manifest_path))
# discard leading slash (/)
assets = manifest_json.map { |_, fn| fn[1..-1] }
connection = Fog::Storage.new(
provider: "aws",
aws_access_key_id: Rails.application.credentials.dig(:aws, :s3_access_key_id),
aws_secret_access_key: Rails.application.credentials.dig(:aws, :s3_secret_access_key),
region: ENV['AWS_S3_REGION'] || raise("Missing S3 Region")
)
prefix = public_output_path.relative_path_from(public_path).to_s
bucket = connection.directories.get(ENV['AWS_S3_ASSETS_BUCKET_NAME'] || raise("Missing bucket name"), :prefix => prefix)
remote_files = bucket.files.inject([]) { |files, f| files << f.key }
local_files_to_upload = assets - remote_files
Rails.logger.info("Syncing #{local_files_to_upload.count} files...")
# Upload new files
local_files_to_upload.each do |f|
next unless public_path.join(f).file?
upload_file f, bucket
end
end
private
def wp_config
Webpacker.config
end
def public_path
wp_config.public_path
end
def public_output_path
wp_config.public_output_path
end
def upload_file(f, bucket)
file_handle = File.open(public_path.join(f))
file = {
key: f,
body: file_handle,
content_type: ::MIME::Types.type_for(File.extname(f)[1..-1]).first,
public: true,
storage_class: 'REDUCED_REDUNDANCY'
}
bucket.files.create(file)
file_handle.close
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment