puma-redeploy 0.1.1 → 0.2.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: 71217e13019896c5b071db53e1b149ddb34d5dd5cf98eb5cd2da7f189c335f6a
4
- data.tar.gz: 32b87f0dd6e54ca89bc0be6032d60c37fb6e88f6fd58eae15e25cb4bc13aebad
3
+ metadata.gz: 65da7c1d7658a5e9bc5e955e5c3392dce1c9300ae20cfec2220e60f15804fb0b
4
+ data.tar.gz: 984a126a32edbf6289aeda36855d801923ab54f4b959b561eb8b41d1e08bba93
5
5
  SHA512:
6
- metadata.gz: bcf4d8732453d835c898595bff21c84a31d8b1f5b30f5cf9a46f1f6c33d3e5dfdf4fcbcc9416a698caa70acb17b4fa319144e3a8e0f3f85af944e5d914ba1ab8
7
- data.tar.gz: e7bbea1217f1eaa8f1bab4d3d0d4d9a798f477d42a28fe79b682251b8e3dd0f5525e4a63aea3dfec880e20c182060dbc81e4b72c05eea53e539f29bcc84ad6d7
6
+ metadata.gz: 6988a62ccf3b83669e8f4e4e361bc48b062f1df6c7cc704903034dac9385f29c6648faaf04393ac88f9a78fa83301ec6820c74043237baa52d99536987a3ba4f
7
+ data.tar.gz: c962806cc92fe13e2b14aae40cd0d9413b14fb249c3eb72f106686b143217e08e40fb2e49068ea15a1be7893a5248ca79e0c6ef3c86bff5c29ddf026414b2be6
@@ -1,4 +1,4 @@
1
- name: Build and publish gem to github package
1
+ name: Build and Publish Gem
2
2
 
3
3
  on:
4
4
  workflow_dispatch:
data/.gitignore CHANGED
@@ -11,3 +11,5 @@
11
11
  .rspec_status
12
12
  Gemfile.lock
13
13
  .DS_Store
14
+ archive.1.0.0.zip
15
+ watch.me
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7
2
+ TargetRubyVersion: 3.1
3
3
  DisplayCopNames: true
4
4
  SuggestExtensions: false
5
5
  NewCops: enable
@@ -20,3 +20,18 @@ Metrics/MethodLength:
20
20
 
21
21
  RSpec/NestedGroups:
22
22
  Max: 4
23
+
24
+ RSpec/MultipleMemoizedHelpers:
25
+ Max: 12
26
+
27
+ RSpec/ExampleLength:
28
+ Max: 6
29
+
30
+ RSpec/ExpectInHook:
31
+ Enabled: false
32
+
33
+ RSpec/StubbedMock:
34
+ Enabled: false
35
+
36
+ RSpec/MessageSpies:
37
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,12 +1,24 @@
1
1
 
2
2
  # Changelog
3
3
 
4
- ## v0.1.1 (NEXT)
4
+ ## v0.2.x (NEXT)
5
5
 
6
6
  **Features:**
7
7
 
8
- - Your contribution here
8
+ **Fixes and enhancements:**
9
+
10
+ ## v0.2.1
11
+
12
+ **Features:**
13
+
14
+ - Add support for S3 handler
15
+
16
+ **Fixes and enhancements:**
17
+
18
+ - Refactor file handler to use new base handler class
19
+
20
+ ## v0.1.1
9
21
 
10
22
  **Fixes and enhancements:**
11
23
 
12
- - Add CHANGELOG.md
24
+ - Initial File based handler support
data/README.md CHANGED
@@ -6,12 +6,13 @@ Key Points:
6
6
  * Encourages the separation of the build process from deployment
7
7
  * Leverages Puma [phased-restart](https://github.com/puma/puma/blob/master/docs/restart.md#phased-restart) to ensure uptime deploy
8
8
  * Deploys in seconds
9
+ * Plugable handlers to detect redeploy (File, S3, Artifactory, etc..)
9
10
 
10
11
 
11
12
  ![image](https://user-images.githubusercontent.com/121275/219976698-80575b17-17b7-4861-8c10-675f3f615e25.png)
12
13
 
13
14
 
14
- Example application can be found [here](https://github.com/tbeauvais/sinatra-api-base)
15
+ Example application can be found [here](https://github.com/tbeauvais/puma-redeploy-test-app)
15
16
 
16
17
 
17
18
  ## Installation
@@ -40,16 +41,23 @@ plugin :redeploy
40
41
 
41
42
  # specify the redeploy watch file
42
43
  redeploy_watch_file './watch_me'
44
+ # For S3 this must be a S3 URL
45
+ redeploy_watch_file 's3://puma-test-app-archives/watch.me'
43
46
 
44
47
  # Specify the number of seconds between checking watch file. Defaults to 30.
45
48
  redeploy_watch_delay 15
46
49
 
47
50
  ```
48
51
 
49
- The watch file must contain the path to the current archive.
50
- For example:
52
+ The watch file must contain the path to the current archive. This can be a file path or S3 URL.
53
+ For example when using a file:
51
54
  ```
52
- /sinatra_test/pkg/my_application_0.0.1.zip
55
+ /sinatra_test/pkg/test_app_0.0.1.zip
56
+ ```
57
+
58
+ For example when using S3:
59
+ ```
60
+ s3://puma-test-app-archives/test_app_0.0.1.zip
53
61
  ```
54
62
 
55
63
  ## Development
data/bin/load_archive CHANGED
@@ -6,8 +6,8 @@ require 'puma-redeploy'
6
6
  require 'logger'
7
7
 
8
8
  def deploy_archive(app_dir, watch_file, logger)
9
- handler = Puma::Redeploy::DeployerFactory.create(target: app_dir, watch_file: watch_file,
10
- logger: logger)
9
+ handler = Puma::Redeploy::DeployerFactory.create(target: app_dir, watch_file:,
10
+ logger:)
11
11
  handler.deploy(source: handler.archive_file)
12
12
  end
13
13
 
@@ -17,14 +17,10 @@ if ARGV.size != 2
17
17
  logger.error 'You must specify the application directory and watch file'
18
18
  logger.info 'load_archive <app directory> <watch file>'
19
19
  logger.info 'e.g. load_archive /app /build/pkg/watch.me'
20
+ exit(1)
20
21
  end
21
22
 
22
23
  app_dir = ARGV[0]
23
24
  watch_file = ARGV[1]
24
25
 
25
- if File.exist?(watch_file) && Dir.exist?(app_dir)
26
- deploy_archive(app_dir, watch_file, logger)
27
- else
28
- logger.error "watch_file #{watch_file} does not exist" unless File.exist?(watch_file)
29
- logger.error "app_dir #{app_dir} does not exist" unless Dir.exist?(app_dir)
30
- end
26
+ deploy_archive(app_dir, watch_file, logger)
@@ -13,8 +13,8 @@ Puma::Plugin.create do
13
13
  in_background do
14
14
  logger = launcher.options[:redeploy_logger] || Logger.new($stdout)
15
15
  watch_file = launcher.options[:redeploy_watch_file]
16
- handler = Puma::Redeploy::DeployerFactory.create(target: launcher.restart_dir, watch_file: watch_file,
17
- logger: logger)
16
+ handler = Puma::Redeploy::DeployerFactory.create(target: launcher.restart_dir, watch_file:,
17
+ logger:)
18
18
 
19
19
  delay = launcher.options[:redeploy_watch_delay] || 30
20
20
  monitor_loop(handler, delay, launcher, logger)
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Puma
6
+ module Redeploy
7
+ # base redeploy handler
8
+ class BaseHandler
9
+ extend Forwardable
10
+ attr_reader :watch_file
11
+
12
+ def initialize(watch_file:, deployer:, logger:)
13
+ @watch_file = watch_file
14
+ @logger = logger
15
+ @deployer = deployer
16
+ end
17
+
18
+ def needs_redeploy?
19
+ return false unless (mtime = touched_at) != @touched_at
20
+
21
+ @touched_at = mtime
22
+ true
23
+ end
24
+
25
+ def_delegators :@deployer, :deploy
26
+
27
+ private
28
+
29
+ attr_accessor :logger
30
+ end
31
+ end
32
+ end
@@ -2,11 +2,19 @@
2
2
 
3
3
  module Puma
4
4
  module Redeploy
5
- # Creates instance if deployer implementation
5
+ # Creates instance of the redeploy handler based on the watch file location
6
6
  class DeployerFactory
7
7
  def self.create(target:, watch_file:, logger:)
8
- file_deployer = Puma::Redeploy::FileDeployer.new(target: target, logger: logger)
9
- Puma::Redeploy::FileHandler.new(watch_file: watch_file, deployer: file_deployer, logger: logger)
8
+ file_deployer = Puma::Redeploy::ZipDeployer.new(target:, logger:)
9
+ if watch_file.start_with?('s3')
10
+ Puma::Redeploy::S3Handler.new(watch_file:, deployer: file_deployer, logger:, s3_client:)
11
+ else
12
+ Puma::Redeploy::FileHandler.new(watch_file:, deployer: file_deployer, logger:)
13
+ end
14
+ end
15
+
16
+ def self.s3_client
17
+ Aws::S3::Client.new
10
18
  end
11
19
  end
12
20
  end
@@ -5,33 +5,18 @@ require 'forwardable'
5
5
  module Puma
6
6
  module Redeploy
7
7
  # file based redeploy handler
8
- class FileHandler
9
- extend Forwardable
10
- attr_reader :watch_file
11
-
8
+ class FileHandler < BaseHandler
12
9
  def initialize(watch_file:, deployer:, logger:)
13
- @watch_file = watch_file
14
- @logger = logger
10
+ super
15
11
  @touched_at = touched_at
16
- @deployer = deployer
17
- end
18
-
19
- def_delegators :@deployer, :deploy
20
- def needs_redeploy?
21
- return false unless (mtime = touched_at) != @touched_at
22
-
23
- @touched_at = mtime
24
- true
25
12
  end
26
13
 
27
14
  def archive_file
28
- File.read(watch_file)&.strip
15
+ File.read(watch_file).strip
29
16
  end
30
17
 
31
18
  private
32
19
 
33
- attr_accessor :logger
34
-
35
20
  def touched_at
36
21
  if File.exist?(watch_file)
37
22
  File.mtime(watch_file)
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'aws-sdk-s3'
5
+
6
+ module Puma
7
+ module Redeploy
8
+ # S3 based redeploy handler
9
+ class S3Handler < BaseHandler
10
+ attr_reader :bucket_name, :object_key, :s3_client
11
+
12
+ def initialize(watch_file:, deployer:, logger:, s3_client:)
13
+ super(watch_file:, deployer:, logger:)
14
+ @s3_client = s3_client
15
+ @bucket_name, @object_key = s3_object_reference(watch_file)
16
+ @touched_at = touched_at
17
+ end
18
+
19
+ def archive_file
20
+ s3_url = read_watch_object
21
+ archive_bucket_name, archive_object_key = s3_object_reference(s3_url)
22
+
23
+ response = s3_client.get_object(bucket: archive_bucket_name, key: archive_object_key)
24
+
25
+ file_name = local_file_path(archive_object_key)
26
+ # Write the object data to a local file
27
+ File.binwrite(file_name, response.body.read)
28
+ file_name
29
+ end
30
+
31
+ private
32
+
33
+ def s3_object_reference(watch_file)
34
+ s3_uri = URI.parse(watch_file)
35
+ [s3_uri.host, s3_uri.path[1..]]
36
+ end
37
+
38
+ def local_file_path(object_key)
39
+ File.basename(object_key)
40
+ end
41
+
42
+ def read_watch_object
43
+ # Get the object data from S3
44
+ object = s3_client.get_object(bucket: bucket_name, key: object_key)
45
+
46
+ object.body.read.strip
47
+ end
48
+
49
+ def touched_at
50
+ head_object = s3_client.head_object(bucket: bucket_name, key: object_key)
51
+
52
+ if head_object
53
+ head_object.last_modified
54
+ else
55
+ logger.info "The S3 object #{bucket_name}/#{object_key} does not exist"
56
+ 0
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Puma
4
4
  module Redeploy
5
- VERSION = '0.1.1'
5
+ VERSION = '0.2.1'
6
6
  end
7
7
  end
@@ -5,7 +5,7 @@ require 'open3'
5
5
  module Puma
6
6
  module Redeploy
7
7
  # Deploys zip archive
8
- class FileDeployer
8
+ class ZipDeployer
9
9
  def initialize(target:, logger:)
10
10
  @target = target
11
11
  @logger = logger
data/lib/puma_redeploy.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Dir.glob("#{__dir__}/puma/redeploy/**/*.rb").sort.each { |file| require file }
3
+ Dir.glob("#{__dir__}/puma/redeploy/**/*.rb").each { |file| require file }
4
4
 
5
5
  module Puma
6
6
  module Redeploy
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  'will be pulled and the app will be reloaded.'
15
15
  spec.homepage = 'https://github.com/tbeauvais/puma-redeploy'
16
16
  spec.license = 'MIT'
17
- spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
17
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
18
18
 
19
19
  spec.executables = ['load_archive']
20
20
 
@@ -30,6 +30,8 @@ Gem::Specification.new do |spec|
30
30
  spec.bindir = 'bin'
31
31
  spec.require_paths = ['lib']
32
32
 
33
+ spec.add_runtime_dependency 'aws-sdk-s3', '~> 1.120.0'
34
+
33
35
  spec.add_development_dependency 'rake', '~> 13.0.6'
34
36
  spec.add_development_dependency 'rspec', '~> 3.12.0'
35
37
  spec.add_development_dependency 'rubocop', '~> 1.43'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma-redeploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - tbeauvais
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-14 00:00:00.000000000 Z
11
+ date: 2023-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-s3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.120.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.120.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -147,11 +161,13 @@ files:
147
161
  - bin/load_archive
148
162
  - lib/puma-redeploy.rb
149
163
  - lib/puma/plugin/redeploy.rb
164
+ - lib/puma/redeploy/base_handler.rb
150
165
  - lib/puma/redeploy/deployer_factory.rb
151
166
  - lib/puma/redeploy/dsl.rb
152
- - lib/puma/redeploy/file_deployer.rb
153
167
  - lib/puma/redeploy/file_handler.rb
168
+ - lib/puma/redeploy/s3_handler.rb
154
169
  - lib/puma/redeploy/version.rb
170
+ - lib/puma/redeploy/zip_deployer.rb
155
171
  - lib/puma_redeploy.rb
156
172
  - puma-redeploy.gemspec
157
173
  homepage: https://github.com/tbeauvais/puma-redeploy
@@ -170,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
170
186
  requirements:
171
187
  - - ">="
172
188
  - !ruby/object:Gem::Version
173
- version: 2.7.0
189
+ version: 3.1.0
174
190
  required_rubygems_version: !ruby/object:Gem::Requirement
175
191
  requirements:
176
192
  - - ">="