s3_asset_deploy 0.1.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d1f14b5addc89b2dcb33d380636458e467a74397d3733032035d33906b5e78b
4
- data.tar.gz: 829e2b62c558ea4692fd4447cef95f8e901d309849065c321654de8fbdc959a7
3
+ metadata.gz: 482b049a3ae897a8b60fdca1931da6de0fe4558ad5c6e958a0d474bdb6e2439c
4
+ data.tar.gz: 41232f6389b851e70dd95970052bfb3d8a7eb90561cfc613a72cdc2973e21d07
5
5
  SHA512:
6
- metadata.gz: c469bd3c5b39c0547ab3d455a601a3a36bf3e27f2b100739781aa11dbdff3355948c3157d0636c750c4f654364625448dce420b96ea4bde045efc339217ebec4
7
- data.tar.gz: dd0b2291255821f71790a0b78ded052e00ec53fb7e42f5d680fadb758ef6ecd0efa1fda534a1102a3749e65dd0e38d114eba3dd2eca9b46b819a6a4966b1d4b1
6
+ metadata.gz: e8bc7982759a34dbcac1c7b97ff34d3e2ed2a5657465394e4a5c3fdbb9c92deac254b0e27750729fc6d7c99486d4963475785e9f0fa8b6fbaad344993416a440
7
+ data.tar.gz: cc8788fc2dea4b4742c69c7fbc3f042b93eea65f06a79af361e8c5fd6ed83eea5b696448ba2265888fca085d8a89bc9ff5ea83b8c57963493619277fc17927de
data/CHANGELOG.md CHANGED
@@ -1,4 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.0.2](https://github.com/Loomly/s3_asset_deploy/compare/v1.0.1...v1.0.2) - 2022-09-12
4
+ - Remove `acl` specification when saving removal manifest. Bucket policies should be used instead.
5
+
6
+ ## [v1.0.1](https://github.com/Loomly/s3_asset_deploy/compare/v1.0.0...v1.0.1) - 2022-02-23
7
+ - Batch delete API calls with max 1000 keys - [PR #32](https://github.com/Loomly/s3_asset_deploy/pull/32)
8
+
9
+ ## [v1.0.0](https://github.com/Loomly/s3_asset_deploy/compare/v0.1.1...v1.0.0) - 2021-05-13
10
+ ### Breaking Changes
11
+ - Remove default `acl` setting when uploading assets to bucket - [PR #25](https://github.com/Loomly/s3_asset_deploy/pull/25)
12
+
3
13
  ## [v0.1.1](https://github.com/Loomly/s3_asset_deploy/compare/v0.1.0...v0.1.1) - 2021-03-22
4
14
  - 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.1)
4
+ s3_asset_deploy (1.0.2)
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.628.0)
13
+ aws-sdk-core (3.145.0)
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
- jmespath (~> 1.0)
18
- aws-sdk-kms (1.41.0)
19
- aws-sdk-core (~> 3, >= 3.109.0)
17
+ jmespath (~> 1, >= 1.6.1)
18
+ aws-sdk-kms (1.58.0)
19
+ aws-sdk-core (~> 3, >= 3.127.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.114.0)
22
+ aws-sdk-core (~> 3, >= 3.127.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.5.1)
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.1)
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
@@ -42,7 +42,7 @@ Before using `S3AssetDeploy` you want to make sure to compile your assets. Asset
42
42
 
43
43
 
44
44
  ```ruby
45
- manager = S3AssetDeploy::Manager("my-s3-bucket")
45
+ manager = S3AssetDeploy::Manager.new("my-s3-bucket")
46
46
  manager.deploy do
47
47
  # Perform deploy to web instances in this block
48
48
  end
@@ -61,7 +61,7 @@ You'll need to initialize `S3AssetDeploy::Manager` with an S3 bucket name and **
61
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`.
62
62
  - **logger** (Logger) -> A custom logger. By default things are logged to `STDOUT`.
63
63
  - **local_asset_collector** (S3AssetDeploy::LocalAssetCollector) -> A custom instance of `S3AssetDeploy::LocalAssetCollector`. This allows you to customize how locally compiled assets are collected.
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 `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`.
65
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.
66
66
 
67
67
  Here's an example:
@@ -108,6 +108,46 @@ manager.clean
108
108
  `S3AssetDeploy::Manager#deploy` and `S3AssetDeploy::Manager#clean` both accept `dry_run` as a keyword argument.
109
109
  `S3AssetDeploy::Manager#clean` also accepts `version_limit`, `version_ttl`, and `removed_ttl` just like `S3AssetDeploy::Manager#deploy`.
110
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`
111
151
 
112
152
  ## Customizing local asset collection
113
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:
@@ -134,7 +174,7 @@ This will skip any write or delete operations and only perform read opeartions w
134
174
  This is helpful for debugging or planning purposes.
135
175
 
136
176
  ```ruby
137
- > manager = S3AssetDeploy::Manager("my-s3-bucket")
177
+ > manager = S3AssetDeploy::Manager.new("my-s3-bucket")
138
178
  > manager.deploy(dry_run: true)
139
179
 
140
180
  I, [2021-02-17T16:12:23.703677 #65335] INFO -- : S3AssetDeploy::Manager: Cleaning assets from test-bucket S3 bucket. Dry run: true
@@ -143,7 +183,7 @@ I, [2021-02-17T16:12:23.703677 #65335] INFO -- : S3AssetDeploy::Manager: Determ
143
183
  ```
144
184
 
145
185
  ## AWS IAM Permissions
146
- `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:
147
187
 
148
188
  ```json
149
189
  "Statement": [
@@ -162,6 +202,65 @@ I, [2021-02-17T16:12:23.703677 #65335] INFO -- : S3AssetDeploy::Manager: Determ
162
202
  ]
163
203
  ```
164
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
+
165
264
  ## Development
166
265
 
167
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.
@@ -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)
@@ -45,7 +45,6 @@ class S3AssetDeploy::RemovalManifest
45
45
  bucket: bucket_name,
46
46
  key: PATH,
47
47
  body: @manifest.to_json,
48
- acl: "private",
49
48
  content_type: "application/json"
50
49
  })
51
50
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module S3AssetDeploy
4
- VERSION = "0.1.1"
4
+ VERSION = "1.0.2"
5
5
  end
@@ -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.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loomly
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-22 00:00:00.000000000 Z
11
+ date: 2022-09-12 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
@@ -176,7 +190,7 @@ 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
196
  summary: Deploy & manage static assets on S3 with rolling deploys & rollbacks in mind.