s3_asset_deploy 0.1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72c4c1220b3051d9189389b3b956d509506380ae4bef112212480e1da9ac75e4
4
- data.tar.gz: b9fbd6e07c1cced6e5a20d1cb72338093eec260a540a434ee3cc60012e680549
3
+ metadata.gz: 3590e77179d747a7737ad4032877bc1e2f2a219d58005711f70ff737cf107fb5
4
+ data.tar.gz: cfc9de4221ce547ddc818d1569b70b3c5ffb6184d79108eec3145534a2361304
5
5
  SHA512:
6
- metadata.gz: cb3a963f7a47375414e9b51b1b3f525a890924995b380d193151e9a77193a7ddec8f1f50864fc60b37c5c768586fefa76b1335d3e849918572ec4b7be3af866a
7
- data.tar.gz: d240fe42ae5578cf136f1dac4b637165603836f8cdceb7bf8d820cd6808048d78b50b4dbbe235f3e1678aedbe8f36a6b76f1310a5d64f0605622650cca2d01b1
6
+ metadata.gz: 4a91acae364734b965b2c1176eee978b23fe4244c0ad4c89993f2a52f528a8d2efe6d7652daf4ca50f2e473eab5d9bb153c5af04f1000e3731e3294d0b5737c0
7
+ data.tar.gz: d1a6dfd9164072da6aa1acbd5a36e280508e291d525a907b9500e5af76e0b07816da5dc6a60ff6d4dba5d95ddc3e891da44627a526189ebb56d723a251063c9c
data/CHANGELOG.md CHANGED
@@ -1 +1,11 @@
1
1
  # Changelog
2
+
3
+ ## [v1.0.1](https://github.com/Loomly/s3_asset_deploy/compare/v1.0.0...v1.0.1) - 2022-02-23
4
+ - Batch delete API calls with max 1000 keys - [PR #32](https://github.com/Loomly/s3_asset_deploy/pull/32)
5
+
6
+ ## [v1.0.0](https://github.com/Loomly/s3_asset_deploy/compare/v0.1.1...v1.0.0) - 2021-05-13
7
+ ### Breaking Changes
8
+ - Remove default `acl` setting when uploading assets to bucket - [PR #25](https://github.com/Loomly/s3_asset_deploy/pull/25)
9
+
10
+ ## [v0.1.1](https://github.com/Loomly/s3_asset_deploy/compare/v0.1.0...v0.1.1) - 2021-03-22
11
+ - Fix bug in AssetHelper.remove_fingerprint referencing asset_path - [4f370ad](https://github.com/Loomly/s3_asset_deploy/commit/4f370ad9c0c1c274acb9b1d8585b878f47020277)
data/Gemfile.lock CHANGED
@@ -1,43 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- s3_asset_deploy (0.1.0)
4
+ s3_asset_deploy (1.0.1)
5
5
  aws-sdk-s3 (~> 1.0)
6
6
  mime-types (~> 3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- aws-eventstream (1.1.0)
12
- aws-partitions (1.422.0)
13
- aws-sdk-core (3.111.2)
11
+ aws-eventstream (1.2.0)
12
+ aws-partitions (1.558.0)
13
+ aws-sdk-core (3.126.2)
14
14
  aws-eventstream (~> 1, >= 1.0.2)
15
- aws-partitions (~> 1, >= 1.239.0)
15
+ aws-partitions (~> 1, >= 1.525.0)
16
16
  aws-sigv4 (~> 1.1)
17
17
  jmespath (~> 1.0)
18
- aws-sdk-kms (1.41.0)
19
- aws-sdk-core (~> 3, >= 3.109.0)
18
+ aws-sdk-kms (1.54.0)
19
+ aws-sdk-core (~> 3, >= 3.126.0)
20
20
  aws-sigv4 (~> 1.1)
21
- aws-sdk-s3 (1.87.0)
22
- aws-sdk-core (~> 3, >= 3.109.0)
21
+ aws-sdk-s3 (1.112.0)
22
+ aws-sdk-core (~> 3, >= 3.126.0)
23
23
  aws-sdk-kms (~> 1)
24
- aws-sigv4 (~> 1.1)
25
- aws-sigv4 (1.2.2)
24
+ aws-sigv4 (~> 1.4)
25
+ aws-sigv4 (1.4.0)
26
26
  aws-eventstream (~> 1, >= 1.0.2)
27
27
  byebug (11.1.3)
28
28
  coderay (1.1.3)
29
29
  diff-lcs (1.4.4)
30
- jmespath (1.4.0)
30
+ jmespath (1.6.0)
31
31
  method_source (1.0.0)
32
- mime-types (3.3.1)
32
+ mime-types (3.4.1)
33
33
  mime-types-data (~> 3.2015)
34
- mime-types-data (3.2020.1104)
34
+ mime-types-data (3.2022.0105)
35
+ mini_portile2 (2.8.0)
36
+ nokogiri (1.13.3)
37
+ mini_portile2 (~> 2.8.0)
38
+ racc (~> 1.4)
35
39
  pry (0.13.1)
36
40
  coderay (~> 1.1)
37
41
  method_source (~> 1.0)
38
42
  pry-byebug (3.9.0)
39
43
  byebug (~> 11.0)
40
44
  pry (~> 0.13.0)
45
+ racc (1.6.0)
41
46
  rake (13.0.3)
42
47
  rspec (3.10.0)
43
48
  rspec-core (~> 3.10.0)
@@ -60,6 +65,7 @@ PLATFORMS
60
65
  ruby
61
66
 
62
67
  DEPENDENCIES
68
+ nokogiri (~> 1.13)
63
69
  pry (~> 0.13)
64
70
  pry-byebug (~> 3.9)
65
71
  rake (~> 13.0)
@@ -69,4 +75,4 @@ DEPENDENCIES
69
75
  timecop (~> 0.9)
70
76
 
71
77
  BUNDLED WITH
72
- 2.2.7
78
+ 2.2.32
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # S3AssetDeploy
2
2
 
3
3
  [![CircleCI](https://circleci.com/gh/Loomly/s3_asset_deploy.svg?style=shield)](https://circleci.com/gh/Loomly/s3_asset_deploy)
4
+ [![Gem Version](https://badge.fury.io/rb/s3_asset_deploy.svg)](https://badge.fury.io/rb/s3_asset_deploy)
4
5
 
5
6
  During rolling deploys to our web instances, this is what we use at
6
7
  [Loomly](https://www.loomly.com) to safely deploy our web assets to S3 to be served via Cloudfront.
@@ -41,7 +42,7 @@ Before using `S3AssetDeploy` you want to make sure to compile your assets. Asset
41
42
 
42
43
 
43
44
  ```ruby
44
- manager = S3AssetDeploy::Manager("my-s3-bucket")
45
+ manager = S3AssetDeploy::Manager.new("my-s3-bucket")
45
46
  manager.deploy do
46
47
  # Perform deploy to web instances in this block
47
48
  end
@@ -60,7 +61,7 @@ You'll need to initialize `S3AssetDeploy::Manager` with an S3 bucket name and **
60
61
  - **s3_client_options** (Hash) -> A hash that is passed directly to [`Aws::S3::Client#initialize`](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#initialize-instance_method) to configure the S3 client. By default the region is set to `us-east-1`.
61
62
  - **logger** (Logger) -> A custom logger. By default things are logged to `STDOUT`.
62
63
  - **local_asset_collector** (S3AssetDeploy::LocalAssetCollector) -> A custom instance of `S3AssetDeploy::LocalAssetCollector`. This allows you to customize how locally compiled assets are collected.
63
- - **upload_options** (Hash) -> A hash consisting of options that are passed directly to [`Aws::S3::Client#put_object`](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#put_object-instance_method) when each asset is uploaded. By default `acl` is set to `public-read` and `cache_control` is set to `public, max-age=31536000`.
64
+ - **upload_options** (Hash) -> A hash consisting of options that are passed directly to [`Aws::S3::Client#put_object`](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#put_object-instance_method) when each asset is uploaded. By default `cache_control` is set to `public, max-age=31536000`.
64
65
  - **remove_fingerprint** (Lambda) -> Lambda for overriding how fingerprints are removed from asset paths. Fingerprints need to be removed during the cleaning process in order to group versions of the same file. If no Lambda is provided, [`S3AssetDeploy::AssetHelper.remove_fingerprint`](https://github.com/Loomly/s3_asset_deploy/blob/main/lib/s3_asset_deploy/asset_helper.rb#L8) is used by default.
65
66
 
66
67
  Here's an example:
@@ -107,6 +108,46 @@ manager.clean
107
108
  `S3AssetDeploy::Manager#deploy` and `S3AssetDeploy::Manager#clean` both accept `dry_run` as a keyword argument.
108
109
  `S3AssetDeploy::Manager#clean` also accepts `version_limit`, `version_ttl`, and `removed_ttl` just like `S3AssetDeploy::Manager#deploy`.
109
110
 
111
+ ### Practical Example of Usage
112
+ There are many ways to use and invoke `S3AssetDeploy`. How you use it will depend on your deploy process and pipeline. At Loomly, we have some rake tasks that are invoked from our CI/CD pipeline to perform deploys.
113
+ Here's a basic example of how we use `S3AssetDeploy`:
114
+
115
+
116
+ ```ruby
117
+ # lib/tasks/deploy.rake
118
+
119
+ require "s3_asset_deploy"
120
+
121
+ namespace :deploy do
122
+ task precompile: :environment do
123
+ puts "Precompiling assets..."
124
+ sh("RAILS_ENV=production SECRET_KEY_BASE='secret key' bundle exec rake assets:precompile")
125
+ end
126
+
127
+ task clobber_assets: :environment do
128
+ puts "Clobbering assets..."
129
+ sh("RAILS_ENV=production SECRET_KEY_BASE='secret key' bundle exec rake assets:clobber")
130
+ end
131
+
132
+ task :production do
133
+ Rake::Task["deploy:precompile"].invoke
134
+
135
+ manager = S3AssetDeploy::Manager.new("my-s3-bucket")
136
+ manager.deploy do
137
+ # Perform deploy to web instances in this block.
138
+ # How you do this will depend on where you are hosting your application and what tools you use to deploy.
139
+ end
140
+
141
+ Rake::Task["deploy:clobber_assets"].invoke # <-- If you are running on CI where the precompiled assets directory is ephemeral, this may be unnecessary
142
+ end
143
+ end
144
+ ```
145
+
146
+ Given the example above, we can perform a deploy by running `bundle exec rake deploy:production`. This task will:
147
+ 1. Precompile assets
148
+ 2. Upload any new assets to S3 using `S3AssetDeploy`
149
+ 3. Deploy a new version of our application
150
+ 4. Clean any outdated or unused assets from S3 using `S3AssetDeploy`
110
151
 
111
152
  ## Customizing local asset collection
112
153
  By default, `S3AssetDeploy::Manager` will use [`S3AssetDeploy::RailsLocalAssetCollector`](https://github.com/Loomly/s3_asset_deploy/blob/main/lib/s3_asset_deploy/rails_local_asset_collector.rb) to collect locally compiled assets. This will use the `Sprockets::Manifest` and `Webpacker` config (if `Webpacker` is installed) to locate the compiled assets. `S3AssetDeploy::RailsLocalAssetCollector` inherits from the [`S3AssetDeploy::LocalAssetCollector`](https://github.com/Loomly/s3_asset_deploy/blob/main/lib/s3_asset_deploy/local_asset_collector.rb) base class. You can completely customize how your local assets are collected for deploys by creating your own class that inherits from `S3AssetDeploy::LocalAssetCollector` and passing it into the manager. You'll want override `S3AssetDeploy::LocalAssetCollector#assets` in your custom collector such that it returns an array of `S3AssetDeploy::LocalAsset` instances. Here's a basic example:
@@ -133,7 +174,7 @@ This will skip any write or delete operations and only perform read opeartions w
133
174
  This is helpful for debugging or planning purposes.
134
175
 
135
176
  ```ruby
136
- > manager = S3AssetDeploy::Manager("my-s3-bucket")
177
+ > manager = S3AssetDeploy::Manager.new("my-s3-bucket")
137
178
  > manager.deploy(dry_run: true)
138
179
 
139
180
  I, [2021-02-17T16:12:23.703677 #65335] INFO -- : S3AssetDeploy::Manager: Cleaning assets from test-bucket S3 bucket. Dry run: true
@@ -142,7 +183,7 @@ I, [2021-02-17T16:12:23.703677 #65335] INFO -- : S3AssetDeploy::Manager: Determ
142
183
  ```
143
184
 
144
185
  ## AWS IAM Permissions
145
- `S3AsetDeploy` requires the following AWS IAM permissions:
186
+ `S3AsetDeploy` requires the following AWS IAM permissions to list, put, and delete objects in your S3 Bucket:
146
187
 
147
188
  ```json
148
189
  "Statement": [
@@ -161,6 +202,65 @@ I, [2021-02-17T16:12:23.703677 #65335] INFO -- : S3AssetDeploy::Manager: Determ
161
202
  ]
162
203
  ```
163
204
 
205
+ ## Configuration with Cloudfront
206
+
207
+ ### Restricting Access with Origin Access Identity
208
+ If you want to setup Cloudfront to serve your assets, you can [restrict access to the bucket by using an Origin Access Identity](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#private-content-granting-permissions-to-oai) so that only Cloudfront can access the objects in your bucket.
209
+
210
+ If you do this, your bucket policy will look something like this:
211
+
212
+ ```json
213
+ {
214
+ "Version": "2012-10-17",
215
+ "Statement": [
216
+ {
217
+ "Sid": "AllowGetObject",
218
+ "Effect": "Allow",
219
+ "Principal": {
220
+ "AWS": [
221
+ "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity #{YOUR_OAI_ID}"
222
+ ]
223
+ },
224
+ "Action": "s3:GetObject",
225
+ "Resource": "arn:aws:s3:::#{YOUR_BUCKET}/*"
226
+ },
227
+ {
228
+ "Sid": "DenyGetObject",
229
+ "Effect": "Deny",
230
+ "Principal": {
231
+ "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity #{YOUR_OAI_ID}"
232
+ },
233
+ "Action": "s3:GetObject",
234
+ "Resource": "arn:aws:s3:::#{YOUR_BUCKET}/s3-asset-deploy-removal-manifest.json"
235
+ }
236
+ ]
237
+ }
238
+ ```
239
+
240
+ This policy allows Cloudfront to access everything **except** the removal manifest uploaded and maintained by this gem since this manifest does not need to be served to clients.
241
+
242
+ ### CORS
243
+ Your CORS configuration on the bucket might look something like this:
244
+
245
+ ```json
246
+ [
247
+ {
248
+ "AllowedHeaders": [
249
+ "Authorization"
250
+ ],
251
+ "AllowedMethods": [
252
+ "GET",
253
+ "HEAD"
254
+ ],
255
+ "AllowedOrigins": [
256
+ "https://*.#{YOUR_SITE}.com"
257
+ ],
258
+ "ExposeHeaders": [],
259
+ "MaxAgeSeconds": 3000
260
+ }
261
+ ]
262
+ ```
263
+
164
264
  ## Development
165
265
 
166
266
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -7,7 +7,7 @@ class S3AssetDeploy::AssetHelper
7
7
 
8
8
  def self.remove_fingerprint(path)
9
9
  match_data = path.match(FINGERPRINTED_ASSET_REGEX)
10
- return asset_path unless match_data
10
+ return path unless match_data
11
11
  "#{match_data[1]}#{match_data[3]}"
12
12
  end
13
13
 
@@ -168,7 +168,6 @@ class S3AssetDeploy::Manager
168
168
  bucket: bucket_name,
169
169
  key: asset.path,
170
170
  body: file_handle,
171
- acl: "public-read",
172
171
  content_type: asset.mime_type,
173
172
  cache_control: "public, max-age=31536000"
174
173
  }.merge(@upload_options)
@@ -194,10 +193,12 @@ class S3AssetDeploy::Manager
194
193
 
195
194
  def delete_objects(keys = [])
196
195
  return if keys.empty?
197
- s3.delete_objects(
198
- bucket: bucket_name,
199
- delete: { objects: keys.map { |key| { key: key }} }
200
- )
196
+ keys.each_slice(1000) do |key_slice|
197
+ s3.delete_objects(
198
+ bucket: bucket_name,
199
+ delete: { objects: key_slice.map { |key| { key: key }} }
200
+ )
201
+ end
201
202
  end
202
203
 
203
204
  def log(msg)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module S3AssetDeploy
4
- VERSION = "0.1.0"
4
+ VERSION = "1.0.1"
5
5
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Loomly"]
9
9
  spec.email = ["contact@loomly.com"]
10
10
 
11
- spec.summary = "Safely deploy web app assets to S3 during rolling or multi-step deploys."
12
- spec.homepage = "https://www.loomly.com"
11
+ spec.summary = "Deploy & manage static assets on S3 with rolling deploys & rollbacks in mind."
12
+ spec.homepage = "https://github.com/Loomly/s3_asset_deploy"
13
13
  spec.license = "MIT"
14
14
  spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
15
15
 
@@ -36,6 +36,10 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency "pry-byebug", "~> 3.9"
37
37
  spec.add_development_dependency "rspec_junit_formatter", "~> 0.4"
38
38
 
39
+ # Required for aws-sdk-ruby.
40
+ # See https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-core/lib/aws-sdk-core/xml/parser.rb#L74
41
+ spec.add_development_dependency "nokogiri", "~> 1.13"
42
+
39
43
  # For more information and examples about making a new gem, checkout our
40
44
  # guide at: https://bundler.io/guides/creating_gem.html
41
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_asset_deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loomly
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-27 00:00:00.000000000 Z
11
+ date: 2022-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.4'
125
+ - !ruby/object:Gem::Dependency
126
+ name: nokogiri
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.13'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.13'
125
139
  description:
126
140
  email:
127
141
  - contact@loomly.com
@@ -154,11 +168,11 @@ files:
154
168
  - lib/s3_asset_deploy/removal_manifest.rb
155
169
  - lib/s3_asset_deploy/version.rb
156
170
  - s3_asset_deploy.gemspec
157
- homepage: https://www.loomly.com
171
+ homepage: https://github.com/Loomly/s3_asset_deploy
158
172
  licenses:
159
173
  - MIT
160
174
  metadata:
161
- homepage_uri: https://www.loomly.com
175
+ homepage_uri: https://github.com/Loomly/s3_asset_deploy
162
176
  source_code_uri: https://github.com/Loomly/s3_asset_deploy
163
177
  changelog_uri: https://github.com/Loomly/s3_asset_deploy/CHANGELOG.md
164
178
  post_install_message:
@@ -176,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
190
  - !ruby/object:Gem::Version
177
191
  version: '0'
178
192
  requirements: []
179
- rubygems_version: 3.0.3
193
+ rubygems_version: 3.2.32
180
194
  signing_key:
181
195
  specification_version: 4
182
- summary: Safely deploy web app assets to S3 during rolling or multi-step deploys.
196
+ summary: Deploy & manage static assets on S3 with rolling deploys & rollbacks in mind.
183
197
  test_files: []