jets_gem_layer 0.1 → 1.0.1

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: 796fe39c52a3459efb7585c20543607952c5760fbde14cd348172e50d1521fe3
4
- data.tar.gz: e9895777617ab674521b57a5d1f43477d9f05aeb3c276fc723b1595b4e8b0fbb
3
+ metadata.gz: 92ac2b1c7617c7a72a43baa82194bc05193d65d3bcd7cbceebf7609bec9b463d
4
+ data.tar.gz: 798fd9fe29457d71874ac3a3821383b286122ae29e0bb67a18501a847e0a05a7
5
5
  SHA512:
6
- metadata.gz: 82457f5266038a4b08424fe518a89aa67f71f15541d6db06435d1e6ae14bc202027fe95044ed70c4d4dc6e6c072c055298464baf8e8257f0eaa23a5c7999fd7c
7
- data.tar.gz: 308673cfb04e7ed74bea54fa2dcc4ebbc2773adb5ea2be3dac64b2182d98a3a7a7b9bda9dd74f543a8cb136bac9d8d201a340834f85c273b7e211f48173f8fe3
6
+ metadata.gz: 4820f54954f93a71919c7fdb75625539c76ecae6938b2af2e926c179fb6350979ab153891c62c4f7a828cd2dc2a49d51c86aaaa610274484f433f90cf06ecd04
7
+ data.tar.gz: 5d09bad45ce5cc6d4e7714ce7bae33e12e3ab0ff97b53ba127e69188585152c0cad49c5eda2604eaad6b25bb0b5f9a25b009e9c9cbd5f482d46582cbb5af0ae1
data/.gitignore CHANGED
@@ -6,10 +6,11 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
-
9
+ *.gem
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  .rakeTasks
13
13
 
14
14
  /.idea/
15
- tags
15
+ tags
16
+ .DS_Store
data/.rubocop.yml CHANGED
@@ -1,3 +1,39 @@
1
+ require: rubocop-rspec
1
2
  inherit_from: .rubocop_todo.yml
2
3
  AllCops:
3
- NewCops: enable
4
+ NewCops: enable
5
+
6
+ RSpec/MultipleExpectations:
7
+ Enabled: false
8
+
9
+ RSpec/NestedGroups:
10
+ Max: 4
11
+
12
+ Lint/MixedRegexpCaptureTypes:
13
+ Exclude:
14
+ - 'lib/jets_gem_layer/build_env/build_layer.rb'
15
+
16
+ Metrics/AbcSize:
17
+ Exclude:
18
+ - 'lib/jets_gem_layer/build_env/build_layer.rb'
19
+
20
+ Metrics/CyclomaticComplexity:
21
+ Exclude:
22
+ - 'lib/jets_gem_layer/build_env/build_layer.rb'
23
+
24
+ Metrics/MethodLength:
25
+ Exclude:
26
+ - 'lib/jets_gem_layer/build_env/build_layer.rb'
27
+
28
+ Metrics/PerceivedComplexity:
29
+ Exclude:
30
+ - 'lib/jets_gem_layer/build_env/build_layer.rb'
31
+
32
+ Metrics/ClassLength:
33
+ Enabled: false
34
+
35
+ RSpec/ExampleLength:
36
+ Max: 10
37
+
38
+ RSpec/MultipleMemoizedHelpers:
39
+ Max: 10
data/.rubocop_todo.yml CHANGED
@@ -6,31 +6,3 @@
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 1
10
- Lint/MixedRegexpCaptureTypes:
11
- Exclude:
12
- - 'lib/jets_gem_layer/build_env/build_layer.rb'
13
-
14
- Metrics/AbcSize:
15
- Exclude:
16
- - 'lib/jets_gem_layer/build_env/build_layer.rb'
17
-
18
- Metrics/CyclomaticComplexity:
19
- Exclude:
20
- - 'lib/jets_gem_layer/build_env/build_layer.rb'
21
-
22
- Metrics/MethodLength:
23
- Exclude:
24
- - 'lib/jets_gem_layer/build_env/build_layer.rb'
25
-
26
- Metrics/PerceivedComplexity:
27
- Exclude:
28
- - 'lib/jets_gem_layer/build_env/build_layer.rb'
29
-
30
- # Offense count: 2
31
- # Configuration parameters: AllowedConstants.
32
- Style/Documentation:
33
- Enabled: false
34
-
35
- Metrics/ClassLength:
36
- Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-3.2.2
data/Gemfile CHANGED
@@ -2,11 +2,14 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- # Specify your gem's dependencies in s3_gem_host.gemspec
6
- gemspec
5
+ gem 'jets', '~> 5.0'
6
+ gem 'rake'
7
7
 
8
8
  group :development, :test do
9
+ gem 'mysql2', require: false # only included to test building a layer with a named dependency (mysql-devel)
9
10
  gem 'rspec'
10
11
  gem 'rubocop', require: false
11
12
  gem 'rubocop-rspec', require: false
13
+ gem 'rubyzip'
14
+ gem 'simplecov', require: false
12
15
  end
data/Gemfile.lock CHANGED
@@ -1,10 +1,3 @@
1
- PATH
2
- remote: .
3
- specs:
4
- jets_gem_layer (0.1)
5
- jets (~> 5.0)
6
- rake
7
-
8
1
  GEM
9
2
  remote: https://rubygems.org/
10
3
  specs:
@@ -61,7 +54,7 @@ GEM
61
54
  rainbow
62
55
  thor
63
56
  zeitwerk
64
- aws-partitions (1.875.0)
57
+ aws-partitions (1.877.0)
65
58
  aws-sdk-apigateway (1.90.0)
66
59
  aws-sdk-core (~> 3, >= 3.188.0)
67
60
  aws-sigv4 (~> 1.1)
@@ -120,6 +113,7 @@ GEM
120
113
  crass (1.0.6)
121
114
  date (3.3.4)
122
115
  diff-lcs (1.5.0)
116
+ docile (1.4.0)
123
117
  dotenv (2.8.1)
124
118
  dsl_evaluator (0.3.1)
125
119
  activesupport
@@ -197,6 +191,7 @@ GEM
197
191
  method_source (1.0.0)
198
192
  mini_mime (1.1.5)
199
193
  minitest (5.20.0)
194
+ mysql2 (0.5.5)
200
195
  net-imap (0.4.9)
201
196
  date
202
197
  net-protocol
@@ -261,15 +256,22 @@ GEM
261
256
  unicode-display_width (>= 2.4.0, < 3.0)
262
257
  rubocop-ast (1.30.0)
263
258
  parser (>= 3.2.1.0)
264
- rubocop-capybara (2.19.0)
259
+ rubocop-capybara (2.20.0)
265
260
  rubocop (~> 1.41)
266
- rubocop-factory_bot (2.24.0)
261
+ rubocop-factory_bot (2.25.0)
267
262
  rubocop (~> 1.33)
268
- rubocop-rspec (2.25.0)
263
+ rubocop-rspec (2.26.0)
269
264
  rubocop (~> 1.40)
270
265
  rubocop-capybara (~> 2.17)
271
266
  rubocop-factory_bot (~> 2.22)
272
267
  ruby-progressbar (1.13.0)
268
+ rubyzip (2.3.2)
269
+ simplecov (0.22.0)
270
+ docile (~> 1.1)
271
+ simplecov-html (~> 0.11)
272
+ simplecov_json_formatter (~> 0.1)
273
+ simplecov-html (0.12.3)
274
+ simplecov_json_formatter (0.1.4)
273
275
  text-table (1.2.4)
274
276
  thor (1.3.0)
275
277
  timeout (0.4.1)
@@ -282,10 +284,14 @@ PLATFORMS
282
284
  arm64-darwin-23
283
285
 
284
286
  DEPENDENCIES
285
- jets_gem_layer!
287
+ jets (~> 5.0)
288
+ mysql2
289
+ rake
286
290
  rspec
287
291
  rubocop
288
292
  rubocop-rspec
293
+ rubyzip
294
+ simplecov
289
295
 
290
296
  BUNDLED WITH
291
297
  2.5.3
data/README.md CHANGED
@@ -14,7 +14,7 @@ is correctly set for your project.
14
14
 
15
15
  ## Installation
16
16
 
17
- 1. Jets Pro would typically be disabled when using this gem so as to not generate multiple Lambda Layers.
17
+ 1. Jets Pro would typically be disabled when using this gem so as to not generate duplicative Lambda Layers.
18
18
 
19
19
  ```ruby
20
20
  # config/application.rb
@@ -55,10 +55,12 @@ JetsGemLayer.load_tasks
55
55
  3. After running `bundle install`, run `rake -T` and you should see this Gem's tasks available for use.
56
56
  ```
57
57
  ➜ rake -T
58
- rake gem_layer:build_and_publish # Build, publish, and clean
59
- rake gem_layer:build # Build the gem layer zip file
60
- rake gem_layer:publish # Publish the built gem laye zip to AWS
61
- rake gem_layer:clean # Clean up the gem's tmp files
58
+ rake gem_layer:build_and_publish # Build and publish a gem layer version, if necessary
59
+ rake gem_layer:build # Build a gem layer zip file
60
+ rake gem_layer:publish # Publish the already built layer zip file
61
+ rake gem_layer:clean # Clean jets_gem_layer tmp files
62
+ rake gem_layer:cleanup_published # Delete old layer versions from AWS (for use after deployment)
63
+ rake gem_layer:delete_all_published # Delete all published versions of the gem layer from AWS
62
64
  ```
63
65
 
64
66
  ## Configuration
@@ -72,9 +74,13 @@ specific to your Gemfile. For example, to build the `mysql2` gem you will need t
72
74
  Dependencies will be installed within the build container and copied into the published Lambda Layer.
73
75
 
74
76
  ## Deployment
75
- Within your project directory (example for development environment):
76
- 1. run `JETS_ENV=development rake gem_layer:build_and_publish`
77
- 2. run `JETS_ENV=development jets deploy`
77
+ Within your project directory (example for development environment) or through your CI/CD platform:
78
+ 1. `JETS_ENV=development rake gem_layer:build_and_publish`
79
+ * If needed, builds and publishes a new gem layer version based on the current Jets namespace, Gemfile.lock and Gemfile
80
+ 2. `JETS_ENV=development JETS_AGREE=no jets deploy`
81
+ * Deploy your application
82
+ 3. `JETS_ENV=development rake gem_layer:cleanup_published`
83
+ * After a successful deploy, you may run this to cleanup the old gem layer version(s) no longer in use
78
84
 
79
85
  ## Acknowledgements
80
86
  A big thank you to the authors of [Lambda Layer Cake](https://github.com/loganb/lambda-layer-cake), which served as a reference.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/core/rake_task'
4
+ require 'bundler/gem_tasks'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -6,6 +6,8 @@ require 'English'
6
6
  require 'open3'
7
7
  require 'fileutils'
8
8
 
9
+ # This script runs in the public.ecr.aws/sam/build-ruby docker container
10
+ # to build native gems and libs which end up in the layer zip file
9
11
  def main
10
12
  warn('Installing yum package manager...')
11
13
  unless system('yum', 'install', '-y', 'yum-utils')
@@ -1,23 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JetsGemLayer
4
+ # All methods that run in the app environment, including rake tasks
4
5
  class TaskHelper
5
6
  include Rake::DSL
6
7
  include Jets::AwsServices
7
8
 
8
9
  # Files used to generate the gem layer
9
10
  INPUT_FILES = Rake::FileList.new(
10
- ['Gemfile', 'Gemfile.lock'].collect { |f| File.join(Jets.root, f) }
11
+ %w[Gemfile Gemfile.lock].map { |f| File.join(Jets.root, f) }
11
12
  )
12
- LOCAL_TMP_DIR = 'tmp/jets_gem_layer'
13
- OUTPUT_DIR = File.expand_path(File.join(Jets.root, "#{LOCAL_TMP_DIR}/"))
13
+ OUTPUT_DIR = File.expand_path(File.join(Jets.root, 'tmp/jets_gem_layer/'))
14
+
15
+ def self.instance
16
+ @instance ||= new
17
+ end
14
18
 
15
19
  def self.install
16
- new.install
20
+ return if @installed
21
+
22
+ instance.install
23
+ @installed = true
17
24
  end
18
25
 
19
26
  def self.arn
20
- @arn ||= new.arn
27
+ instance.arn
21
28
  end
22
29
 
23
30
  def arn
@@ -34,69 +41,129 @@ module JetsGemLayer
34
41
 
35
42
  def install
36
43
  namespace :gem_layer do
37
- install_build_and_publish
44
+ install_clean
38
45
  install_build
39
46
  install_publish
40
- install_clean
47
+ install_build_and_publish
48
+ install_cleanup_published
49
+ install_delete_all_published
41
50
  end
51
+ true
42
52
  end
43
53
 
44
54
  def install_build_and_publish
45
- desc 'Build and publish a gem layer version'
55
+ desc 'Build and publish a gem layer version, if necessary'
46
56
  task :build_and_publish do
57
+ if published?
58
+ puts "#{layer_name} already published for #{layer_version_description}. Not doing anything!"
59
+ next
60
+ end
47
61
  Rake::Task['gem_layer:build'].invoke
48
62
  Rake::Task['gem_layer:publish'].invoke
49
- Rake::Task['gem_layer:clean'].invoke
50
63
  end
51
64
  end
52
65
 
53
66
  def install_build
54
- desc 'Build the gem layer zip file'
55
- task :build do
56
- Rake::Task['gem_layer:clean'].invoke
67
+ desc 'Build a gem layer zip file'
68
+ task build: :clean do
57
69
  build_layer
58
70
  zip_layer
59
71
  end
60
72
  end
61
73
 
62
74
  def install_publish
63
- desc 'Publish a built layer zip file'
75
+ desc 'Publish the already built layer zip file'
64
76
  task :publish do
65
77
  publish_layer
66
78
  end
67
79
  end
68
80
 
69
81
  def install_clean
70
- desc 'Clean tmp files'
82
+ desc 'Clean jets_gem_layer tmp files'
71
83
  task :clean do
72
- FileUtils.rm_r(working_dir) if File.exist?(working_dir)
84
+ clean_working_dir
73
85
  end
74
86
  end
75
87
 
76
- def build_layer
77
- FileUtils.mkdir_p(inputs_dir)
78
- FileUtils.cp(INPUT_FILES.existing, inputs_dir)
79
- system(*docker_run_cmd) or raise
88
+ def install_cleanup_published
89
+ desc 'Delete old layer versions from AWS (for use after deployment)'
90
+ task :cleanup_published do
91
+ cleanup_published
92
+ end
80
93
  end
81
94
 
82
- def zip_layer
83
- pwd = Dir.pwd
84
- begin
85
- Dir.chdir(outputs_dir)
86
- system(*%W[zip -r #{File.join(working_dir, "#{layer_name}.zip")} lib ruby], out: File::NULL) or raise
87
- puts 'Layer zipped successfully...'
88
- ensure
89
- Dir.chdir(pwd)
95
+ def install_delete_all_published
96
+ desc 'Delete all published versions of the gem layer from AWS'
97
+ task :delete_all_published do
98
+ delete_all_published
90
99
  end
91
100
  end
92
101
 
102
+ def build_layer
103
+ FileUtils.mkdir_p(inputs_dir)
104
+ FileUtils.cp(INPUT_FILES.existing, inputs_dir)
105
+ system(*docker_run_cmd) or raise $CHILD_STATUS.to_s
106
+ zip_layer
107
+ end
108
+
93
109
  def publish_layer
94
110
  aws_lambda.publish_layer_version(
95
111
  layer_name:, # required
96
112
  description: layer_version_description,
97
113
  content: { zip_file: File.read(zip_file_path) }
98
114
  )
99
- puts "#{layer_name} published for #{layer_version_description}..."
115
+ puts "#{layer_name} published for #{layer_version_description}!"
116
+ end
117
+
118
+ def clean_working_dir
119
+ FileUtils.rm_rf(working_dir)
120
+ end
121
+
122
+ def cleanup_published
123
+ all_layer_versions.each_with_index do |layer_version, i|
124
+ next if i.zero? # skips the current version
125
+
126
+ aws_lambda.delete_layer_version(layer_name:, version_number: layer_version.version)
127
+ puts "Deleted #{layer_version.layer_version_arn}"
128
+ end
129
+ puts 'Deleted all prior versions!'
130
+ end
131
+
132
+ def delete_all_published
133
+ all_layer_versions.each do |layer_version|
134
+ aws_lambda.delete_layer_version(layer_name:, version_number: layer_version.version)
135
+ puts "Deleted #{layer_version.layer_version_arn}"
136
+ end
137
+ puts 'Deleted all published versions!'
138
+ end
139
+
140
+ # paginate through all layer versions to get them all (but it's unlikely there will be more than 1 page)
141
+ def all_layer_versions
142
+ all_versions = []
143
+ marker = nil
144
+ loop do
145
+ page = aws_lambda.list_layer_versions(layer_name:, max_items: 50, marker:)
146
+ all_versions.concat page.layer_versions
147
+ marker = page.next_marker
148
+ break if marker.nil?
149
+ end
150
+ all_versions
151
+ end
152
+
153
+ def published_layer_version
154
+ @published_layer_version ||= aws_lambda.list_layer_versions(layer_name:, max_items: 1).layer_versions.first
155
+ end
156
+
157
+ def published?
158
+ published_layer_version&.description == layer_version_description
159
+ end
160
+
161
+ def published_arn
162
+ return nil unless published?
163
+
164
+ published_layer_version.layer_version_arn
165
+ rescue StandardError
166
+ 'error-fetching-gem-layer-arn'
100
167
  end
101
168
 
102
169
  private
@@ -150,30 +217,24 @@ module JetsGemLayer
150
217
  -v #{outputs_dir}:/tmp/outputs
151
218
  -v #{File.expand_path("#{__dir__}/build_env")}:/var/task]
152
219
 
153
- ENV.fetch('GEM_LAYER_ENV').split(',').each { |env| cmd.push "-e#{env}" } if ENV['GEM_LAYER_ENV']
220
+ ENV.fetch('GEM_LAYER_ENV').split(',').each { |env| cmd.push "-e#{env}" } if ENV.key?('GEM_LAYER_ENV')
154
221
 
155
- if ENV['GEM_LAYER_PACKAGE_DEPENDENCIES']
222
+ if ENV.key?('GEM_LAYER_PACKAGE_DEPENDENCIES')
156
223
  cmd.push "-eGEM_LAYER_PACKAGE_DEPENDENCIES=#{ENV.fetch('GEM_LAYER_PACKAGE_DEPENDENCIES')}"
157
224
  end
158
225
 
159
226
  cmd.push(*%W[public.ecr.aws/sam/build-ruby#{docker_tag} ruby build_layer.rb])
160
227
  end
161
228
 
162
- def published_arn
163
- return nil unless published?
164
-
165
- published_layer_version.layer_version_arn
166
- rescue StandardError
167
- Jets.logger.error('Could not resolve lambda layer arn')
168
- 'error-fetching-gem-layer-arn'
169
- end
170
-
171
- def published?
172
- published_layer_version&.description == layer_version_description
173
- end
174
-
175
- def published_layer_version
176
- @published_layer_version ||= aws_lambda.list_layer_versions({ layer_name: }).layer_versions&.first
229
+ def zip_layer
230
+ pwd = Dir.pwd
231
+ begin
232
+ Dir.chdir(outputs_dir)
233
+ system(*%W[zip -r #{File.join(working_dir, "#{layer_name}.zip")} lib ruby], out: File::NULL) or raise
234
+ puts 'Layer zipped successfully!'
235
+ ensure
236
+ Dir.chdir(pwd)
237
+ end
177
238
  end
178
239
  end
179
240
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JetsGemLayer
4
- VERSION = '0.1'
4
+ VERSION = '1.0.1'
5
5
  end
@@ -5,8 +5,10 @@ require 'digest'
5
5
  require 'fileutils'
6
6
  require 'rake'
7
7
 
8
+ require 'jets_gem_layer/version'
8
9
  require 'jets_gem_layer/task_helper'
9
10
 
11
+ # Base module with helper methods
10
12
  module JetsGemLayer
11
13
  def self.load_tasks
12
14
  JetsGemLayer::TaskHelper.install
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jets_gem_layer
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DocGo Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-29 00:00:00.000000000 Z
11
+ date: 2024-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jets
@@ -49,10 +49,12 @@ files:
49
49
  - ".gitignore"
50
50
  - ".rubocop.yml"
51
51
  - ".rubocop_todo.yml"
52
+ - ".ruby-version"
52
53
  - Gemfile
53
54
  - Gemfile.lock
54
55
  - LICENSE.txt
55
56
  - README.md
57
+ - Rakefile
56
58
  - jets_gem_layer.gemspec
57
59
  - lib/jets_gem_layer.rb
58
60
  - lib/jets_gem_layer/build_env/build_layer.rb