outboxable 0.1.2 → 0.1.3

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: f1d338ac197df1adcd420ef12703e96615086f8cc7a0062b72f11deaaec68666
4
- data.tar.gz: 8af422939a04418b12fdb66701b310d49399ba12c974cbeb7718c91b2975760a
3
+ metadata.gz: 469a8e0dea372c23c827c4bff24fecaed9f4c2921f4d40de8fdbed7225dbd52e
4
+ data.tar.gz: 17bd59884f0a7385ae7557b76192ba08aa81e1cd9441730e71dd1bb426a9f60f
5
5
  SHA512:
6
- metadata.gz: 4fa5c959e651053d21bc817f58e93ed9d5b58badf44abda041308de7b5be2f17a380bf1656095ad5fde6d9e55cf5c54e241b8fb91980ca800570d2d2028ab6f3
7
- data.tar.gz: 90f310a90f39dcebce8ae111aaeec53db9ea056d5e995763a58380e904ad6c17152696af05299db7a087fa55d37f8fe219c141395d12b520fe433f733eb4f279
6
+ metadata.gz: 1419c8437e010866124d4f3bb2edbb126475f4e9c2647f68facbb565dde6c48e2b86eb457716b16fa895d035be0f9954067b30fc79ffeebd8dcebfe275c0fa2e
7
+ data.tar.gz: 747042c4e73e79cf0fc114c003f0c8a3499cfcf705f2fcdf98396d211313163048be1e42d71e5cfc2ea65ce34ccda54958eb485b191bd2957a4ff2f057457263
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  SuggestExtensions: false
6
6
  Layout/SpaceBeforeBrackets: # (new in 1.7)
7
7
  Enabled: true
8
- Layout/LineLength:
8
+ Layout/LineLength:
9
9
  Max: 350
10
10
  Lint/AmbiguousAssignment: # (new in 1.7)
11
11
  Enabled: true
@@ -110,4 +110,8 @@ Metrics/MethodLength:
110
110
  Metrics/CyclomaticComplexity:
111
111
  Max: 15
112
112
  Metrics/PerceivedComplexity:
113
- Max: 15
113
+ Max: 15
114
+ Lint/DuplicateMethods: # Disables duplicate methods warning
115
+ Enabled: false
116
+ Gemspec/RequiredRubyVersion: # Disables required ruby version warning
117
+ Enabled: false
data/Gemfile CHANGED
@@ -1,12 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in outboxable.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
8
+ gem 'rake', '~> 13.0'
9
9
 
10
- gem "rspec", "~> 3.0"
10
+ gem 'rspec', '~> 3.0'
11
+
12
+ gem 'rubocop-rails', '~> 2.18'
13
+
14
+ group :development, :test do
15
+ gem "sidekiq", "~> 7.0", require: true
16
+ gem "sidekiq-cron", "~> 1.10"
17
+ gem "activesupport", "~> 7.0"
18
+ end
11
19
 
12
- gem "rubocop", "~> 1.21"
data/Gemfile.lock CHANGED
@@ -1,27 +1,47 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- outboxable (0.1.2)
4
+ outboxable (0.1.3)
5
5
  bunny (>= 2.19.0)
6
6
  connection_pool (~> 2.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
+ activesupport (7.0.4.3)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
11
16
  amq-protocol (2.3.2)
12
17
  ast (2.4.2)
13
18
  bunny (2.20.3)
14
19
  amq-protocol (~> 2.3, >= 2.3.1)
15
20
  sorted_set (~> 1, >= 1.0.2)
21
+ concurrent-ruby (1.2.2)
16
22
  connection_pool (2.3.0)
17
23
  diff-lcs (1.5.0)
24
+ et-orbi (1.2.7)
25
+ tzinfo
26
+ fugit (1.8.1)
27
+ et-orbi (~> 1, >= 1.2.7)
28
+ raabro (~> 1.4)
29
+ globalid (1.1.0)
30
+ activesupport (>= 5.0)
31
+ i18n (1.12.0)
32
+ concurrent-ruby (~> 1.0)
18
33
  json (2.6.3)
34
+ minitest (5.18.0)
19
35
  parallel (1.22.1)
20
36
  parser (3.2.1.0)
21
37
  ast (~> 2.4.1)
38
+ raabro (1.4.0)
39
+ rack (2.2.6.4)
22
40
  rainbow (3.1.1)
23
41
  rake (13.0.6)
24
42
  rbtree (0.4.6)
43
+ redis-client (0.14.1)
44
+ connection_pool
25
45
  regexp_parser (2.7.0)
26
46
  rexml (3.2.5)
27
47
  rspec (3.12.0)
@@ -37,33 +57,51 @@ GEM
37
57
  diff-lcs (>= 1.2.0, < 2.0)
38
58
  rspec-support (~> 3.12.0)
39
59
  rspec-support (3.12.0)
40
- rubocop (1.45.1)
60
+ rubocop (1.48.0)
41
61
  json (~> 2.3)
42
62
  parallel (~> 1.10)
43
63
  parser (>= 3.2.0.0)
44
64
  rainbow (>= 2.2.2, < 4.0)
45
65
  regexp_parser (>= 1.8, < 3.0)
46
66
  rexml (>= 3.2.5, < 4.0)
47
- rubocop-ast (>= 1.24.1, < 2.0)
67
+ rubocop-ast (>= 1.26.0, < 2.0)
48
68
  ruby-progressbar (~> 1.7)
49
69
  unicode-display_width (>= 2.4.0, < 3.0)
50
- rubocop-ast (1.26.0)
70
+ rubocop-ast (1.27.0)
51
71
  parser (>= 3.2.1.0)
52
- ruby-progressbar (1.11.0)
72
+ rubocop-rails (2.18.0)
73
+ activesupport (>= 4.2.0)
74
+ rack (>= 1.1)
75
+ rubocop (>= 1.33.0, < 2.0)
76
+ ruby-progressbar (1.13.0)
53
77
  set (1.0.3)
78
+ sidekiq (7.0.7)
79
+ concurrent-ruby (< 2)
80
+ connection_pool (>= 2.3.0)
81
+ rack (>= 2.2.4)
82
+ redis-client (>= 0.11.0)
83
+ sidekiq-cron (1.10.0)
84
+ fugit (~> 1.8)
85
+ globalid (>= 1.0.1)
86
+ sidekiq (>= 6)
54
87
  sorted_set (1.0.3)
55
88
  rbtree
56
89
  set (~> 1.0)
90
+ tzinfo (2.0.6)
91
+ concurrent-ruby (~> 1.0)
57
92
  unicode-display_width (2.4.2)
58
93
 
59
94
  PLATFORMS
60
95
  x86_64-linux
61
96
 
62
97
  DEPENDENCIES
98
+ activesupport (~> 7.0)
63
99
  outboxable!
64
100
  rake (~> 13.0)
65
101
  rspec (~> 3.0)
66
- rubocop (~> 1.21)
102
+ rubocop-rails (~> 2.18)
103
+ sidekiq (~> 7.0)
104
+ sidekiq-cron (~> 1.10)
67
105
 
68
106
  BUNDLED WITH
69
107
  2.4.2
data/README.md CHANGED
@@ -6,7 +6,7 @@ Please take into consideration that this Gem is **opinionated**, meaning it expe
6
6
 
7
7
  ### Restrictions
8
8
 
9
- 1. When using RabbitMQ, it only publishes events to a ***topic*** exchange.
9
+ 1. When using RabbitMQ, it only publishes events to a ***topic*** exchange.
10
10
  1. It assumes that you are using routing keys to publish to the topic exchange.
11
11
  1. It publishes events in a background job using [Sidekiq](https://github.com/sidekiq/sidekiq). Therefore, you application must use Sidekiq.
12
12
  1. It implements the [polling publisher pattern](https://microservices.io/patterns/data/polling-publisher.html). For that, it uses [sidekiq-cron](https://github.com/sidekiq-cron/sidekiq-cron) to check the unpublished outboxes every 5 seconds after the initialization of the application.
@@ -25,7 +25,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
25
25
  $ gem install outboxable
26
26
  ```
27
27
 
28
- Then run:
28
+ Then run:
29
29
 
30
30
  ```shell
31
31
  $ rails g outboxable:install
@@ -42,7 +42,7 @@ $ rails db:migrate
42
42
  The installation command above will also add a configuration file to your initializer:
43
43
 
44
44
  ```ruby
45
- # This monkey patch allows you to customize the message format that you publish to your broker.
45
+ # This monkey patch allows you to customize the message format that you publish to your broker.
46
46
  # By default, Outboxable publishes a CloudEvent message to your broker.
47
47
  module Outboxable
48
48
  module RabbitMq
@@ -73,14 +73,14 @@ Outboxable.configure do |config|
73
73
  # RabbitMQ configurations
74
74
  config.rabbitmq_host = ENV.fetch('RABBITMQ__HOST')
75
75
  config.rabbitmq_port = ENV.fetch('RABBITMQ__PORT', 5672)
76
- config.rabbitmq_user = ENV.fetch('RABBITMQ__USER')
76
+ config.rabbitmq_user = ENV.fetch('RABBITMQ__USERNAME')
77
77
  config.rabbitmq_password = ENV.fetch('RABBITMQ__PASSWORD')
78
78
  config.rabbitmq_vhost = ENV.fetch('RABBITMQ__VHOST')
79
79
  config.rabbitmq_event_bus_exchange = ENV.fetch('EVENTBUS__EXCHANGE_NAME')
80
80
  end
81
81
  ```
82
82
 
83
- The monkey patch in the code above is crucial in giving you a way to customize the format of the message that you will publish to the message broker. Be default, it follows the specs of the [Cloud Native Events Specifications v1.0.2](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md).
83
+ The monkey patch in the code above is crucial in giving you a way to customize the format of the message that you will publish to the message broker. Be default, it follows the specs of the [Cloud Native Events Specifications v1.0.2](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md).
84
84
 
85
85
 
86
86
 
@@ -155,7 +155,7 @@ end
155
155
 
156
156
 
157
157
 
158
- The ``outbox_configurations`` method will be called and used by the Outboxable Gem to transactionally create an outbox and publish. In the code above, it will create an outbox when the book is created. For that purpose it will use the routing key ``books.created`` as a convention. It will also publish an event if the book is updated, using the routing key: ``books.published`` since it was specified in the hash.
158
+ The ``outbox_configurations`` method will be called and used by the Outboxable Gem to transactionally create an outbox and publish. In the code above, it will create an outbox when the book is created. For that purpose it will use the routing key ``books.created`` as a convention. It will also publish an event if the book is updated, using the routing key: ``books.published`` since it was specified in the hash.
159
159
 
160
160
 
161
161
 
@@ -196,13 +196,13 @@ Here's the schema of what could be passed to the ``outbox_configurations`` in JS
196
196
 
197
197
 
198
198
 
199
- The ``run_on`` key represents another hash that can have the keys ``create`` and ``update``. If one of these keys are not supplied, the outbox will not be created for the unspecified operation; in other words, if you do not specify the configuration for ``update``, for example, an outbox will NOT be created when the book is updated.
199
+ The ``run_on`` key represents another hash that can have the keys ``create`` and ``update``. If one of these keys are not supplied, the outbox will not be created for the unspecified operation; in other words, if you do not specify the configuration for ``update``, for example, an outbox will NOT be created when the book is updated.
200
200
 
201
201
  Each operation key such as ``create`` and ``update`` can also take a ``condition`` key, which represents a Ruby proc that must return a boolean expression. It can also take a ``routing_key`` option, which specifies that routing key with which the outbox will publish the event to the message broker. If you don't specify the ``routing_key``, it will use the base`s routing key dotted by``created`` for create operation and ``updated`` for update operation.
202
202
 
203
203
 
204
204
 
205
- Last but not least, run sidekiq so that the Outboxable Gem can publish the events to the broker:
205
+ Last but not least, run sidekiq so that the Outboxable Gem can publish the events to the broker:
206
206
 
207
207
  ```shell
208
208
  $ bundle exec sidekiq
data/Rakefile CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- require "rubocop/rake_task"
8
+ require 'rubocop/rake_task'
9
9
 
10
10
  RuboCop::RakeTask.new
11
11
 
@@ -2,7 +2,7 @@ module Outboxable
2
2
  class InstallGenerator < Rails::Generators::Base
3
3
  include Rails::Generators::Migration
4
4
 
5
- source_root File.expand_path('../../../templates', __FILE__)
5
+ source_root File.expand_path('../../templates', __dir__)
6
6
 
7
7
  # Copy initializer into user app
8
8
  def copy_initializer
@@ -11,26 +11,26 @@ module Outboxable
11
11
 
12
12
  # Copy user information (model & Migrations) into user app
13
13
  def create_user_model
14
- target_path = "app/models/outbox.rb"
15
- unless File.exist?(File.join(Rails.root, target_path))
16
- template("outbox.rb", target_path)
14
+ target_path = 'app/models/outbox.rb'
15
+ if Rails.root.join(target_path).exist?
16
+ say_status('skipped', 'Model outbox already exists')
17
17
  else
18
- say_status('skipped', "Model outbox already exists")
18
+ template('outbox.rb', target_path)
19
19
  end
20
20
  end
21
21
 
22
22
  # Copy migrations
23
23
  def copy_migrations
24
- if self.class.migration_exists?('db/migrate', "create_outboxable_outboxes")
25
- say_status('skipped', "Migration create_outboxable_outboxes already exists")
24
+ if self.class.migration_exists?('db/migrate', 'create_outboxable_outboxes')
25
+ say_status('skipped', 'Migration create_outboxable_outboxes already exists')
26
26
  else
27
- migration_template('create_outboxable_outboxes.rb', "db/migrate/create_outboxable_outboxes.rb")
27
+ migration_template('create_outboxable_outboxes.rb', 'db/migrate/create_outboxable_outboxes.rb')
28
28
  end
29
29
  end
30
30
 
31
31
  # Use to assign migration time otherwise generator will error
32
- def self.next_migration_number(dir)
33
- Time.now.utc.strftime("%Y%m%d%H%M%S")
32
+ def self.next_migration_number(_dir)
33
+ Time.now.utc.strftime('%Y%m%d%H%M%S')
34
34
  end
35
35
  end
36
36
  end
@@ -12,7 +12,7 @@ module Outboxable
12
12
  ALLOWED_MESSAGE_BROKERS = %i[rabbitmq].freeze
13
13
  ALLOWED_ORMS = %i[activerecord].freeze
14
14
 
15
- attr_accessor :rabbitmq_host,
15
+ attr_accessor :rabbitmq_host,
16
16
  :rabbitmq_port,
17
17
  :rabbitmq_user,
18
18
  :rabbitmq_password,
@@ -31,7 +31,7 @@ module Outboxable
31
31
  Sidekiq::Options[:cron_poll_interval] = 5
32
32
 
33
33
  # Create the cron job for the polling publisher
34
- Sidekiq::Cron::Job.create(name: 'OutboxablePollingPublisher', cron: '*/5 * * * * *', class: 'Outboxable::PollingPublisherWorker')
34
+ Sidekiq::Cron::Job.create(name: 'OutboxablePollingPublisher', cron: '*/5 * * * * *', class: 'Outboxable::PollingPublisherWorker')
35
35
  end
36
36
 
37
37
  def message_broker=(message_broker)
@@ -4,11 +4,13 @@ module Outboxable
4
4
  sidekiq_options queue: 'critical'
5
5
 
6
6
  def perform
7
- Outbox.pending.find_in_batches(batch_size: 100).each do |batch|
7
+ Outbox.pending.where(last_attempted_at: [..Time.zone.now, nil]).find_in_batches(batch_size: 100).each do |batch|
8
8
  batch.each do |outbox|
9
+ # This is to prevent a job from being retried too many times. Worst-case scenario is 1 minute delay in jobs.
10
+ outbox.update(last_attempted_at: 1.minute.from_now)
9
11
  Outboxable::Worker.perform_async(outbox.id)
10
12
  end
11
13
  end
12
14
  end
13
15
  end
14
- end
16
+ end
@@ -4,34 +4,34 @@ module Outboxable
4
4
  def initialize(resource:)
5
5
  @resource = resource
6
6
  end
7
-
7
+
8
8
  def to_envelope(resource:)
9
9
  # throw not implemented method error
10
- raise NotImplementedError, "Please implement the to_envelope method in your own module"
10
+ raise NotImplementedError, 'Please implement the to_envelope method in your own module'
11
11
  end
12
-
12
+
13
13
  def publish
14
14
  confirmed = nil
15
-
15
+
16
16
  Outboxable::Connection.instance.channel.with do |channel|
17
17
  channel.confirm_select
18
-
18
+
19
19
  # Declare a exchange
20
20
  exchange = channel.topic(@resource.exchange, durable: true)
21
-
21
+
22
22
  # Publish the CloudEvent resource to the exchange
23
23
  exchange.publish(to_envelope(resource: @resource), routing_key: @resource.routing_key, headers: @resource.try(:headers) || {})
24
-
24
+
25
25
  # Wait for confirmation
26
26
  confirmed = channel.wait_for_confirms
27
27
  end
28
-
28
+
29
29
  return unless confirmed
30
-
30
+
31
31
  @resource.reload
32
32
  @resource.increment_attempt
33
33
  @resource.update(status: :published, retry_at: nil)
34
34
  end
35
35
  end
36
36
  end
37
- end
37
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Outboxable
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.3"
5
5
  end
@@ -1,9 +1,11 @@
1
+ require 'sidekiq'
2
+
1
3
  module Outboxable
2
4
  class Worker
3
- include Sidekiq::Job
5
+ include ::Sidekiq::Job
4
6
 
5
7
  def perform(outbox_id)
6
8
  Outboxable::PublishingManager.publish(resource: Outbox.find(outbox_id))
7
9
  end
8
10
  end
9
- end
11
+ end
data/lib/outboxable.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "outboxable/version"
3
+ require_relative 'outboxable/version'
4
4
 
5
5
  require 'outboxable/worker'
6
6
  require 'outboxable/publishing_manager'
@@ -9,10 +9,11 @@ require 'outboxable/connection'
9
9
  require 'outboxable/configuration'
10
10
  require 'outboxable/rabbitmq/publisher'
11
11
 
12
+ require 'active_support/concern'
12
13
 
13
14
  module Outboxable
14
15
  class Error < StandardError; end
15
-
16
+
16
17
  extend ActiveSupport::Concern
17
18
 
18
19
  included do
@@ -21,7 +22,7 @@ module Outboxable
21
22
 
22
23
  has_many :outboxes, as: :outboxable, autosave: false
23
24
 
24
- def instantiate_outbox(routing_key: )
25
+ def instantiate_outbox(routing_key:)
25
26
  outboxes.new(
26
27
  routing_key:,
27
28
  exchange: Outboxable.configuration.rabbitmq_event_bus_exchange,
@@ -17,7 +17,7 @@ class CreateOutboxableOutboxes < ActiveRecord::Migration[7.0]
17
17
 
18
18
  t.integer :size, null: false, default: 0
19
19
 
20
- t.references :outboxable, polymorphic: true, null: true
20
+ t.references :outboxable, polymorphic: true, null: true
21
21
 
22
22
  t.timestamps
23
23
  end
@@ -1,4 +1,4 @@
1
- # This monkey patch allows you to customize the message format that you publish to your broker.
1
+ # This monkey patch allows you to customize the message format that you publish to your broker.
2
2
  # By default, Outboxable publishes a CloudEvent message to your broker.
3
3
  module Outboxable
4
4
  module RabbitMq
@@ -29,7 +29,7 @@ Outboxable.configure do |config|
29
29
  # RabbitMQ configurations
30
30
  config.rabbitmq_host = ENV.fetch('RABBITMQ__HOST')
31
31
  config.rabbitmq_port = ENV.fetch('RABBITMQ__PORT', 5672)
32
- config.rabbitmq_user = ENV.fetch('RABBITMQ__USER')
32
+ config.rabbitmq_user = ENV.fetch('RABBITMQ__USERNAME')
33
33
  config.rabbitmq_password = ENV.fetch('RABBITMQ__PASSWORD')
34
34
  config.rabbitmq_vhost = ENV.fetch('RABBITMQ__VHOST')
35
35
  config.rabbitmq_event_bus_exchange = ENV.fetch('EVENTBUS__EXCHANGE_NAME')
@@ -2,9 +2,9 @@ class Outbox < ApplicationRecord
2
2
  attribute :allow_publish, :boolean, default: true
3
3
 
4
4
  # Callbacks
5
- after_commit :publish, if: :allow_publish?
5
+ before_create :set_last_attempted_at
6
6
  before_save :check_publishing
7
-
7
+ after_commit :publish, if: :allow_publish?
8
8
  # Enums
9
9
  enum status: { pending: 0, published: 1, failed: 2 }
10
10
  enum size: { single: 0, batch: 1 }
@@ -17,8 +17,7 @@ class Outbox < ApplicationRecord
17
17
  # Associations
18
18
  belongs_to :outboxable, polymorphic: true, optional: true
19
19
 
20
- def increment_attempt
21
- self.attempts = attempts + 1
20
+ def set_last_attempted_at
22
21
  self.last_attempted_at = Time.zone.now
23
22
  end
24
23
 
@@ -29,4 +28,4 @@ class Outbox < ApplicationRecord
29
28
  def check_publishing
30
29
  self.allow_publish = false if published?
31
30
  end
32
- end
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: outboxable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brusk Awat
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-12 00:00:00.000000000 Z
11
+ date: 2023-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -68,14 +68,15 @@ files:
68
68
  - lib/templates/initializer.rb
69
69
  - lib/templates/outbox.rb
70
70
  - sig/outboxable.rbs
71
- homepage: https://githuh.com/broosk1993/outboxable
71
+ homepage: https://github.com/broosk1993/outboxable
72
72
  licenses:
73
73
  - MIT
74
74
  metadata:
75
75
  allowed_push_host: https://rubygems.org
76
- homepage_uri: https://githuh.com/broosk1993/outboxable
77
- source_code_uri: https://githuh.com/broosk1993/outboxable
78
- changelog_uri: https://githuh.com/broosk1993/outboxable/CHANGELOG.md
76
+ homepage_uri: https://github.com/broosk1993/outboxable
77
+ source_code_uri: https://github.com/broosk1993/outboxable
78
+ changelog_uri: https://github.com/broosk1993/outboxable/blob/main/CHANGELOG.md
79
+ rubygems_mfa_required: 'true'
79
80
  post_install_message:
80
81
  rdoc_options: []
81
82
  require_paths:
@@ -84,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
85
  requirements:
85
86
  - - ">="
86
87
  - !ruby/object:Gem::Version
87
- version: 2.6.0
88
+ version: 3.1.2
88
89
  required_rubygems_version: !ruby/object:Gem::Requirement
89
90
  requirements:
90
91
  - - ">="