patches 3.6.2 → 3.7.0

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: 3ef48f4cd04fd29602ab012fab6414c16cece6fa3ecd687f9deac3ff9244bf7b
4
- data.tar.gz: f89c55aa18e9f84e77e5a26872896df6b5b0819842e940976b262a5b20e55dda
3
+ metadata.gz: 895215b6ac8fa6eb09aea79add6efebcead371d5b50579d983b70eff79c58682
4
+ data.tar.gz: aa05b38f701c0c525364d16f0f22dc7fde9b33c2a34aac240751e78b02d1c3d6
5
5
  SHA512:
6
- metadata.gz: 5899f3e9202d2227efd661d38771eef7534ac48414903b1fbd66820631ccf8dd90dcb20b2bc9f8bfbca81375388fe531acacab6dc294c92a621804083fd0b93b
7
- data.tar.gz: 59707c3bb9d64ad45971fa7ef2287c346aa72fe6bcb393ed027ddd47ca6202feff2034b5ec30c1a32e5d39041ba4fe2bb2d1ee6ca625aabc58d87978f7e9e7c6
6
+ metadata.gz: e454bd2d14b1cf02eca6fc4bd18d3732c83627032c0a6a2fb76dbf6c43d07da7ee6786f542c8f689290b75deedc48ea8fb1b8eeb0581363fd48e9719a3478e38
7
+ data.tar.gz: a286831eb61b05d4fbdee99989247671307d3881433e293eacda3afc533b262d0d82d1cb6e098a0c3f4153b01891bd0e4ecece47f235ed36d09715ebb81e3c64
data/CHANGELOG.md CHANGED
@@ -6,6 +6,127 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.7.0] - 2026-09-10
10
+
11
+ Declares dependencies the gem always relied on, and announces what 4.0 is
12
+ expected to require. No public API changes and no version constraint moves, so
13
+ anything that installed 3.6.x installs this.
14
+
15
+ ### Added
16
+ - Gem metadata (`source_code_uri`, `changelog_uri`, `bug_tracker_uri`,
17
+ `documentation_uri`). None were declared, so rubygems.org kept showing values
18
+ carried over from older releases - 3.6.3 still lists `source_code_uri` as
19
+ `http://github.com/jobready/patches`, from before the org was renamed
20
+ - `activerecord` as an explicit runtime dependency, at the same `>= 3.2` floor
21
+ as `railties` so nothing currently installable is excluded. `Patches::Patch`
22
+ subclasses `ActiveRecord::Base` and `Patches::Base#execute` calls
23
+ `ActiveRecord::Base.connection`, but only `railties` had been declared
24
+ - `Patches.deprecator`, a gem-owned `ActiveSupport::Deprecation` instance rather
25
+ than the singleton Rails 7.1 deprecated and 8.0 removed. Host applications can
26
+ silence or redirect it with `Patches.deprecator.behavior = :silence`
27
+ - A deprecation warning when `config.use_slack` is set: from 4.0 Patches will
28
+ not depend on `slack-notifier`, so only applications using Slack carry it.
29
+ Add `gem 'slack-notifier'` to your Gemfile to keep notifications working
30
+ - A deprecation warning on `require 'patches/capistrano'`. The Capistrano task
31
+ is removed in 4.0; invoke `rake patches:run` from your deployment process
32
+ instead. It remains opt-in and loads nothing unless a Capfile requires it
33
+ - Deprecation warnings for the two other things 4.0 is expected to require:
34
+ Sidekiq 6.3 or newer, which is where `Sidekiq::Job` arrives, and Ruby 3.2 /
35
+ Rails 7.2. Those floors are higher than the range CI verifies - Ruby 3.0 and
36
+ Rails 7.1 still pass - so anyone below them hears about it a release ahead.
37
+ The Ruby and Rails notice runs from a Rails initializer, after the
38
+ application's own, so `Patches.deprecator.behavior` can silence it
39
+
40
+ ### Changed
41
+ - The published gem carries only what a consumer needs - 27 files rather than
42
+ 42. `Dockerfile`, `docker-compose.yml`, `.devcontainer/`, `.github/`, `bin/`,
43
+ `Rakefile`, `RELEASING.md` and a decorative image were being packaged. `lib`,
44
+ the install migration, `docs/usage.md` and the top-level docs remain
45
+ - The development container works again. It was pinned to `ruby:2.3`, which
46
+ cannot satisfy the current Gemfile, and had not been touched since 2018. The
47
+ Ruby version is now a build argument and the gem versions are passed through
48
+ from the shell, so any cell of the matrix in README.md is reproducible in it.
49
+ A `.devcontainer/` referencing the same compose service comes with it, for
50
+ VS Code and Codespaces
51
+
52
+ ### Removed
53
+ - `.github/workflows/publish.yml`. It published on `release: published` using a
54
+ `GEM_HOST_API_KEY`, had never run in the four years since it was added, and
55
+ would now attempt a duplicate push if a GitHub Release were created after a
56
+ tag. Releases come from `.github/workflows/release.yml` - see
57
+ [RELEASING.md](RELEASING.md)
58
+
59
+ ## [3.6.3] - 2026-09-09
60
+
61
+ Bug fixes only. No version constraint changes, no API changes and nothing
62
+ removed from the public interface, so anything that installed 3.6.2 installs
63
+ this. First step of a staged modernisation: declaring dependencies and adding
64
+ deprecations comes in 3.7.0, raising minimums in 4.0.0.
65
+
66
+ ### Fixed
67
+ - Sidekiq 7 and 8 compatibility. Strict argument checking, enabled by default
68
+ from Sidekiq 7, rejected the job arguments the workers enqueued:
69
+ `patches:run` passed the runner class object itself and `application_version`
70
+ used a symbol key, so enqueueing raised `ArgumentError: Job arguments to
71
+ Patches::Worker must be native JSON types`. The task now enqueues the runner
72
+ class name and the key is a string. The serialised payload is byte-identical
73
+ to 3.6.2's - the class already reached Redis as `"Patches::Runner"` and the
74
+ symbol key as `"application_version"` - so in-flight jobs and rolling deploys
75
+ that mix old and new workers are unaffected
76
+ - The install migration inherited from a bare `ActiveRecord::Migration`, which
77
+ Rails has refused since 5.0 with "Directly inheriting from
78
+ ActiveRecord::Migration is not supported", so
79
+ `rake patches:install:migrations && rake db:migrate` failed on every Rails
80
+ since. It now declares `ActiveRecord::Migration[5.0]`, which Rails still
81
+ supports through 8.1, so no minimum moves
82
+ - `Patches.default_path` guarded on `defined?(:Rails)`, which tests a symbol
83
+ literal and is always true; outside Rails it raised `NameError` instead of
84
+ returning nil
85
+
86
+ ### Added
87
+ - Specs for the install migration, which shipped with no coverage at all, and
88
+ for `Patches.sidekiq_job_module`, including its `Sidekiq::Worker` fallback
89
+ - A release workflow and `RELEASING.md`, both matching rdytech/superset-client:
90
+ pushing a `v`-prefixed tag publishes to RubyGems through trusted publishing,
91
+ and a tag not reachable from `develop` is refused. It also waits for the
92
+ version to appear on RubyGems, so a release that does not land fails loudly -
93
+ `3.6.1` was tagged and released on GitHub but never published, and nothing
94
+ reported it
95
+ - CI now runs 17 Ruby/Rails combinations (Ruby 3.0-4.0 against Rails 7.1-8.1)
96
+ in place of a single Ruby 2.7 cell, plus a leg for each Sidekiq state:
97
+ absent, 6.5, and 7.x/8.x with strict arguments both on and off. Ruby 2.7 and
98
+ Rails 6.1/7.0 are not exercised, being well past upstream support; they are
99
+ untested rather than blocked, since no constraint changed. README.md records
100
+ the verified range and how to check an older combination locally
101
+
102
+ ### Changed
103
+ - The workers resolve their mixin through `Patches.sidekiq_job_module`, which
104
+ prefers `Sidekiq::Job` (Sidekiq 6.3+) and falls back to `Sidekiq::Worker`, so
105
+ no Sidekiq version loses support
106
+ - Development dependencies pruned to those actually used: `capybara`,
107
+ `factory_girl`, `timecop`, `generator_spec`, `byebug` and `database_cleaner`
108
+ were referenced by no spec, and `rspec-rails` was never required, so plain
109
+ `rspec` replaces it. `rails`, `sqlite3`, `sidekiq` and `concurrent-ruby` moved
110
+ to the Gemfile so CI can vary them; the stale `sidekiq ~> 3.4.1` pin is what
111
+ hid the strict argument incompatibility, and it also held `json` at `~> 1.0`
112
+ - Sidekiq-dependent specs moved under `spec/sidekiq/` so the suite runs with the
113
+ gem absent
114
+
115
+ ### Known issues
116
+ - The install migration now declares `ActiveRecord::Migration[5.0]`, and
117
+ `ActiveRecord::Migration.[]` does not exist before Rails 5.0. A *fresh*
118
+ install on Rails 4.2 or earlier therefore needs `patches_patches` created by
119
+ hand - the table it wants is a `path` string, timestamps, and a unique index
120
+ on `path`. Existing installs are unaffected, having already copied the
121
+ migration into the host application. Those versions are far outside the range
122
+ CI verifies, and the previous file could not be loaded by any Rails from 5.0
123
+ on, so this trades an impossible install for an unlikely one
124
+
125
+ ### Removed
126
+ - `lib/generators/patches.rb`, a dead duplicate of the patch generator that
127
+ wrote to `app/db/` from a template (`patch.erb`) that does not exist. Not
128
+ reachable through Rails' generator lookup, so not part of the public interface
129
+
9
130
  ## [3.6.2] - 2022-08-10
10
131
 
11
132
  Fixes incorrect release - tag and published gem back in sync
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 JobReady
1
+ Copyright (c) 2015 ReadyTech
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,52 +1,216 @@
1
1
  # Patches
2
- [![Build status](https://badge.buildkite.com/4f3df3f3458bcc933dc44cab6c136af5c3bbdd9f761f1a99ff.svg)](https://buildkite.com/jobready/patches)
3
- [![Maintainability](https://api.codeclimate.com/v1/badges/39d142050017ffeb2564/maintainability)](https://codeclimate.com/repos/557f93b76956807f81000001/maintainability)
4
- [![Test Coverage](https://api.codeclimate.com/v1/badges/39d142050017ffeb2564/test_coverage)](https://codeclimate.com/repos/557f93b76956807f81000001/test_coverage)
2
+ [![Run specs](https://github.com/rdytech/patches/actions/workflows/specs.yml/badge.svg)](https://github.com/rdytech/patches/actions/workflows/specs.yml)
5
3
  [![Gem Version](https://badge.fury.io/rb/patches.svg)](https://badge.fury.io/rb/patches)
6
4
 
7
5
  ![patches](docs/patches.jpg)
8
6
 
7
+ A simple gem for one off tasks - the things that do not belong in a schema
8
+ migration. Back-filling a column, correcting bad data, kicking off a one-time
9
+ import: write it as a class, deploy it, and Patches runs it once and records
10
+ that it ran.
9
11
 
10
- A simple gem for one off tasks
12
+ ## Installation
11
13
 
12
- ## Version 2.0
14
+ Add the gem to your application's Gemfile:
13
15
 
14
- Please note the breaking change release around deployment. See [docs/usage.md](docs/usage.md) for the full change.
16
+ ```ruby
17
+ gem 'patches'
18
+ ```
15
19
 
16
- TL;DR You need to manually declare the patches task to run in your deploy.rb
20
+ Then install the migration that records which patches have run:
17
21
 
18
- ## Installation
22
+ ```
23
+ bundle exec rake patches:install:migrations
24
+ bundle exec rake db:migrate
25
+ ```
26
+
27
+ ## Usage
19
28
 
20
- Add this line to your application's Gemfile:
29
+ Generate a patch:
30
+
31
+ ```
32
+ bundle exec rails g patches:patch PreferenceUpdate
33
+ ```
34
+
35
+ Fill in `run`:
21
36
 
22
37
  ```ruby
23
- gem 'patches'
38
+ class PreferenceUpdate < Patches::Base
39
+ def run
40
+ User.where(preference: nil).update_all(preference: 'default')
41
+ end
42
+ end
24
43
  ```
25
- And then execute:
26
44
 
27
- $ bundle
45
+ Run the pending ones - each patch runs once, and is recorded in
46
+ `patches_patches`:
28
47
 
29
- Or install it yourself as:
48
+ ```
49
+ bundle exec rake patches:run
50
+ ```
30
51
 
31
- $ gem install patches
52
+ `rake patches:pending` lists what has not run yet. Patches can run inline or in
53
+ the background via Sidekiq, across all tenants when you use Apartment, and
54
+ report to Slack. See [docs/usage.md](docs/usage.md) for configuration, tenants,
55
+ deployment and the Capistrano task.
32
56
 
33
- ## Usage
57
+ ## Compatibility
58
+
59
+ This release changes no version constraint: the gemspec still requires only
60
+ `railties >= 3.2` and sets no Ruby floor, so anything that installed 3.6.2
61
+ installs 3.6.3. The table is what CI verifies, which is narrower than what the
62
+ gem permits - older Ruby and Rails are untested here, not blocked.
63
+
64
+ | | Rails 7.1 | Rails 7.2 | Rails 8.0 | Rails 8.1 |
65
+ |---|---|---|---|---|
66
+ | **Ruby 3.0** | ✅ | | | |
67
+ | **Ruby 3.1** | ✅ | ✅ | | |
68
+ | **Ruby 3.2** | ✅ | ✅ | ✅ | ✅ |
69
+ | **Ruby 3.3** | ✅ | ✅ | ✅ | ✅ |
70
+ | **Ruby 3.4** | | ✅ | ✅ | ✅ |
71
+ | **Ruby 4.0** | | ✅ | ✅ | ✅ |
72
+
73
+ A blank cell is a pairing Rails itself does not support. Ruby 2.7 and Rails
74
+ 6.1/7.0 are deliberately not exercised - they are well past upstream support -
75
+ though the gem still installs and, as of this release, passes on them.
76
+
77
+ Ruby 4.0 is newer than all of these Rails releases, so those cells record that
78
+ Patches is verified on it, not that Rails claims support for it.
79
+
80
+ ### Sidekiq
81
+
82
+ Sidekiq is an **optional** integration, not a runtime dependency: Patches runs
83
+ each patch inline when Sidekiq is absent. Set `config.use_sidekiq = true` to run
84
+ them in the background - see [docs/usage.md](docs/usage.md).
85
+
86
+ The workers resolve their mixin at load time via `Patches.sidekiq_job_module`,
87
+ preferring `Sidekiq::Job` (the name Sidekiq has used since 6.3) and falling back
88
+ to `Sidekiq::Worker`, so older Sidekiq keeps working. CI covers each state a
89
+ consumer can be in:
90
+
91
+ | State | Covered by |
92
+ |---|---|
93
+ | Sidekiq not installed | A leg omitting the gem entirely, exercising the `defined?(Sidekiq)` guards |
94
+ | Installed, strict arguments on | Sidekiq 7.x and 8.x at their default (`:raise`) |
95
+ | Installed, strict arguments off | Sidekiq 7.x and 8.x with `Sidekiq.strict_args!(false)` |
96
+ | Older Sidekiq | A 6.5 leg, plus a spec covering the `Sidekiq::Worker` fallback |
97
+
98
+ ### Running one combination locally
99
+
100
+ The Gemfile reads the same variables CI sets, so any cell above is reproducible.
101
+ Bundler re-evaluates the Gemfile on every invocation, so **export** them rather
102
+ than prefixing a single command — otherwise `bundle exec` silently resolves the
103
+ defaults and you test something other than what you intended:
104
+
105
+ ```
106
+ export RAILS_VERSION="~> 8.0.0"
107
+
108
+ bundle install
109
+ bundle exec rspec
110
+ ```
111
+
112
+ Without Sidekiq at all, which is what a consumer that does not use it gets:
113
+
114
+ ```
115
+ export SIDEKIQ_VERSION=none
116
+
117
+ bundle install
118
+ bundle exec rspec --exclude-pattern "sidekiq/**/*_spec.rb"
119
+ ```
34
120
 
35
- see [docs/usage.md](docs/usage.md)
121
+ With Sidekiq 7 and strict argument checking turned off:
122
+
123
+ ```
124
+ export SIDEKIQ_VERSION="~> 7.0" SIDEKIQ_STRICT_ARGS=false
125
+
126
+ bundle install
127
+ bundle exec rspec
128
+ ```
129
+
130
+ Rails 6.1 and 7.0 need two extra pins if you do want to check them, neither
131
+ caused by Patches — Rails <= 7.0 pins its sqlite3 adapter to `~> 1.4`, and Rails
132
+ < 7.1 predates `concurrent-ruby` 1.3.5 removing a `Logger` constant it relies
133
+ on:
134
+
135
+ ```
136
+ export RAILS_VERSION="~> 6.1.0" \
137
+ SQLITE3_VERSION="~> 1.4" \
138
+ CONCURRENT_RUBY_VERSION="< 1.3.5"
139
+
140
+ bundle install
141
+ bundle exec rspec
142
+ ```
143
+
144
+ `unset` the variables (or use a fresh shell) before running the default
145
+ combination again, and delete `test.db` when switching between them: the suite
146
+ creates `patches_patches` only when it is missing, so a database left by an
147
+ earlier run can mask ordering problems.
148
+
149
+ ## Deprecations
150
+
151
+ 3.7.0 introduces no breaking changes. It announces what 4.0 is expected to
152
+ require, so the upgrade is uneventful. Each warning names its replacement and
153
+ goes through the gem's own deprecator, which a host application can silence or
154
+ redirect:
155
+
156
+ ```ruby
157
+ Patches.deprecator.behavior = :silence # or :raise, :log, a lambda...
158
+ ```
159
+
160
+ | Deprecated | Replacement |
161
+ |---|---|
162
+ | Relying on Patches to install `slack-notifier` | Add `gem 'slack-notifier'` to your Gemfile if you use `config.use_slack`. From 4.0 only applications that want it carry it |
163
+ | `require 'patches/capistrano'` | Invoke `rake patches:run` from your deployment process. The Capistrano task is removed in 4.0 |
164
+ | Sidekiq older than 6.3 | Any supported Sidekiq (7.x or 8.x). 4.0 is expected to include `Sidekiq::Job` directly instead of falling back to `Sidekiq::Worker` |
165
+ | Ruby older than 3.2, Rails older than 7.2 | Ruby 3.2+ and Rails 7.2+. 4.0 is expected to raise the gemspec floors to these, which are higher than the range CI verifies today |
166
+
167
+ Nothing is removed in this release, and the gemspec floors are unchanged, so
168
+ anything that installed 3.6.x installs 3.7.0.
36
169
 
37
170
  ## Development
38
171
 
172
+ In VS Code or Codespaces, open the repository in the dev container - it reuses
173
+ the `app` service from `docker-compose.yml`, so there is one definition of the
174
+ environment rather than two. Otherwise, from a shell:
175
+
176
+ ```
177
+ docker compose build
178
+ docker compose run --rm app
179
+ ```
180
+
181
+ The container's default command runs the specs. Any cell of the matrix above is
182
+ reproducible in it: the Ruby version is a build argument, and the gem versions
183
+ are passed through from your shell. The image is built with the default
184
+ versions, so a non-default cell has to install them first:
185
+
39
186
  ```
40
- docker-compose build
41
- docker-compose run app bundle exec rspec
187
+ docker compose build --build-arg RUBY_VERSION=3.1
188
+
189
+ RAILS_VERSION="~> 7.1.0" docker compose run --rm app \
190
+ sh -c 'bundle install && bundle exec rspec'
191
+
192
+ SIDEKIQ_VERSION=none docker compose run --rm app \
193
+ sh -c 'bundle install && bundle exec rspec --exclude-pattern "sidekiq/**/*_spec.rb"'
194
+ ```
195
+
196
+ Or without Docker, if you have the Ruby you want on your path:
197
+
198
+ ```
199
+ bundle install
200
+ bundle exec rspec
42
201
  ```
43
202
 
44
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org/gems/patches).
203
+ To install this gem onto your local machine, run `bundle exec rake install`.
204
+
205
+ ## Releasing
206
+
207
+ Releases are published by GitHub Actions from a `vX.Y.Z` tag — see
208
+ [RELEASING.md](RELEASING.md).
45
209
 
46
210
  ## Contributing
47
211
 
48
- 1. Fork it ( https://github.com/jobready/patches/fork )
212
+ 1. Fork it ( https://github.com/rdytech/patches/fork )
49
213
  2. Create your feature branch (`git checkout -b feature/my-feature-name`)
50
214
  3. Commit your changes (`git commit -am 'Add some feature'`)
51
215
  4. Push to the branch (`git push origin feature/my-new-feature`)
52
- 5. Create a new Pull Request
216
+ 5. Create a new Pull Request against `develop`
@@ -1,4 +1,4 @@
1
- class CreatePatch < ActiveRecord::Migration
1
+ class CreatePatch < ActiveRecord::Migration[5.0]
2
2
  def change
3
3
  create_table :patches_patches do |t|
4
4
  t.string :path, null: false
data/docs/usage.md CHANGED
@@ -22,6 +22,10 @@ bundle exec rake db:migrate
22
22
 
23
23
  ## Configuration
24
24
 
25
+ > **Note.** From 4.0 Patches will not depend on `slack-notifier`, so only
26
+ > applications using Slack carry it. If you set `config.use_slack`, add
27
+ > `gem 'slack-notifier'` to your Gemfile.
28
+
25
29
  If you would like to run the patches asynchronously, or would like them to notify
26
30
  your Slack channel when they fail or succeed, you need to set up
27
31
  an initializer to set those options.
@@ -113,6 +117,11 @@ bundle exec rake patches:run
113
117
 
114
118
  Patches will only ever run once, patches will run in order of creation date.
115
119
 
120
+ ### Capistrano
121
+
122
+ > **Deprecated.** `patches/capistrano` is removed in 4.0. Invoke
123
+ > `rake patches:run` from your deployment process instead.
124
+
116
125
  To run patches on deployment using Capistrano, edit your Capfile and add
117
126
 
118
127
  ```ruby
@@ -1 +1,5 @@
1
+ require 'patches/deprecation'
2
+
3
+ Patches.warn_capistrano_support_removed_in_4_0
4
+
1
5
  load File.expand_path("capistrano/tasks.rake", File.dirname(__FILE__))
@@ -1,3 +1,5 @@
1
+ require 'patches/deprecation'
2
+
1
3
  module Patches
2
4
  class Config
3
5
  class << self
@@ -30,6 +32,18 @@ module Patches
30
32
  @sidekiq_queue = 'default'
31
33
  end
32
34
 
35
+ # Warns only for applications that enable Slack, and only the first time
36
+ # - an initializer that reloads, or configures twice, should not repeat
37
+ # the notice.
38
+ def use_slack=(enabled)
39
+ if enabled && !@warned_about_slack_notifier
40
+ @warned_about_slack_notifier = true
41
+ Patches.warn_slack_notifier_dependency_removed_in_4_0
42
+ end
43
+
44
+ @use_slack = enabled
45
+ end
46
+
33
47
  def sidekiq_options
34
48
  @sidekiq_options ||= { retry: false, queue: sidekiq_queue }
35
49
  end
@@ -0,0 +1,48 @@
1
+ require 'active_support/deprecation'
2
+
3
+ module Patches
4
+ # A gem-owned deprecator rather than ActiveSupport::Deprecation's singleton,
5
+ # which Rails 7.1 deprecated and 8.0 removed. Host applications can silence or
6
+ # redirect it: Patches.deprecator.behavior = :silence.
7
+ def self.deprecator
8
+ @deprecator ||= ActiveSupport::Deprecation.new('4.0', 'patches')
9
+ end
10
+
11
+ # The floors 4.0 is expected to set. Deliberately higher than what CI verifies
12
+ # today - Ruby 3.0 and Rails 7.1 still pass - so consumers on those versions
13
+ # hear about it a release ahead rather than at upgrade time.
14
+ MINIMUM_RUBY_IN_4_0 = '3.2'.freeze
15
+ MINIMUM_RAILS_IN_4_0 = '7.2'.freeze
16
+
17
+ def self.warn_slack_notifier_dependency_removed_in_4_0
18
+ deprecator.warn(
19
+ 'patches will stop depending on slack-notifier in 4.0, so that only ' \
20
+ "applications using Slack carry it. Add gem 'slack-notifier' to your " \
21
+ 'Gemfile to keep notifications working.'
22
+ )
23
+ end
24
+
25
+ def self.warn_capistrano_support_removed_in_4_0
26
+ deprecator.warn(
27
+ 'patches/capistrano is deprecated and will be removed in 4.0. Invoke ' \
28
+ '`rake patches:run` from your deployment process instead.'
29
+ )
30
+ end
31
+
32
+ def self.warn_about_versions_dropped_in_4_0
33
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new(MINIMUM_RUBY_IN_4_0)
34
+ deprecator.warn(
35
+ "Ruby #{RUBY_VERSION} will not be supported by patches 4.0, which is " \
36
+ "expected to require Ruby >= #{MINIMUM_RUBY_IN_4_0}."
37
+ )
38
+ end
39
+
40
+ return unless defined?(::Rails::VERSION::STRING)
41
+ return if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new(MINIMUM_RAILS_IN_4_0)
42
+
43
+ deprecator.warn(
44
+ "Rails #{::Rails::VERSION::STRING} will not be supported by patches 4.0, " \
45
+ "which is expected to require Rails >= #{MINIMUM_RAILS_IN_4_0}."
46
+ )
47
+ end
48
+ end
@@ -3,5 +3,14 @@ require 'rails/engine'
3
3
  module Patches
4
4
  class Engine < Rails::Engine
5
5
  isolate_namespace Patches
6
+
7
+ # After the application's own initializers, so that a host which sets
8
+ # Patches.deprecator.behavior in config/initializers can actually silence
9
+ # this. Warning at require time - which happens during Bundler.require,
10
+ # before any initializer - meant the documented mechanism could not work.
11
+ # It also means Rails::VERSION is always loaded by the time we look.
12
+ initializer 'patches.version_deprecations', after: :load_config_initializers do
13
+ Patches.warn_about_versions_dropped_in_4_0
14
+ end
6
15
  end
7
16
  end
@@ -0,0 +1,18 @@
1
+ require 'sidekiq'
2
+ require 'patches/deprecation'
3
+
4
+ module Patches
5
+ # Sidekiq renamed Sidekiq::Worker to Sidekiq::Job in 6.3 and still ships the
6
+ # old name as a deprecated alias. Resolving it at include time keeps the
7
+ # workers working on every Sidekiq this gem has ever supported, so the change
8
+ # needs no version bump from consumers.
9
+ def self.sidekiq_job_module
10
+ return ::Sidekiq::Job if defined?(::Sidekiq::Job)
11
+
12
+ deprecator.warn(
13
+ 'Sidekiq older than 6.3 does not provide Sidekiq::Job; patches 4.0 is ' \
14
+ 'expected to require it. Upgrade Sidekiq, which supports 7.x and 8.x.'
15
+ )
16
+ ::Sidekiq::Worker
17
+ end
18
+ end
@@ -13,8 +13,10 @@ class Patches::TenantRunner
13
13
  if parallel?
14
14
  Patches::TenantWorker.perform_async(
15
15
  tenant,
16
- path,
17
- application_version: Patches::Config.configuration.application_version
16
+ # Sidekiq 7+ rejects anything that is not a native JSON type, and a
17
+ # path is commonly a Pathname (Patches.default_path returns one).
18
+ path && path.to_s,
19
+ 'application_version' => Patches::Config.configuration.application_version
18
20
  )
19
21
  else
20
22
  run(tenant, path)
@@ -1,13 +1,15 @@
1
- require 'sidekiq'
1
+ require 'active_support/core_ext/hash/keys'
2
+ require 'patches/sidekiq_job'
2
3
 
3
4
  class Patches::TenantWorker
4
- include Sidekiq::Worker
5
+ include Patches.sidekiq_job_module
5
6
  include Patches::TenantRunConcern
6
7
  include Patches::ApplicationVersionValidation
7
8
 
8
9
  sidekiq_options Patches::Config.configuration.sidekiq_options
9
10
 
10
11
  def perform(tenant_name, path, params = {})
12
+ params = (params || {}).stringify_keys
11
13
  if valid_application_version?(params['application_version'])
12
14
  run(tenant_name, path)
13
15
  else
@@ -1,6 +1,6 @@
1
1
  module Patches
2
2
  MAJOR = 3
3
- MINOR = 6
4
- PATCH = 2
3
+ MINOR = 7
4
+ PATCH = 0
5
5
  VERSION = [MAJOR, MINOR, PATCH].compact.join(".").freeze
6
6
  end
@@ -1,12 +1,14 @@
1
- require 'sidekiq'
1
+ require 'active_support/core_ext/hash/keys'
2
+ require 'patches/sidekiq_job'
2
3
 
3
4
  class Patches::Worker
4
- include Sidekiq::Worker
5
+ include Patches.sidekiq_job_module
5
6
  include Patches::ApplicationVersionValidation
6
7
 
7
8
  sidekiq_options Patches::Config.configuration.sidekiq_options
8
9
 
9
10
  def perform(runner, params = {})
11
+ params = (params || {}).stringify_keys
10
12
  if valid_application_version?(params['application_version'])
11
13
  runner.constantize.new.perform
12
14
  else
data/lib/patches.rb CHANGED
@@ -2,7 +2,7 @@ require "patches/version"
2
2
 
3
3
  module Patches
4
4
  def self.default_path
5
- Rails.root.join('db/patches/') if defined?(:Rails)
5
+ Rails.root.join('db/patches/') if defined?(Rails)
6
6
  end
7
7
 
8
8
  def self.class_name(path)
@@ -19,10 +19,12 @@ module Patches
19
19
  end
20
20
  end
21
21
 
22
+ require "patches/deprecation"
22
23
  require "patches/base"
23
24
  require "patches/config"
24
25
  require "patches/tenant_run_concern"
25
26
  require "patches/application_version_validation"
27
+ require "patches/sidekiq_job" if defined?(Sidekiq)
26
28
  require "patches/tenant_worker" if defined?(Sidekiq)
27
29
  require "patches/engine" if defined?(Rails)
28
30
  require "patches/patch"
@@ -9,8 +9,8 @@ namespace :patches do
9
9
 
10
10
  if defined?(Sidekiq) && Patches::Config.configuration.use_sidekiq
11
11
  Patches::Worker.perform_async(
12
- runner,
13
- application_version: Patches::Config.configuration.application_version
12
+ runner.name,
13
+ 'application_version' => Patches::Config.configuration.application_version
14
14
  )
15
15
  else
16
16
  runner.new.perform
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patches
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.2
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
- - JobReady
8
- autorequire:
7
+ - ReadyTech
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-08-10 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: railties
@@ -24,6 +23,20 @@ dependencies:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: '3.2'
26
+ - !ruby/object:Gem::Dependency
27
+ name: activerecord
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '3.2'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '3.2'
27
40
  - !ruby/object:Gem::Dependency
28
41
  name: slack-notifier
29
42
  requirement: !ruby/object:Gem::Requirement
@@ -42,142 +55,64 @@ dependencies:
42
55
  name: bundler
43
56
  requirement: !ruby/object:Gem::Requirement
44
57
  requirements:
45
- - - "~>"
58
+ - - ">"
46
59
  - !ruby/object:Gem::Version
47
60
  version: '1.8'
48
61
  type: :development
49
62
  prerelease: false
50
63
  version_requirements: !ruby/object:Gem::Requirement
51
64
  requirements:
52
- - - "~>"
65
+ - - ">"
53
66
  - !ruby/object:Gem::Version
54
67
  version: '1.8'
55
68
  - !ruby/object:Gem::Dependency
56
69
  name: rake
57
70
  requirement: !ruby/object:Gem::Requirement
58
71
  requirements:
59
- - - "~>"
72
+ - - ">"
60
73
  - !ruby/object:Gem::Version
61
74
  version: '10.0'
62
75
  type: :development
63
76
  prerelease: false
64
77
  version_requirements: !ruby/object:Gem::Requirement
65
78
  requirements:
66
- - - "~>"
79
+ - - ">"
67
80
  - !ruby/object:Gem::Version
68
81
  version: '10.0'
69
82
  - !ruby/object:Gem::Dependency
70
- name: sqlite3
83
+ name: rspec
71
84
  requirement: !ruby/object:Gem::Requirement
72
85
  requirements:
73
86
  - - "~>"
74
87
  - !ruby/object:Gem::Version
75
- version: 1.3.5
88
+ version: '3.13'
76
89
  type: :development
77
90
  prerelease: false
78
91
  version_requirements: !ruby/object:Gem::Requirement
79
92
  requirements:
80
93
  - - "~>"
81
94
  - !ruby/object:Gem::Version
82
- version: 1.3.5
83
- - !ruby/object:Gem::Dependency
84
- name: rspec-rails
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 4.0.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 4.0.0
97
- - !ruby/object:Gem::Dependency
98
- name: capybara
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 2.3.0
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 2.3.0
111
- - !ruby/object:Gem::Dependency
112
- name: generator_spec
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: 0.9.0
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: 0.9.0
95
+ version: '3.13'
125
96
  - !ruby/object:Gem::Dependency
126
97
  name: simplecov
127
98
  requirement: !ruby/object:Gem::Requirement
128
99
  requirements:
129
100
  - - "~>"
130
101
  - !ruby/object:Gem::Version
131
- version: '0.10'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '0.10'
139
- - !ruby/object:Gem::Dependency
140
- name: factory_girl
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 4.5.0
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
102
+ version: '0.17'
103
+ - - "<"
151
104
  - !ruby/object:Gem::Version
152
- version: 4.5.0
153
- - !ruby/object:Gem::Dependency
154
- name: timecop
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: 0.7.0
105
+ version: '0.18'
160
106
  type: :development
161
107
  prerelease: false
162
108
  version_requirements: !ruby/object:Gem::Requirement
163
109
  requirements:
164
110
  - - "~>"
165
111
  - !ruby/object:Gem::Version
166
- version: 0.7.0
167
- - !ruby/object:Gem::Dependency
168
- name: database_cleaner
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: 1.3.0
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
112
+ version: '0.17'
113
+ - - "<"
179
114
  - !ruby/object:Gem::Version
180
- version: 1.3.0
115
+ version: '0.18'
181
116
  - !ruby/object:Gem::Dependency
182
117
  name: pry
183
118
  requirement: !ruby/object:Gem::Requirement
@@ -192,20 +127,6 @@ dependencies:
192
127
  - - ">="
193
128
  - !ruby/object:Gem::Version
194
129
  version: '0'
195
- - !ruby/object:Gem::Dependency
196
- name: sidekiq
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - "~>"
200
- - !ruby/object:Gem::Version
201
- version: 3.4.1
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - "~>"
207
- - !ruby/object:Gem::Version
208
- version: 3.4.1
209
130
  - !ruby/object:Gem::Dependency
210
131
  name: webmock
211
132
  requirement: !ruby/object:Gem::Requirement
@@ -220,44 +141,18 @@ dependencies:
220
141
  - - ">="
221
142
  - !ruby/object:Gem::Version
222
143
  version: '0'
223
- - !ruby/object:Gem::Dependency
224
- name: byebug
225
- requirement: !ruby/object:Gem::Requirement
226
- requirements:
227
- - - ">="
228
- - !ruby/object:Gem::Version
229
- version: '0'
230
- type: :development
231
- prerelease: false
232
- version_requirements: !ruby/object:Gem::Requirement
233
- requirements:
234
- - - ">="
235
- - !ruby/object:Gem::Version
236
- version: '0'
237
144
  description: A simple gem for one off tasks for example database patches
238
145
  email:
239
- - ruby_gems@jobready.com.au
146
+ - ruby_gems@readytech.io
240
147
  executables: []
241
148
  extensions: []
242
149
  extra_rdoc_files: []
243
150
  files:
244
- - ".buildkite/pipeline.yml"
245
- - ".github/workflows/publish.yml"
246
- - ".gitignore"
247
- - ".rspec"
248
151
  - CHANGELOG.md
249
- - Dockerfile
250
- - Gemfile
251
152
  - LICENSE.md
252
153
  - README.md
253
- - Rakefile
254
- - bin/console
255
- - bin/setup
256
154
  - db/migrate/201506011700_create_patch.rb
257
- - docker-compose.yml
258
- - docs/patches.jpg
259
155
  - docs/usage.md
260
- - lib/generators/patches.rb
261
156
  - lib/generators/patches/patch_generator.rb
262
157
  - lib/generators/patches/templates/patch.rb.erb
263
158
  - lib/generators/patches/templates/patch_spec.rb.erb
@@ -267,23 +162,27 @@ files:
267
162
  - lib/patches/capistrano.rb
268
163
  - lib/patches/capistrano/tasks.rake
269
164
  - lib/patches/config.rb
165
+ - lib/patches/deprecation.rb
270
166
  - lib/patches/engine.rb
271
167
  - lib/patches/notifier.rb
272
168
  - lib/patches/patch.rb
273
169
  - lib/patches/pending.rb
274
170
  - lib/patches/runner.rb
171
+ - lib/patches/sidekiq_job.rb
275
172
  - lib/patches/tenant_run_concern.rb
276
173
  - lib/patches/tenant_runner.rb
277
174
  - lib/patches/tenant_worker.rb
278
175
  - lib/patches/version.rb
279
176
  - lib/patches/worker.rb
280
177
  - lib/tasks/patches.rake
281
- - patches.gemspec
282
- homepage: http://github.com/jobready/patches
178
+ homepage: https://github.com/rdytech/patches
283
179
  licenses:
284
180
  - MIT
285
- metadata: {}
286
- post_install_message:
181
+ metadata:
182
+ source_code_uri: https://github.com/rdytech/patches
183
+ changelog_uri: https://github.com/rdytech/patches/blob/v3.7.0/CHANGELOG.md
184
+ bug_tracker_uri: https://github.com/rdytech/patches/issues
185
+ documentation_uri: https://github.com/rdytech/patches/blob/v3.7.0/docs/usage.md
287
186
  rdoc_options: []
288
187
  require_paths:
289
188
  - lib
@@ -298,8 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
298
197
  - !ruby/object:Gem::Version
299
198
  version: '0'
300
199
  requirements: []
301
- rubygems_version: 3.1.6
302
- signing_key:
200
+ rubygems_version: 3.6.9
303
201
  specification_version: 4
304
202
  summary: A simple gem for one off tasks
305
203
  test_files: []
@@ -1,24 +0,0 @@
1
- steps:
2
- - label: ':hammer: Tests'
3
- plugins:
4
- docker-compose:
5
- run: app
6
- command: 'bundle exec rspec'
7
- agents:
8
- queue: docker-heavy
9
- artifact_paths: 'coverage/.resultset.json'
10
-
11
- - wait
12
-
13
- - command: "Report CodeClimate Coverage"
14
- label: ":codeclimate: Report coverage"
15
- plugins:
16
- jobready/codeclimate-test-reporter#v2.0:
17
- prefix: /app
18
- artifact: "coverage/.resultset*.json"
19
- input_type: simplecov
20
- parts: 1
21
- env:
22
- CC_TEST_REPORTER_ID:
23
- agents:
24
- queue: docker-heavy
@@ -1,26 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- release:
5
- types: [published]
6
-
7
- jobs:
8
- build:
9
- name: Build + Publish
10
- runs-on: ubuntu-latest
11
- permissions:
12
- contents: read
13
- packages: write
14
-
15
- steps:
16
- - uses: actions/checkout@v3
17
- - uses: ruby/setup-ruby@v1
18
- with:
19
- ruby-version: '2.7'
20
-
21
- - name: Publish to RubyGems
22
- run: |
23
- gem build *.gemspec
24
- gem push *.gem
25
- env:
26
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/.gitignore DELETED
@@ -1,13 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- /coverage/
11
- /test.db
12
- /*.gem
13
- .byebug_history
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --require spec_helper
data/Dockerfile DELETED
@@ -1,9 +0,0 @@
1
- FROM ruby:2.3
2
-
3
- RUN touch ~/.gemrc && echo "gem: --no-ri --no-rdoc" >> ~/.gemrc
4
-
5
- WORKDIR /app/
6
- ADD . /app/
7
- RUN bundle install
8
-
9
- CMD bundle exec rake -T
data/Gemfile DELETED
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
5
- gem "rails", "~> 4.1"
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "patches"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
data/bin/setup DELETED
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here
data/docker-compose.yml DELETED
@@ -1,11 +0,0 @@
1
- version: '3.2'
2
- services:
3
- app:
4
- build: .
5
- volumes:
6
- - .:/app
7
- - app-gems:/usr/local/bundle
8
-
9
- volumes:
10
- app-gems:
11
- driver: local
data/docs/patches.jpg DELETED
Binary file
@@ -1,22 +0,0 @@
1
- module Patches
2
- module Generators
3
- class PatchGenerator < Rails::Generators::NamedBase
4
- desc 'Adds an empty patch'
5
- source_root File.expand_path('../templates', __FILE__)
6
-
7
- def generate_patch
8
- template "patch.erb", "app/db/#{file_name}.rb"
9
- end
10
-
11
- private
12
-
13
- def class_name
14
- name.camelize
15
- end
16
-
17
- def file_name
18
- name.underscore
19
- end
20
- end
21
- end
22
- end
data/patches.gemspec DELETED
@@ -1,39 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'patches/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "patches"
8
- spec.version = Patches::VERSION
9
- spec.authors = ["JobReady"]
10
- spec.email = ["ruby_gems@jobready.com.au"]
11
-
12
- spec.licenses = ['MIT']
13
- spec.summary = %q{A simple gem for one off tasks}
14
- spec.description = %q{A simple gem for one off tasks for example database patches}
15
- spec.homepage = "http://github.com/jobready/patches"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_dependency "railties", ">= 3.2"
23
- spec.add_dependency "slack-notifier"
24
-
25
- spec.add_development_dependency "bundler", "~> 1.8"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "sqlite3", "~> 1.3.5"
28
- spec.add_development_dependency "rspec-rails", "~> 4.0.0"
29
- spec.add_development_dependency "capybara", "~> 2.3.0"
30
- spec.add_development_dependency "generator_spec", "~> 0.9.0"
31
- spec.add_development_dependency "simplecov", "~> 0.10"
32
- spec.add_development_dependency "factory_girl", "~> 4.5.0"
33
- spec.add_development_dependency "timecop", "~> 0.7.0"
34
- spec.add_development_dependency "database_cleaner", "~> 1.3.0"
35
- spec.add_development_dependency "pry"
36
- spec.add_development_dependency "sidekiq", "~> 3.4.1"
37
- spec.add_development_dependency "webmock"
38
- spec.add_development_dependency "byebug"
39
- end