jets_gem_layer 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 796fe39c52a3459efb7585c20543607952c5760fbde14cd348172e50d1521fe3
4
+ data.tar.gz: e9895777617ab674521b57a5d1f43477d9f05aeb3c276fc723b1595b4e8b0fbb
5
+ SHA512:
6
+ metadata.gz: 82457f5266038a4b08424fe518a89aa67f71f15541d6db06435d1e6ae14bc202027fe95044ed70c4d4dc6e6c072c055298464baf8e8257f0eaa23a5c7999fd7c
7
+ data.tar.gz: 308673cfb04e7ed74bea54fa2dcc4ebbc2773adb5ea2be3dac64b2182d98a3a7a7b9bda9dd74f543a8cb136bac9d8d201a340834f85c273b7e211f48173f8fe3
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ .rakeTasks
13
+
14
+ /.idea/
15
+ tags
data/.rubocop.yml ADDED
@@ -0,0 +1,3 @@
1
+ inherit_from: .rubocop_todo.yml
2
+ AllCops:
3
+ NewCops: enable
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,36 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2023-12-28 16:04:34 UTC using RuboCop version 1.59.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
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/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in s3_gem_host.gemspec
6
+ gemspec
7
+
8
+ group :development, :test do
9
+ gem 'rspec'
10
+ gem 'rubocop', require: false
11
+ gem 'rubocop-rspec', require: false
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,291 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jets_gem_layer (0.1)
5
+ jets (~> 5.0)
6
+ rake
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionmailer (7.0.8)
12
+ actionpack (= 7.0.8)
13
+ actionview (= 7.0.8)
14
+ activejob (= 7.0.8)
15
+ activesupport (= 7.0.8)
16
+ mail (~> 2.5, >= 2.5.4)
17
+ net-imap
18
+ net-pop
19
+ net-smtp
20
+ rails-dom-testing (~> 2.0)
21
+ actionpack (7.0.8)
22
+ actionview (= 7.0.8)
23
+ activesupport (= 7.0.8)
24
+ rack (~> 2.0, >= 2.2.4)
25
+ rack-test (>= 0.6.3)
26
+ rails-dom-testing (~> 2.0)
27
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
28
+ actionview (7.0.8)
29
+ activesupport (= 7.0.8)
30
+ builder (~> 3.1)
31
+ erubi (~> 1.4)
32
+ rails-dom-testing (~> 2.0)
33
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
34
+ activejob (7.0.8)
35
+ activesupport (= 7.0.8)
36
+ globalid (>= 0.3.6)
37
+ activemodel (7.0.8)
38
+ activesupport (= 7.0.8)
39
+ activerecord (7.0.8)
40
+ activemodel (= 7.0.8)
41
+ activesupport (= 7.0.8)
42
+ activesupport (7.0.8)
43
+ concurrent-ruby (~> 1.0, >= 1.0.2)
44
+ i18n (>= 1.6, < 2)
45
+ minitest (>= 5.1)
46
+ tzinfo (~> 2.0)
47
+ ast (2.4.2)
48
+ aws-eventstream (1.3.0)
49
+ aws-logs (0.5.1)
50
+ activesupport
51
+ aws-mfa-secure
52
+ aws-sdk-cloudwatchlogs
53
+ rainbow
54
+ thor
55
+ zeitwerk
56
+ aws-mfa-secure (0.4.4)
57
+ activesupport
58
+ aws-sdk-core
59
+ aws_config
60
+ memoist
61
+ rainbow
62
+ thor
63
+ zeitwerk
64
+ aws-partitions (1.875.0)
65
+ aws-sdk-apigateway (1.90.0)
66
+ aws-sdk-core (~> 3, >= 3.188.0)
67
+ aws-sigv4 (~> 1.1)
68
+ aws-sdk-cloudformation (1.97.0)
69
+ aws-sdk-core (~> 3, >= 3.188.0)
70
+ aws-sigv4 (~> 1.1)
71
+ aws-sdk-cloudwatchlogs (1.76.0)
72
+ aws-sdk-core (~> 3, >= 3.188.0)
73
+ aws-sigv4 (~> 1.1)
74
+ aws-sdk-core (3.190.1)
75
+ aws-eventstream (~> 1, >= 1.3.0)
76
+ aws-partitions (~> 1, >= 1.651.0)
77
+ aws-sigv4 (~> 1.8)
78
+ jmespath (~> 1, >= 1.6.1)
79
+ aws-sdk-dynamodb (1.98.0)
80
+ aws-sdk-core (~> 3, >= 3.188.0)
81
+ aws-sigv4 (~> 1.1)
82
+ aws-sdk-kinesis (1.54.0)
83
+ aws-sdk-core (~> 3, >= 3.188.0)
84
+ aws-sigv4 (~> 1.1)
85
+ aws-sdk-kms (1.75.0)
86
+ aws-sdk-core (~> 3, >= 3.188.0)
87
+ aws-sigv4 (~> 1.1)
88
+ aws-sdk-lambda (1.113.0)
89
+ aws-sdk-core (~> 3, >= 3.188.0)
90
+ aws-sigv4 (~> 1.1)
91
+ aws-sdk-s3 (1.142.0)
92
+ aws-sdk-core (~> 3, >= 3.189.0)
93
+ aws-sdk-kms (~> 1)
94
+ aws-sigv4 (~> 1.8)
95
+ aws-sdk-sns (1.70.0)
96
+ aws-sdk-core (~> 3, >= 3.188.0)
97
+ aws-sigv4 (~> 1.1)
98
+ aws-sdk-sqs (1.69.0)
99
+ aws-sdk-core (~> 3, >= 3.188.0)
100
+ aws-sigv4 (~> 1.1)
101
+ aws-sdk-ssm (1.162.0)
102
+ aws-sdk-core (~> 3, >= 3.188.0)
103
+ aws-sigv4 (~> 1.1)
104
+ aws-sigv4 (1.8.0)
105
+ aws-eventstream (~> 1, >= 1.0.2)
106
+ aws_config (0.1.1)
107
+ builder (3.2.4)
108
+ cfn-status (0.5.0)
109
+ aws-sdk-cloudformation
110
+ cfn_camelizer (0.5.0)
111
+ activesupport
112
+ memoist
113
+ rainbow
114
+ cfn_response (0.2.0)
115
+ cli-format (0.5.0)
116
+ activesupport
117
+ text-table
118
+ zeitwerk
119
+ concurrent-ruby (1.2.2)
120
+ crass (1.0.6)
121
+ date (3.3.4)
122
+ diff-lcs (1.5.0)
123
+ dotenv (2.8.1)
124
+ dsl_evaluator (0.3.1)
125
+ activesupport
126
+ memoist
127
+ rainbow
128
+ zeitwerk
129
+ erubi (1.12.0)
130
+ gems (1.2.0)
131
+ globalid (1.2.1)
132
+ activesupport (>= 6.1)
133
+ hashie (5.0.0)
134
+ i18n (1.14.1)
135
+ concurrent-ruby (~> 1.0)
136
+ jets (5.0.8)
137
+ actionmailer (~> 7.0.8)
138
+ actionpack (~> 7.0.8)
139
+ actionview (~> 7.0.8)
140
+ activerecord (~> 7.0.8)
141
+ activesupport (~> 7.0.8)
142
+ aws-logs
143
+ aws-mfa-secure (~> 0.4.0)
144
+ aws-sdk-apigateway
145
+ aws-sdk-cloudformation
146
+ aws-sdk-cloudwatchlogs
147
+ aws-sdk-dynamodb
148
+ aws-sdk-kinesis
149
+ aws-sdk-lambda
150
+ aws-sdk-s3
151
+ aws-sdk-sns
152
+ aws-sdk-sqs
153
+ aws-sdk-ssm
154
+ cfn-status (>= 0.5.0)
155
+ cfn_camelizer (>= 0.4.9)
156
+ cfn_response
157
+ cli-format (>= 0.4.0)
158
+ dotenv
159
+ dsl_evaluator (>= 0.3.0)
160
+ gems
161
+ hashie
162
+ jets-api (>= 0.1.4)
163
+ jets-git
164
+ jets-html-sanitizer
165
+ kramdown
166
+ memoist
167
+ mini_mime
168
+ rack
169
+ railties (~> 7.0.8)
170
+ rainbow
171
+ recursive-open-struct
172
+ text-table
173
+ thor
174
+ zeitwerk (>= 2.6.0)
175
+ jets-api (0.1.5)
176
+ jets-git (0.2.1)
177
+ activesupport
178
+ memoist
179
+ rainbow
180
+ zeitwerk
181
+ jets-html-sanitizer (1.0.4)
182
+ loofah (~> 2.2, >= 2.2.2)
183
+ jmespath (1.6.2)
184
+ json (2.7.1)
185
+ kramdown (2.4.0)
186
+ rexml
187
+ language_server-protocol (3.17.0.3)
188
+ loofah (2.22.0)
189
+ crass (~> 1.0.2)
190
+ nokogiri (>= 1.12.0)
191
+ mail (2.8.1)
192
+ mini_mime (>= 0.1.1)
193
+ net-imap
194
+ net-pop
195
+ net-smtp
196
+ memoist (0.16.2)
197
+ method_source (1.0.0)
198
+ mini_mime (1.1.5)
199
+ minitest (5.20.0)
200
+ net-imap (0.4.9)
201
+ date
202
+ net-protocol
203
+ net-pop (0.1.2)
204
+ net-protocol
205
+ net-protocol (0.2.2)
206
+ timeout
207
+ net-smtp (0.4.0)
208
+ net-protocol
209
+ nokogiri (1.16.0-arm64-darwin)
210
+ racc (~> 1.4)
211
+ parallel (1.24.0)
212
+ parser (3.2.2.4)
213
+ ast (~> 2.4.1)
214
+ racc
215
+ racc (1.7.3)
216
+ rack (2.2.8)
217
+ rack-test (2.1.0)
218
+ rack (>= 1.3)
219
+ rails-dom-testing (2.2.0)
220
+ activesupport (>= 5.0.0)
221
+ minitest
222
+ nokogiri (>= 1.6)
223
+ rails-html-sanitizer (1.6.0)
224
+ loofah (~> 2.21)
225
+ nokogiri (~> 1.14)
226
+ railties (7.0.8)
227
+ actionpack (= 7.0.8)
228
+ activesupport (= 7.0.8)
229
+ method_source
230
+ rake (>= 12.2)
231
+ thor (~> 1.0)
232
+ zeitwerk (~> 2.5)
233
+ rainbow (3.1.1)
234
+ rake (13.1.0)
235
+ recursive-open-struct (1.1.3)
236
+ regexp_parser (2.8.3)
237
+ rexml (3.2.6)
238
+ rspec (3.12.0)
239
+ rspec-core (~> 3.12.0)
240
+ rspec-expectations (~> 3.12.0)
241
+ rspec-mocks (~> 3.12.0)
242
+ rspec-core (3.12.2)
243
+ rspec-support (~> 3.12.0)
244
+ rspec-expectations (3.12.3)
245
+ diff-lcs (>= 1.2.0, < 2.0)
246
+ rspec-support (~> 3.12.0)
247
+ rspec-mocks (3.12.6)
248
+ diff-lcs (>= 1.2.0, < 2.0)
249
+ rspec-support (~> 3.12.0)
250
+ rspec-support (3.12.1)
251
+ rubocop (1.59.0)
252
+ json (~> 2.3)
253
+ language_server-protocol (>= 3.17.0)
254
+ parallel (~> 1.10)
255
+ parser (>= 3.2.2.4)
256
+ rainbow (>= 2.2.2, < 4.0)
257
+ regexp_parser (>= 1.8, < 3.0)
258
+ rexml (>= 3.2.5, < 4.0)
259
+ rubocop-ast (>= 1.30.0, < 2.0)
260
+ ruby-progressbar (~> 1.7)
261
+ unicode-display_width (>= 2.4.0, < 3.0)
262
+ rubocop-ast (1.30.0)
263
+ parser (>= 3.2.1.0)
264
+ rubocop-capybara (2.19.0)
265
+ rubocop (~> 1.41)
266
+ rubocop-factory_bot (2.24.0)
267
+ rubocop (~> 1.33)
268
+ rubocop-rspec (2.25.0)
269
+ rubocop (~> 1.40)
270
+ rubocop-capybara (~> 2.17)
271
+ rubocop-factory_bot (~> 2.22)
272
+ ruby-progressbar (1.13.0)
273
+ text-table (1.2.4)
274
+ thor (1.3.0)
275
+ timeout (0.4.1)
276
+ tzinfo (2.0.6)
277
+ concurrent-ruby (~> 1.0)
278
+ unicode-display_width (2.5.0)
279
+ zeitwerk (2.6.12)
280
+
281
+ PLATFORMS
282
+ arm64-darwin-23
283
+
284
+ DEPENDENCIES
285
+ jets_gem_layer!
286
+ rspec
287
+ rubocop
288
+ rubocop-rspec
289
+
290
+ BUNDLED WITH
291
+ 2.5.3
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+
2
+ Copyright (c) Dara Technologies, LLC
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Jets Gem Layer
2
+ This gem provides a framework for automatically creating and publish an AWS Lambda Layer from project gems and
3
+ their linked libraries for use with [Ruby on Jets](https://github.com/rubyonjets/jets).
4
+
5
+ This gem creates a Lambda Layer based on your Jets project namespace and ruby version. I.e. for the app `demo` in `production` environment,
6
+ the Lambda Layer `demo-prod-ruby-3_2_2-gem_layer` will be created or its version incremented as needed. A new version is published whenever your
7
+ Gemfile.lock and/or Gemfile is changed (this is tracked based on a hash value stored in the Lambda Layer version description).
8
+
9
+ * The gem's build task runs in a docker container, i.e. `public.ecr.aws/sam/build-ruby:3.2`. The container version
10
+ is based on the current minor ruby version (i.e. 3.2 for ruby 3.2.2, so ensure your build environment's ruby version
11
+ is correctly set for your project.
12
+ * Docker is a prerequisite and must be installed to use this gem.
13
+ * This gem has not been tested to work on windows machines.
14
+
15
+ ## Installation
16
+
17
+ 1. Jets Pro would typically be disabled when using this gem so as to not generate multiple Lambda Layers.
18
+
19
+ ```ruby
20
+ # config/application.rb
21
+
22
+ config.pro.disable = true
23
+ ```
24
+
25
+ 2. The layer ARN created by this gem must be inserted so it is referenced on app deployment. The easiest way to do this
26
+ is to add the included helper to your environment configuration.
27
+
28
+ ```ruby
29
+ # config/production.rb
30
+
31
+ # JetsGemLayer.arn will resolve to the latest version of the published Layer, also looking for a correct hash in the
32
+ # layer description indicating the current Gemfile.lock and Gemfile are supported.
33
+ # If a suitable layer is not found, the gem will log an error and resolve to 'error-fetching-gem-layer-arn' which will allow your
34
+ # application to run locally but hopefully prevent an invalid deployment
35
+ config.lambda.layers = [JetsGemLayer.arn]
36
+ ```
37
+
38
+ 3. Add this gem to your Gemfile:
39
+ ```ruby
40
+ # Gemfile
41
+ gem 'jets_gem_layer'
42
+ ```
43
+
44
+ 4. Add the gem's initializer to your Rakefile
45
+ ```ruby
46
+ # Rakefile
47
+
48
+ require 'jets'
49
+ require_relative 'config/application'
50
+
51
+ Jets.application.load_tasks
52
+ JetsGemLayer.load_tasks
53
+ ```
54
+
55
+ 3. After running `bundle install`, run `rake -T` and you should see this Gem's tasks available for use.
56
+ ```
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
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ The following environmental variables may be used:
67
+ * `GEM_LAYER_ENV`: Comma-separated `key=value` pairs which will be added to the docker build environment.
68
+ For example, to pass a Gemfury token for Bundler, you could use `GEM_LAYER_ENV="BUNDLE_GEM__FURY__IO=xxyyzz"`
69
+ and `BUNDLE_GEM__FURY__IO` will be set correctly within the build container.
70
+ * `GEM_LAYER_PACKAGE_DEPENDENCIES`: use this to identify comma separated dependencies required for bundle install
71
+ specific to your Gemfile. For example, to build the `mysql2` gem you will need to set `GEM_LAYER_PACKAGE_DEPENDENCIES=mysql-devel`.
72
+ Dependencies will be installed within the build container and copied into the published Lambda Layer.
73
+
74
+ ## 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`
78
+
79
+ ## Acknowledgements
80
+ A big thank you to the authors of [Lambda Layer Cake](https://github.com/loganb/lambda-layer-cake), which served as a reference.
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'jets_gem_layer/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'jets_gem_layer'
9
+ spec.version = JetsGemLayer::VERSION
10
+ spec.authors = ['DocGo Engineering']
11
+ spec.license = 'MIT'
12
+ spec.required_ruby_version = '~> 3.2'
13
+
14
+ spec.summary = 'Rake tasks to automate building a Lambda Layer for Ruby on Jets projects'
15
+ spec.description = 'This gem provides Rake tasks to create and publish an AWS Lambda Layer from project gems ' \
16
+ 'and their linked libraries. Designed for use with Ruby on Jets 5.'
17
+ spec.homepage = 'https://github.com/ambulnzllc/jets_gem_layer'
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+
22
+ spec.add_dependency 'jets', '~> 5.0'
23
+ spec.add_dependency 'rake'
24
+ spec.metadata['rubygems_mfa_required'] = 'true'
25
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Substantial portions of this file attributed to lambda_layer_cake (c) 2019 Logan Bowers
4
+
5
+ require 'English'
6
+ require 'open3'
7
+ require 'fileutils'
8
+
9
+ def main
10
+ warn('Installing yum package manager...')
11
+ unless system('yum', 'install', '-y', 'yum-utils')
12
+ warn("Could not install yum-utils, exit code #{$CHILD_STATUS}, aborting...")
13
+ exit 1
14
+ end
15
+
16
+ Dir.chdir('/tmp/inputs')
17
+
18
+ if ENV['GEM_LAYER_PACKAGE_DEPENDENCIES']
19
+ warn("Installing package dependencies: #{ENV.fetch('GEM_LAYER_PACKAGE_DEPENDENCIES')}...")
20
+ gem_deps = ENV.fetch('GEM_LAYER_PACKAGE_DEPENDENCIES').split(',')
21
+ unless system('yum', 'install', '-y', *gem_deps)
22
+ warn('Could not install build dependency packages, aborting...')
23
+ exit 2
24
+ end
25
+ end
26
+
27
+ warn('Building gems...')
28
+ FileUtils.mkdir_p('/tmp/build/bundle')
29
+ system('bundle', 'lock', '--add-platform', 'x86_64-linux')
30
+ system('bundle', 'config', 'set', '--local', 'deployment', 'true')
31
+ system('bundle', 'config', 'set', '--local', 'path', '/tmp/build/bundle')
32
+ unless system('bundle', 'install')
33
+ warn('Error while building gems, aborting...')
34
+ exit 3
35
+ end
36
+
37
+ warn('Copying libs...')
38
+ required_libs = Set.new
39
+ yum_cache = Hash.new do |h, k|
40
+ pkgs_str, = Open3.capture2('repoquery', '-f', k)
41
+ h[k] = pkgs_str
42
+ end
43
+
44
+ Dir['/tmp/build/**/*.so*'].each do |lib|
45
+ deps_str, status = Open3.capture2('ldd', lib)
46
+ unless status.exitstatus.zero?
47
+ warn("Couldn't run ldd! Status code: #{status}, ignoring…")
48
+ # exit 3
49
+ end
50
+ deps = deps_str.split("\n").collect { |d_str| d_str[%r{(?<==>\s)(/\S+)}] }.compact
51
+ next unless deps.length.positive?
52
+
53
+ deps.each do |dep|
54
+ pkgs = yum_cache[dep].split("\n")
55
+ required_libs << dep if pkgs.length.positive?
56
+ end
57
+ end
58
+
59
+ FileUtils.mkdir_p('/tmp/outputs/lib')
60
+ FileUtils.cp(required_libs.to_a, '/tmp/outputs/lib')
61
+
62
+ # These files are not needed at runtime
63
+ FileUtils.rm_rf(Dir['/tmp/build/bundle/ruby/*/cache'])
64
+ FileUtils.rm_rf(Dir['/tmp/build/bundle/ruby/*/gems/*/test'])
65
+
66
+ # Move outputs into place for zipping up
67
+ FileUtils.mkdir_p('/tmp/outputs/ruby')
68
+ FileUtils.cp_r('/tmp/build/bundle/ruby', '/tmp/outputs/ruby')
69
+ FileUtils.mv('/tmp/outputs/ruby/ruby', '/tmp/outputs/ruby/gems')
70
+ FileUtils.chmod_R(0o755, '/tmp/outputs')
71
+
72
+ warn('Successfully generated gems and dependencies...')
73
+ end
74
+
75
+ main
76
+ true
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JetsGemLayer
4
+ class TaskHelper
5
+ include Rake::DSL
6
+ include Jets::AwsServices
7
+
8
+ # Files used to generate the gem layer
9
+ INPUT_FILES = Rake::FileList.new(
10
+ ['Gemfile', 'Gemfile.lock'].collect { |f| File.join(Jets.root, f) }
11
+ )
12
+ LOCAL_TMP_DIR = 'tmp/jets_gem_layer'
13
+ OUTPUT_DIR = File.expand_path(File.join(Jets.root, "#{LOCAL_TMP_DIR}/"))
14
+
15
+ def self.install
16
+ new.install
17
+ end
18
+
19
+ def self.arn
20
+ @arn ||= new.arn
21
+ end
22
+
23
+ def arn
24
+ # We do not want to do any of this when running in the lambda environment
25
+ # as it is only required for deployment.
26
+ @arn ||= if ENV['LAMBDA_TASK_ROOT']
27
+ 'no-op-while-running-in-lambda'
28
+ else
29
+ published_arn
30
+ end
31
+
32
+ @arn ||= 'no-matching-gem-layer-found'
33
+ end
34
+
35
+ def install
36
+ namespace :gem_layer do
37
+ install_build_and_publish
38
+ install_build
39
+ install_publish
40
+ install_clean
41
+ end
42
+ end
43
+
44
+ def install_build_and_publish
45
+ desc 'Build and publish a gem layer version'
46
+ task :build_and_publish do
47
+ Rake::Task['gem_layer:build'].invoke
48
+ Rake::Task['gem_layer:publish'].invoke
49
+ Rake::Task['gem_layer:clean'].invoke
50
+ end
51
+ end
52
+
53
+ def install_build
54
+ desc 'Build the gem layer zip file'
55
+ task :build do
56
+ Rake::Task['gem_layer:clean'].invoke
57
+ build_layer
58
+ zip_layer
59
+ end
60
+ end
61
+
62
+ def install_publish
63
+ desc 'Publish a built layer zip file'
64
+ task :publish do
65
+ publish_layer
66
+ end
67
+ end
68
+
69
+ def install_clean
70
+ desc 'Clean tmp files'
71
+ task :clean do
72
+ FileUtils.rm_r(working_dir) if File.exist?(working_dir)
73
+ end
74
+ end
75
+
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
80
+ end
81
+
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)
90
+ end
91
+ end
92
+
93
+ def publish_layer
94
+ aws_lambda.publish_layer_version(
95
+ layer_name:, # required
96
+ description: layer_version_description,
97
+ content: { zip_file: File.read(zip_file_path) }
98
+ )
99
+ puts "#{layer_name} published for #{layer_version_description}..."
100
+ end
101
+
102
+ private
103
+
104
+ def input_hash
105
+ @input_hash ||= begin
106
+ hash = Digest::SHA1.hexdigest(INPUT_FILES.existing.collect do |f|
107
+ File.read(f)
108
+ end.join("\x1C"))
109
+ hash[0..7]
110
+ end
111
+ end
112
+
113
+ def inputs_dir
114
+ working_dir('gem_layer_cache')
115
+ end
116
+
117
+ def layer_name
118
+ "#{Jets.project_namespace}-ruby-#{RUBY_VERSION.gsub('.', '_')}-gem_layer"
119
+ end
120
+
121
+ def layer_version_description
122
+ @layer_version_description ||= "Dependency Hash: #{input_hash}"
123
+ end
124
+
125
+ def zip_file_path
126
+ File.join(working_dir, "#{layer_name}.zip")
127
+ end
128
+
129
+ def outputs_dir
130
+ working_dir(layer_name.to_s)
131
+ end
132
+
133
+ def working_dir(path_suffix = '')
134
+ File.expand_path(
135
+ File.join(
136
+ OUTPUT_DIR,
137
+ path_suffix
138
+ )
139
+ )
140
+ end
141
+
142
+ def docker_tag
143
+ (/^\d+\.\d+/.match(RUBY_VERSION)[0]).to_s
144
+ end
145
+
146
+ def docker_run_cmd
147
+ cmd = %W[docker run --rm
148
+ --platform linux/amd64
149
+ -v #{inputs_dir}:/tmp/inputs
150
+ -v #{outputs_dir}:/tmp/outputs
151
+ -v #{File.expand_path("#{__dir__}/build_env")}:/var/task]
152
+
153
+ ENV.fetch('GEM_LAYER_ENV').split(',').each { |env| cmd.push "-e#{env}" } if ENV['GEM_LAYER_ENV']
154
+
155
+ if ENV['GEM_LAYER_PACKAGE_DEPENDENCIES']
156
+ cmd.push "-eGEM_LAYER_PACKAGE_DEPENDENCIES=#{ENV.fetch('GEM_LAYER_PACKAGE_DEPENDENCIES')}"
157
+ end
158
+
159
+ cmd.push(*%W[public.ecr.aws/sam/build-ruby#{docker_tag} ruby build_layer.rb])
160
+ end
161
+
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
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JetsGemLayer
4
+ VERSION = '0.1'
5
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jets'
4
+ require 'digest'
5
+ require 'fileutils'
6
+ require 'rake'
7
+
8
+ require 'jets_gem_layer/task_helper'
9
+
10
+ module JetsGemLayer
11
+ def self.load_tasks
12
+ JetsGemLayer::TaskHelper.install
13
+ end
14
+
15
+ def self.arn
16
+ JetsGemLayer::TaskHelper.arn
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jets_gem_layer
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - DocGo Engineering
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-12-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jets
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: This gem provides Rake tasks to create and publish an AWS Lambda Layer
42
+ from project gems and their linked libraries. Designed for use with Ruby on Jets
43
+ 5.
44
+ email:
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".rubocop.yml"
51
+ - ".rubocop_todo.yml"
52
+ - Gemfile
53
+ - Gemfile.lock
54
+ - LICENSE.txt
55
+ - README.md
56
+ - jets_gem_layer.gemspec
57
+ - lib/jets_gem_layer.rb
58
+ - lib/jets_gem_layer/build_env/build_layer.rb
59
+ - lib/jets_gem_layer/task_helper.rb
60
+ - lib/jets_gem_layer/version.rb
61
+ homepage: https://github.com/ambulnzllc/jets_gem_layer
62
+ licenses:
63
+ - MIT
64
+ metadata:
65
+ rubygems_mfa_required: 'true'
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.2'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubygems_version: 3.5.3
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Rake tasks to automate building a Lambda Layer for Ruby on Jets projects
85
+ test_files: []