unforgettable 0.2.1 → 1.0.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 +4 -4
- data/.rubocop.yml +19 -0
- data/CHANGELOG.md +16 -0
- data/Gemfile +12 -1
- data/Gemfile.lock +239 -112
- data/README.md +53 -0
- data/bin/console +2 -6
- data/lib/generators/unforgettable/install_generator.rb +16 -12
- data/lib/generators/unforgettable/task_generator.rb +8 -9
- data/lib/generators/unforgettable/templates/task_template.rake +1 -1
- data/lib/unforgettable/models/release.rb +6 -2
- data/lib/unforgettable/railtie.rb +4 -1
- data/lib/unforgettable/tasks/release.rb +9 -6
- data/lib/unforgettable/tasks/{unforgetable → unforgettable}/release.rake +3 -1
- data/lib/unforgettable/version.rb +1 -1
- data/lib/unforgettable.rb +4 -5
- data/unforgettable.gemspec +9 -11
- metadata +11 -70
- data/lib/unforgettable/engine.rb +0 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 32b471126131360b2eb1f004da9f55dbcb17f8988023fd4d0d496069a6827a55
|
|
4
|
+
data.tar.gz: 03c7e667867659201dfb8c4a09534bff4595b4da2e95068f6f73915a7eb76d92
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47737ef7762ab3604730848e806a6cbd2c18fa68261d8543c4758feeaa5babdec65bf019e71daa5cfa9cbe4f371d120b321a9ed20b166568f260483ce57175d0
|
|
7
|
+
data.tar.gz: ad8317abcd31d084ebfeb5bf735b44f0d6c6a2ef91767a907c09625a55d6a7983fee7997c751489935ba64e7626c489574798474dcbdf9bf71c38f488e702753
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Load extension gems (Minitest, Rails, Rake cops)
|
|
2
|
+
plugins:
|
|
3
|
+
- rubocop-minitest
|
|
4
|
+
- rubocop-rails
|
|
5
|
+
- rubocop-rake
|
|
6
|
+
|
|
7
|
+
# ERB templates are not plain Ruby; exclude from linting
|
|
8
|
+
AllCops:
|
|
9
|
+
NewCops: enable
|
|
10
|
+
Exclude:
|
|
11
|
+
- "lib/generators/**/templates/**"
|
|
12
|
+
|
|
13
|
+
# Prefer double quotes for strings (matches existing code style in this gem)
|
|
14
|
+
Style/StringLiterals:
|
|
15
|
+
EnforcedStyle: double_quotes
|
|
16
|
+
|
|
17
|
+
# Generator tests assert multiple aspects of one generated file
|
|
18
|
+
Minitest/MultipleAssertions:
|
|
19
|
+
Max: 5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [1.0.0] - 2026-03-03
|
|
5
|
+
### Changed
|
|
6
|
+
- **Ruby 3.0+ required.** The gemspec now requires Ruby `>= 3.0.0`. If you are on Ruby 2.x, stay on gem version 0.2.x; no new features will be backported to 0.2.x.
|
|
7
|
+
- Fixed typo: task directory renamed from `unforgetable` to `unforgettable` (behavior unchanged).
|
|
8
|
+
- Generator `source_root` now uses `__dir__` for compatibility.
|
|
9
|
+
- Install generator test now asserts migration file content instead of directory entry count.
|
|
10
|
+
|
|
11
|
+
### Removed
|
|
12
|
+
- Redundant engine (empty `Rails::Engine` subclass removed; Railtie and explicit requires remain).
|
|
13
|
+
|
|
14
|
+
### Developer experience
|
|
15
|
+
- Double quotes enforced in `lib/unforgettable.rb` to match RuboCop.
|
|
16
|
+
- Added `# frozen_string_literal: true` where missing.
|
|
17
|
+
- `bin/console` now uses Pry when available.
|
|
18
|
+
- RuboCop and extensions (rubocop-minitest, rubocop-rails, rubocop-rake) added as development dependencies.
|
|
19
|
+
|
|
4
20
|
## [0.2.1] - 2021-06-01
|
|
5
21
|
### Fixed
|
|
6
22
|
- Sort order of tasks by name before running.
|
data/Gemfile
CHANGED
|
@@ -5,6 +5,17 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in unforgettable.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
+
gem "minitest", "~> 5.0"
|
|
8
9
|
gem "rake", "~> 13.0"
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
group :development do
|
|
12
|
+
gem "pry"
|
|
13
|
+
gem "rack-test"
|
|
14
|
+
gem "rails"
|
|
15
|
+
gem "rubocop"
|
|
16
|
+
gem "rubocop-minitest"
|
|
17
|
+
gem "rubocop-rails"
|
|
18
|
+
gem "rubocop-rake"
|
|
19
|
+
gem "ruby-lsp"
|
|
20
|
+
gem "timecop"
|
|
21
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,145 +1,267 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
unforgettable (0.
|
|
4
|
+
unforgettable (1.0.0)
|
|
5
5
|
activerecord
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
action_text-trix (2.1.16)
|
|
11
|
+
railties
|
|
12
|
+
actioncable (8.1.2)
|
|
13
|
+
actionpack (= 8.1.2)
|
|
14
|
+
activesupport (= 8.1.2)
|
|
13
15
|
nio4r (~> 2.0)
|
|
14
16
|
websocket-driver (>= 0.6.1)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
zeitwerk (~> 2.6)
|
|
18
|
+
actionmailbox (8.1.2)
|
|
19
|
+
actionpack (= 8.1.2)
|
|
20
|
+
activejob (= 8.1.2)
|
|
21
|
+
activerecord (= 8.1.2)
|
|
22
|
+
activestorage (= 8.1.2)
|
|
23
|
+
activesupport (= 8.1.2)
|
|
24
|
+
mail (>= 2.8.0)
|
|
25
|
+
actionmailer (8.1.2)
|
|
26
|
+
actionpack (= 8.1.2)
|
|
27
|
+
actionview (= 8.1.2)
|
|
28
|
+
activejob (= 8.1.2)
|
|
29
|
+
activesupport (= 8.1.2)
|
|
30
|
+
mail (>= 2.8.0)
|
|
31
|
+
rails-dom-testing (~> 2.2)
|
|
32
|
+
actionpack (8.1.2)
|
|
33
|
+
actionview (= 8.1.2)
|
|
34
|
+
activesupport (= 8.1.2)
|
|
35
|
+
nokogiri (>= 1.8.5)
|
|
36
|
+
rack (>= 2.2.4)
|
|
37
|
+
rack-session (>= 1.0.1)
|
|
33
38
|
rack-test (>= 0.6.3)
|
|
34
|
-
rails-dom-testing (~> 2.
|
|
35
|
-
rails-html-sanitizer (~> 1.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
rails-dom-testing (~> 2.2)
|
|
40
|
+
rails-html-sanitizer (~> 1.6)
|
|
41
|
+
useragent (~> 0.16)
|
|
42
|
+
actiontext (8.1.2)
|
|
43
|
+
action_text-trix (~> 2.1.15)
|
|
44
|
+
actionpack (= 8.1.2)
|
|
45
|
+
activerecord (= 8.1.2)
|
|
46
|
+
activestorage (= 8.1.2)
|
|
47
|
+
activesupport (= 8.1.2)
|
|
48
|
+
globalid (>= 0.6.0)
|
|
41
49
|
nokogiri (>= 1.8.5)
|
|
42
|
-
actionview (
|
|
43
|
-
activesupport (=
|
|
50
|
+
actionview (8.1.2)
|
|
51
|
+
activesupport (= 8.1.2)
|
|
44
52
|
builder (~> 3.1)
|
|
45
|
-
erubi (~> 1.
|
|
46
|
-
rails-dom-testing (~> 2.
|
|
47
|
-
rails-html-sanitizer (~> 1.
|
|
48
|
-
activejob (
|
|
49
|
-
activesupport (=
|
|
53
|
+
erubi (~> 1.11)
|
|
54
|
+
rails-dom-testing (~> 2.2)
|
|
55
|
+
rails-html-sanitizer (~> 1.6)
|
|
56
|
+
activejob (8.1.2)
|
|
57
|
+
activesupport (= 8.1.2)
|
|
50
58
|
globalid (>= 0.3.6)
|
|
51
|
-
activemodel (
|
|
52
|
-
activesupport (=
|
|
53
|
-
activerecord (
|
|
54
|
-
activemodel (=
|
|
55
|
-
activesupport (=
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
activesupport (
|
|
64
|
-
|
|
59
|
+
activemodel (8.1.2)
|
|
60
|
+
activesupport (= 8.1.2)
|
|
61
|
+
activerecord (8.1.2)
|
|
62
|
+
activemodel (= 8.1.2)
|
|
63
|
+
activesupport (= 8.1.2)
|
|
64
|
+
timeout (>= 0.4.0)
|
|
65
|
+
activestorage (8.1.2)
|
|
66
|
+
actionpack (= 8.1.2)
|
|
67
|
+
activejob (= 8.1.2)
|
|
68
|
+
activerecord (= 8.1.2)
|
|
69
|
+
activesupport (= 8.1.2)
|
|
70
|
+
marcel (~> 1.0)
|
|
71
|
+
activesupport (8.1.2)
|
|
72
|
+
base64
|
|
73
|
+
bigdecimal
|
|
74
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
75
|
+
connection_pool (>= 2.2.5)
|
|
76
|
+
drb
|
|
65
77
|
i18n (>= 1.6, < 2)
|
|
78
|
+
json
|
|
79
|
+
logger (>= 1.4.2)
|
|
66
80
|
minitest (>= 5.1)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
81
|
+
securerandom (>= 0.3)
|
|
82
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
83
|
+
uri (>= 0.13.1)
|
|
84
|
+
addressable (2.8.8)
|
|
85
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
86
|
+
ast (2.4.3)
|
|
87
|
+
base64 (0.3.0)
|
|
88
|
+
bigdecimal (4.0.1)
|
|
89
|
+
builder (3.3.0)
|
|
70
90
|
coderay (1.1.3)
|
|
71
|
-
concurrent-ruby (1.
|
|
91
|
+
concurrent-ruby (1.3.6)
|
|
92
|
+
connection_pool (3.0.2)
|
|
72
93
|
crass (1.0.6)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
94
|
+
date (3.5.1)
|
|
95
|
+
drb (2.2.3)
|
|
96
|
+
erb (6.0.2)
|
|
97
|
+
erubi (1.13.1)
|
|
98
|
+
globalid (1.3.0)
|
|
99
|
+
activesupport (>= 6.1)
|
|
100
|
+
i18n (1.14.8)
|
|
77
101
|
concurrent-ruby (~> 1.0)
|
|
78
|
-
|
|
102
|
+
io-console (0.8.2)
|
|
103
|
+
irb (1.17.0)
|
|
104
|
+
pp (>= 0.6.0)
|
|
105
|
+
prism (>= 1.3.0)
|
|
106
|
+
rdoc (>= 4.0.0)
|
|
107
|
+
reline (>= 0.4.2)
|
|
108
|
+
json (2.18.1)
|
|
109
|
+
json-schema (6.1.0)
|
|
110
|
+
addressable (~> 2.8)
|
|
111
|
+
bigdecimal (>= 3.1, < 5)
|
|
112
|
+
language_server-protocol (3.17.0.5)
|
|
113
|
+
lint_roller (1.1.0)
|
|
114
|
+
logger (1.7.0)
|
|
115
|
+
loofah (2.25.0)
|
|
79
116
|
crass (~> 1.0.2)
|
|
80
|
-
nokogiri (>= 1.
|
|
81
|
-
mail (2.
|
|
117
|
+
nokogiri (>= 1.12.0)
|
|
118
|
+
mail (2.9.0)
|
|
119
|
+
logger
|
|
82
120
|
mini_mime (>= 0.1.1)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
121
|
+
net-imap
|
|
122
|
+
net-pop
|
|
123
|
+
net-smtp
|
|
124
|
+
marcel (1.1.0)
|
|
125
|
+
mcp (0.8.0)
|
|
126
|
+
json-schema (>= 4.1)
|
|
127
|
+
method_source (1.1.0)
|
|
128
|
+
mini_mime (1.1.5)
|
|
129
|
+
minitest (5.27.0)
|
|
130
|
+
net-imap (0.6.3)
|
|
131
|
+
date
|
|
132
|
+
net-protocol
|
|
133
|
+
net-pop (0.1.2)
|
|
134
|
+
net-protocol
|
|
135
|
+
net-protocol (0.2.2)
|
|
136
|
+
timeout
|
|
137
|
+
net-smtp (0.5.1)
|
|
138
|
+
net-protocol
|
|
139
|
+
nio4r (2.7.5)
|
|
140
|
+
nokogiri (1.19.1-arm64-darwin)
|
|
141
|
+
racc (~> 1.4)
|
|
142
|
+
nokogiri (1.19.1-x86_64-darwin)
|
|
91
143
|
racc (~> 1.4)
|
|
92
|
-
|
|
144
|
+
parallel (1.27.0)
|
|
145
|
+
parser (3.3.10.1)
|
|
146
|
+
ast (~> 2.4.1)
|
|
147
|
+
racc
|
|
148
|
+
pp (0.6.3)
|
|
149
|
+
prettyprint
|
|
150
|
+
prettyprint (0.2.0)
|
|
151
|
+
prism (1.9.0)
|
|
152
|
+
pry (0.16.0)
|
|
93
153
|
coderay (~> 1.1)
|
|
94
154
|
method_source (~> 1.0)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
155
|
+
reline (>= 0.6.0)
|
|
156
|
+
psych (5.3.1)
|
|
157
|
+
date
|
|
158
|
+
stringio
|
|
159
|
+
public_suffix (7.0.0)
|
|
160
|
+
racc (1.8.1)
|
|
161
|
+
rack (3.2.5)
|
|
162
|
+
rack-session (2.1.1)
|
|
163
|
+
base64 (>= 0.1.0)
|
|
164
|
+
rack (>= 3.0.0)
|
|
165
|
+
rack-test (2.2.0)
|
|
166
|
+
rack (>= 1.3)
|
|
167
|
+
rackup (2.3.1)
|
|
168
|
+
rack (>= 3)
|
|
169
|
+
rails (8.1.2)
|
|
170
|
+
actioncable (= 8.1.2)
|
|
171
|
+
actionmailbox (= 8.1.2)
|
|
172
|
+
actionmailer (= 8.1.2)
|
|
173
|
+
actionpack (= 8.1.2)
|
|
174
|
+
actiontext (= 8.1.2)
|
|
175
|
+
actionview (= 8.1.2)
|
|
176
|
+
activejob (= 8.1.2)
|
|
177
|
+
activemodel (= 8.1.2)
|
|
178
|
+
activerecord (= 8.1.2)
|
|
179
|
+
activestorage (= 8.1.2)
|
|
180
|
+
activesupport (= 8.1.2)
|
|
111
181
|
bundler (>= 1.15.0)
|
|
112
|
-
railties (=
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
182
|
+
railties (= 8.1.2)
|
|
183
|
+
rails-dom-testing (2.3.0)
|
|
184
|
+
activesupport (>= 5.0.0)
|
|
185
|
+
minitest
|
|
116
186
|
nokogiri (>= 1.6)
|
|
117
|
-
rails-html-sanitizer (1.
|
|
118
|
-
loofah (~> 2.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
187
|
+
rails-html-sanitizer (1.7.0)
|
|
188
|
+
loofah (~> 2.25)
|
|
189
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
190
|
+
railties (8.1.2)
|
|
191
|
+
actionpack (= 8.1.2)
|
|
192
|
+
activesupport (= 8.1.2)
|
|
193
|
+
irb (~> 1.13)
|
|
194
|
+
rackup (>= 1.0.0)
|
|
195
|
+
rake (>= 12.2)
|
|
196
|
+
thor (~> 1.0, >= 1.2.2)
|
|
197
|
+
tsort (>= 0.2)
|
|
198
|
+
zeitwerk (~> 2.6)
|
|
199
|
+
rainbow (3.1.1)
|
|
200
|
+
rake (13.3.1)
|
|
201
|
+
rbs (3.10.3)
|
|
202
|
+
logger
|
|
203
|
+
tsort
|
|
204
|
+
rdoc (7.2.0)
|
|
205
|
+
erb
|
|
206
|
+
psych (>= 4.0.0)
|
|
207
|
+
tsort
|
|
208
|
+
regexp_parser (2.11.3)
|
|
209
|
+
reline (0.6.3)
|
|
210
|
+
io-console (~> 0.5)
|
|
211
|
+
rubocop (1.85.0)
|
|
212
|
+
json (~> 2.3)
|
|
213
|
+
language_server-protocol (~> 3.17.0.2)
|
|
214
|
+
lint_roller (~> 1.1.0)
|
|
215
|
+
mcp (~> 0.6)
|
|
216
|
+
parallel (~> 1.10)
|
|
217
|
+
parser (>= 3.3.0.2)
|
|
218
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
219
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
220
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
221
|
+
ruby-progressbar (~> 1.7)
|
|
222
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
223
|
+
rubocop-ast (1.49.0)
|
|
224
|
+
parser (>= 3.3.7.2)
|
|
225
|
+
prism (~> 1.7)
|
|
226
|
+
rubocop-minitest (0.39.1)
|
|
227
|
+
lint_roller (~> 1.1)
|
|
228
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
229
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
230
|
+
rubocop-rails (2.34.3)
|
|
231
|
+
activesupport (>= 4.2.0)
|
|
232
|
+
lint_roller (~> 1.1)
|
|
233
|
+
rack (>= 1.1)
|
|
234
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
235
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
|
236
|
+
rubocop-rake (0.7.1)
|
|
237
|
+
lint_roller (~> 1.1)
|
|
238
|
+
rubocop (>= 1.72.1)
|
|
239
|
+
ruby-lsp (0.26.7)
|
|
240
|
+
language_server-protocol (~> 3.17.0)
|
|
241
|
+
prism (>= 1.2, < 2.0)
|
|
242
|
+
rbs (>= 3, < 5)
|
|
243
|
+
ruby-progressbar (1.13.0)
|
|
244
|
+
securerandom (0.4.1)
|
|
245
|
+
stringio (3.2.0)
|
|
246
|
+
thor (1.5.0)
|
|
247
|
+
timecop (0.9.10)
|
|
248
|
+
timeout (0.6.0)
|
|
249
|
+
tsort (0.2.0)
|
|
250
|
+
tzinfo (2.0.6)
|
|
136
251
|
concurrent-ruby (~> 1.0)
|
|
137
|
-
|
|
252
|
+
unicode-display_width (3.2.0)
|
|
253
|
+
unicode-emoji (~> 4.1)
|
|
254
|
+
unicode-emoji (4.2.0)
|
|
255
|
+
uri (1.1.1)
|
|
256
|
+
useragent (0.16.11)
|
|
257
|
+
websocket-driver (0.8.0)
|
|
258
|
+
base64
|
|
138
259
|
websocket-extensions (>= 0.1.0)
|
|
139
260
|
websocket-extensions (0.1.5)
|
|
140
|
-
zeitwerk (2.
|
|
261
|
+
zeitwerk (2.7.5)
|
|
141
262
|
|
|
142
263
|
PLATFORMS
|
|
264
|
+
arm64-darwin-24
|
|
143
265
|
x86_64-darwin-19
|
|
144
266
|
|
|
145
267
|
DEPENDENCIES
|
|
@@ -148,8 +270,13 @@ DEPENDENCIES
|
|
|
148
270
|
rack-test
|
|
149
271
|
rails
|
|
150
272
|
rake (~> 13.0)
|
|
273
|
+
rubocop
|
|
274
|
+
rubocop-minitest
|
|
275
|
+
rubocop-rails
|
|
276
|
+
rubocop-rake
|
|
277
|
+
ruby-lsp
|
|
151
278
|
timecop
|
|
152
279
|
unforgettable!
|
|
153
280
|
|
|
154
281
|
BUNDLED WITH
|
|
155
|
-
|
|
282
|
+
4.0.7
|
data/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
How many times have you deployed a new release of a rails app and forgot to run a post-release rake task? Unforgettable tracks which tasks it has run previously, and which tasks still need to be invoked. Never forget to run post-release deploy rake tasks again!
|
|
4
4
|
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Ruby 3.0 or newer. (If you need Ruby 2.x, use gem version 0.2.x.)
|
|
8
|
+
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
7
11
|
Add this line to your application's Gemfile:
|
|
@@ -51,6 +55,55 @@ end
|
|
|
51
55
|
after 'deploy:published', 'deploy:release'
|
|
52
56
|
```
|
|
53
57
|
|
|
58
|
+
### Integration with Kamal
|
|
59
|
+
|
|
60
|
+
You can integrate Unforgettable with Kamal deploys by calling it from a post-deploy hook.
|
|
61
|
+
Create a file `post-deploy` under the `.kmal` folder in the root of your project. The integration should look something like:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
|
|
65
|
+
$stdout.sync = true
|
|
66
|
+
|
|
67
|
+
$stderr.puts "Running bin/rails unforgettable:release on remote Docker containers..."
|
|
68
|
+
|
|
69
|
+
def get_container_name(host)
|
|
70
|
+
base_name = "grogo-web"
|
|
71
|
+
destination = ENV["KAMAL_DESTINATION"]
|
|
72
|
+
version = ENV["KAMAL_VERSION"]
|
|
73
|
+
|
|
74
|
+
potential_names = [
|
|
75
|
+
[ base_name, destination, version ].reject { |v| v.to_s.strip.empty? }.join("-"),
|
|
76
|
+
[ base_name, version ].reject { |v| v.to_s.strip.empty? }.join("-")
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
# Check potential names to see which matches a container id on the server.
|
|
80
|
+
potential_names.each do |name|
|
|
81
|
+
command = "ssh deploy@#{host} \"docker ps --format '{{.Names}}' | grep #{name}\""
|
|
82
|
+
result = `#{command}`.strip
|
|
83
|
+
return result unless result.empty?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def execute_task(host, container_name)
|
|
90
|
+
task = "bin/rails unforgettable:release"
|
|
91
|
+
remote_host = "deploy@#{host}"
|
|
92
|
+
|
|
93
|
+
command = "ssh #{remote_host} 'docker exec #{container_name} #{task}'"
|
|
94
|
+
unless system(command)
|
|
95
|
+
$stderr.puts "Failed to execute rake task on remote Docker container: #{task} for host #{host}"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
ENV["KAMAL_HOSTS"].to_s.split(",").each do |host|
|
|
100
|
+
container_name = get_container_name(host)
|
|
101
|
+
execute_task(host, container_name)
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Note: Kamal will not show the $stdout by default. Run Kamal in verbose mode with `kamal deploy -v` in order to see any output.
|
|
106
|
+
|
|
54
107
|
### Rerunning Completed Tasks
|
|
55
108
|
|
|
56
109
|
Unforgettable records all tasks that have been run as a row on the `unforgettable_releases` table.
|
data/bin/console
CHANGED
|
@@ -7,9 +7,5 @@ require "unforgettable"
|
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# Pry.start
|
|
13
|
-
|
|
14
|
-
require "irb"
|
|
15
|
-
IRB.start(__FILE__)
|
|
10
|
+
require "pry"
|
|
11
|
+
Pry.start
|
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/active_record"
|
|
3
5
|
|
|
4
6
|
module Unforgettable
|
|
5
7
|
module Generators
|
|
8
|
+
# Generates the unforgettable_releases migration and lib/tasks/unforgettable directory.
|
|
6
9
|
class InstallGenerator < Rails::Generators::Base
|
|
7
10
|
include Rails::Generators::Migration
|
|
8
11
|
|
|
9
12
|
desc "Generate a migration for unforgettable_releases"
|
|
10
|
-
source_root File.
|
|
13
|
+
source_root File.expand_path("templates", __dir__)
|
|
11
14
|
|
|
12
15
|
def generate_migration
|
|
13
|
-
migration_template "migration_template.rb", "db/migrate/create_unforgettable_releases.rb",
|
|
16
|
+
migration_template "migration_template.rb", "db/migrate/create_unforgettable_releases.rb",
|
|
17
|
+
migration_version: migration_version
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
def create_unforgettable_folder
|
|
17
|
-
template(
|
|
21
|
+
template(".keep", "lib/tasks/unforgettable/.keep")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.next_migration_number(dirname)
|
|
25
|
+
next_migration_number = current_migration_number(dirname) + 1
|
|
26
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
|
18
27
|
end
|
|
19
28
|
|
|
20
29
|
private
|
|
21
30
|
|
|
22
31
|
def migration_version
|
|
23
|
-
|
|
24
|
-
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
|
25
|
-
end
|
|
26
|
-
end
|
|
32
|
+
return unless defined?(Rails::VERSION) && Rails::VERSION::MAJOR >= 5
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
next_migration_number = current_migration_number(dirname) + 1
|
|
30
|
-
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
|
34
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
|
31
35
|
end
|
|
32
36
|
end
|
|
33
37
|
end
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
2
4
|
|
|
3
5
|
module Unforgettable
|
|
4
6
|
module Generators
|
|
7
|
+
# Generates a timestamped release rake task in lib/tasks/unforgettable/.
|
|
5
8
|
class TaskGenerator < Rails::Generators::Base
|
|
6
|
-
|
|
7
9
|
desc "Create an unforgettable release rake task"
|
|
8
|
-
source_root File.
|
|
10
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
11
|
|
|
10
12
|
def create_rakefile
|
|
11
|
-
template(
|
|
13
|
+
template("task_template.rake", "lib/tasks/unforgettable/release_#{release_id}.rake")
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
private
|
|
15
17
|
|
|
16
18
|
def release_id
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def task_name
|
|
21
|
-
":release_#{release_id}".to_sym
|
|
19
|
+
# Time.now: in generator context (e.g. tests) Time.zone can be nil
|
|
20
|
+
@release_id ||= Time.now.strftime("%Y%m%d%H%M%S") # rubocop:disable Rails/TimeZone
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
namespace :unforgettable do
|
|
2
2
|
desc "Unforgettable release task <%= release_id %>"
|
|
3
|
-
task <%=
|
|
3
|
+
task release_<%= release_id %>: :environment do
|
|
4
4
|
# Add any code that needs to be run by unforgettable
|
|
5
5
|
# `User.admin.update_all(state: 'active')`
|
|
6
6
|
#
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Unforgettable
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
# ActiveRecord model for tracking which release tasks have been run.
|
|
5
|
+
# Inherits from ActiveRecord::Base (not ApplicationRecord) so the gem works in any host app.
|
|
6
|
+
class Release < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
|
|
7
|
+
self.table_name = "unforgettable_releases"
|
|
4
8
|
end
|
|
5
9
|
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Unforgettable
|
|
4
|
+
# Rails integration: loads unforgettable rake tasks.
|
|
2
5
|
class Railtie < Rails::Railtie
|
|
3
6
|
railtie_name :unforgettable
|
|
4
7
|
|
|
@@ -7,4 +10,4 @@ module Unforgettable
|
|
|
7
10
|
Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
|
|
8
11
|
end
|
|
9
12
|
end
|
|
10
|
-
end
|
|
13
|
+
end
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Unforgettable
|
|
2
4
|
module Tasks
|
|
5
|
+
# Runs any release rake tasks that have not been run yet (recorded in Unforgettable::Release).
|
|
3
6
|
class Release
|
|
4
7
|
class << self
|
|
5
8
|
def call
|
|
@@ -14,24 +17,24 @@ module Unforgettable
|
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
def all_tasks
|
|
17
|
-
filenames = Dir.entries(unforgettable_folder).reject {|f| File.directory?(f) || f[0].include?(
|
|
18
|
-
filenames.map { |filename| filename.split(
|
|
20
|
+
filenames = Dir.entries(unforgettable_folder).reject { |f| File.directory?(f) || f[0].include?(".") }
|
|
21
|
+
filenames.map { |filename| filename.split(".")[0] }
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
def unforgettable_folder
|
|
22
|
-
|
|
25
|
+
Rails.root.join("lib", "tasks", "unforgettable").to_s # rubocop:disable Rails/FilePath -- join with args is correct
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def run!(task_name)
|
|
26
29
|
print_border
|
|
27
|
-
puts "Running #{task_name}"
|
|
30
|
+
puts "Running #{task_name}" # rubocop:disable Rails/Output -- intentional: user-facing rake output
|
|
28
31
|
Rake::Task["unforgettable:#{task_name}"].invoke
|
|
29
32
|
create_record(task_name)
|
|
30
33
|
print_border
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def print_border
|
|
34
|
-
puts "*" * 80
|
|
37
|
+
puts "*" * 80 # rubocop:disable Rails/Output -- intentional: user-facing rake output
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
def create_record(task_name)
|
|
@@ -40,4 +43,4 @@ module Unforgettable
|
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
|
-
end
|
|
46
|
+
end
|
data/lib/unforgettable.rb
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "rails"
|
|
4
4
|
require "active_record"
|
|
5
5
|
|
|
6
6
|
require_relative "unforgettable/version"
|
|
7
7
|
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require 'unforgettable/tasks/release'
|
|
8
|
+
require "unforgettable/railtie" if defined?(Rails::Railtie)
|
|
9
|
+
require "unforgettable/models/release"
|
|
10
|
+
require "unforgettable/tasks/release"
|
|
12
11
|
|
|
13
12
|
module Unforgettable
|
|
14
13
|
class Error < StandardError; end
|
data/unforgettable.gemspec
CHANGED
|
@@ -7,17 +7,20 @@ Gem::Specification.new do |spec|
|
|
|
7
7
|
spec.version = Unforgettable::VERSION
|
|
8
8
|
spec.authors = ["James Stubblefield"]
|
|
9
9
|
|
|
10
|
-
spec.summary = "Unforgettable tracks which tasks it has run previously, and
|
|
11
|
-
|
|
12
|
-
spec.
|
|
10
|
+
spec.summary = "Unforgettable tracks which tasks it has run previously, and " \
|
|
11
|
+
"which tasks still need to be invoked."
|
|
12
|
+
spec.description = "Unforgettable tracks which tasks it has run previously, and " \
|
|
13
|
+
"which tasks still need to be invoked."
|
|
14
|
+
spec.homepage = "https://github.com/jameswilliamiii/unforgettable"
|
|
13
15
|
spec.license = "MIT"
|
|
14
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
|
|
15
17
|
|
|
16
18
|
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
|
17
19
|
|
|
18
20
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
19
|
-
spec.metadata["source_code_uri"] = "https://
|
|
20
|
-
spec.metadata["changelog_uri"] = "https://
|
|
21
|
+
spec.metadata["source_code_uri"] = "https://github.com/jameswilliamiii/unforgettable"
|
|
22
|
+
spec.metadata["changelog_uri"] = "https://github.com/jameswilliamiii/unforgettable/blob/master/CHANGELOG.md"
|
|
23
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
21
24
|
|
|
22
25
|
# Specify which files should be added to the gem when it is released.
|
|
23
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
@@ -30,11 +33,6 @@ Gem::Specification.new do |spec|
|
|
|
30
33
|
|
|
31
34
|
spec.add_dependency "activerecord"
|
|
32
35
|
|
|
33
|
-
spec.add_development_dependency "rack-test"
|
|
34
|
-
spec.add_development_dependency "rails"
|
|
35
|
-
spec.add_development_dependency "pry"
|
|
36
|
-
spec.add_development_dependency "timecop"
|
|
37
|
-
|
|
38
36
|
# For more information and examples about making a new gem, checkout our
|
|
39
37
|
# guide at: https://bundler.io/guides/creating_gem.html
|
|
40
38
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unforgettable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James Stubblefield
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -24,70 +23,14 @@ dependencies:
|
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: rack-test
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: rails
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: pry
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - ">="
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - ">="
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: timecop
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
26
|
description: Unforgettable tracks which tasks it has run previously, and which tasks
|
|
84
27
|
still need to be invoked.
|
|
85
|
-
email:
|
|
86
28
|
executables: []
|
|
87
29
|
extensions: []
|
|
88
30
|
extra_rdoc_files: []
|
|
89
31
|
files:
|
|
90
32
|
- ".gitignore"
|
|
33
|
+
- ".rubocop.yml"
|
|
91
34
|
- CHANGELOG.md
|
|
92
35
|
- Gemfile
|
|
93
36
|
- Gemfile.lock
|
|
@@ -102,22 +45,21 @@ files:
|
|
|
102
45
|
- lib/generators/unforgettable/templates/migration_template.rb
|
|
103
46
|
- lib/generators/unforgettable/templates/task_template.rake
|
|
104
47
|
- lib/unforgettable.rb
|
|
105
|
-
- lib/unforgettable/engine.rb
|
|
106
48
|
- lib/unforgettable/models/release.rb
|
|
107
49
|
- lib/unforgettable/railtie.rb
|
|
108
50
|
- lib/unforgettable/tasks/release.rb
|
|
109
|
-
- lib/unforgettable/tasks/
|
|
51
|
+
- lib/unforgettable/tasks/unforgettable/release.rake
|
|
110
52
|
- lib/unforgettable/version.rb
|
|
111
53
|
- unforgettable.gemspec
|
|
112
|
-
homepage: https://
|
|
54
|
+
homepage: https://github.com/jameswilliamiii/unforgettable
|
|
113
55
|
licenses:
|
|
114
56
|
- MIT
|
|
115
57
|
metadata:
|
|
116
58
|
allowed_push_host: https://rubygems.org/
|
|
117
|
-
homepage_uri: https://
|
|
118
|
-
source_code_uri: https://
|
|
119
|
-
changelog_uri: https://
|
|
120
|
-
|
|
59
|
+
homepage_uri: https://github.com/jameswilliamiii/unforgettable
|
|
60
|
+
source_code_uri: https://github.com/jameswilliamiii/unforgettable
|
|
61
|
+
changelog_uri: https://github.com/jameswilliamiii/unforgettable/blob/master/CHANGELOG.md
|
|
62
|
+
rubygems_mfa_required: 'true'
|
|
121
63
|
rdoc_options: []
|
|
122
64
|
require_paths:
|
|
123
65
|
- lib
|
|
@@ -125,15 +67,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
125
67
|
requirements:
|
|
126
68
|
- - ">="
|
|
127
69
|
- !ruby/object:Gem::Version
|
|
128
|
-
version:
|
|
70
|
+
version: 3.0.0
|
|
129
71
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
72
|
requirements:
|
|
131
73
|
- - ">="
|
|
132
74
|
- !ruby/object:Gem::Version
|
|
133
75
|
version: '0'
|
|
134
76
|
requirements: []
|
|
135
|
-
rubygems_version: 3.2
|
|
136
|
-
signing_key:
|
|
77
|
+
rubygems_version: 3.7.2
|
|
137
78
|
specification_version: 4
|
|
138
79
|
summary: Unforgettable tracks which tasks it has run previously, and which tasks still
|
|
139
80
|
need to be invoked.
|