jets_gem_layer 0.1 → 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: 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