rake-gem-maintenance 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65b010085edf81afe7c8233594c9b8e115889cdfd02f15527d354d5482cf24d1
4
- data.tar.gz: ea5de615c2d4c76e9fd1f89fd222beb804060206ca6319feb0635ac114e2b7da
3
+ metadata.gz: be7d681a68e8e69bdc90eac0b8bfec1eaa7a87e65f0e8c49a56dccf2af77e37e
4
+ data.tar.gz: 70233681d6a4c67bbc20d58788e87e461dbaa0b54baca8cd3f1ffc32243248d8
5
5
  SHA512:
6
- metadata.gz: f263f65817da2c6afcef96d0968679f84905f7c7c51e4ddc96cae2b1372b0a0231137eb9685752b0aa88017c913da9e86f51d29953761891a8700fc152b71cd2
7
- data.tar.gz: 9abdac846de81dda6854f396b757051847a10bf3fc36c2f4ec72cd13f04d2d0f5fce7a814ee0a164b3f509923639c4b5785fbc102074a48e55f465d4a67c6ff2
6
+ metadata.gz: 76ea9b6df6e145ee9acd98af449069401a57116b0ec3efefa35d0f80586a7984e2e2ad1d8dd90248feafe8f3aa79897599455ed1b5dac04cff934095033afc1d
7
+ data.tar.gz: 667939fde2e1f1dcc4ea51eb2330ef0300be97d305fc1ee229656cd97e1825230da4009e77a910a37c8723a13c8fe402294d581340e51705d95ea46f4a9c41b2
@@ -10,7 +10,7 @@
10
10
  # badge_service_token — write token for badge.cbp-org.internal
11
11
 
12
12
  when:
13
- event: [push, manual]
13
+ event: push
14
14
  branch: main
15
15
 
16
16
  labels:
@@ -34,7 +34,7 @@ steps:
34
34
  RUBYGEMS_OTP_SEED:
35
35
  from_secret: rubygems_otp_seed
36
36
  commands:
37
- - apk add --no-cache build-base git
37
+ - apk add --no-cache build-base git yaml-dev
38
38
  - bundle install --jobs 4 --retry 3
39
39
  - ruby scripts/ci_publish_rubygems.rb
40
40
 
@@ -1,7 +1,6 @@
1
1
  when:
2
2
  - event: cron
3
3
  cron: monthly-renew-api-key
4
- - event: manual
5
4
 
6
5
  labels:
7
6
  platform: linux
@@ -29,7 +28,7 @@ steps:
29
28
  from_secret: woodpecker_api_token
30
29
  WOODPECKER_SERVER: "https://ci.cbp-org.internal"
31
30
  commands:
32
- - apk add --no-cache build-base
31
+ - apk add --no-cache build-base git yaml-dev
33
32
  - bundle install --jobs 4 --retry 3
34
33
  - bundle exec rake upgrade:renew_api_key
35
34
 
@@ -19,7 +19,7 @@ steps:
19
19
  environment:
20
20
  CUCUMBER_PUBLISH_QUIET: "true"
21
21
  commands:
22
- - apk add --no-cache build-base git
22
+ - apk add --no-cache build-base git yaml-dev
23
23
  - mkdir -p /root/.local/share/ruby-advisory-db/gems
24
24
  - bundle install --jobs 4 --retry 3
25
25
  - bundle exec rake verify
data/AGENTS.md ADDED
@@ -0,0 +1,78 @@
1
+ # AGENTS.md
2
+
3
+ ## Project Overview
4
+
5
+ rake-gem-maintenance is a Ruby gem providing reusable Rake::TaskLib subclasses for gem maintenance workflows: dependency upgrades and version bumps.
6
+
7
+ ## Common Commands
8
+
9
+ ```bash
10
+ # Install dependencies
11
+ bundle install
12
+
13
+ # Run all verification (specs + rubocop)
14
+ rake
15
+
16
+ # Run RSpec tests only
17
+ rake spec
18
+
19
+ # Run linter with auto-correct
20
+ rake rubocop
21
+ ```
22
+
23
+ ## Architecture
24
+
25
+ ### Core Classes (lib/rake/gem/maintenance/)
26
+
27
+ - **UpgradeTask** — Rake::TaskLib subclass defining upgrade:* tasks (branch, gems, commit, push, auto)
28
+ - Default repositories: rubygems.org
29
+ - **InternalUpgradeTask** — Rake::TaskLib subclass for internal gems only
30
+ - Default repositories: gems.cbp-org.internal
31
+ - **DualUpgradeTask** — Rake::TaskLib subclass for gems published to both rubygems.org and cbp-org
32
+ - Default repositories: both rubygems.org and cbp-org.internal
33
+ - **VersionBumpTask** — Rake::TaskLib subclass defining version:bump[type] and bump[type] tasks
34
+ - **GemPublisher** — Handles publishing gems to multiple repositories, collecting warnings for failed pushes
35
+ - **Repos** — Pre-configured repository sets (internal, all, rubygems, default)
36
+
37
+ ### Entry Points
38
+
39
+ - `rake/gem/maintenance.rb` — requires all task classes
40
+ - `rake/gem/maintenance/install_tasks.rb` — auto-instantiates UpgradeTask and VersionBumpTask with defaults
41
+
42
+ ### Quick Usage
43
+
44
+ ```ruby
45
+ # Internal gems only (cbp-org.internal)
46
+ Rake::Gem::Maintenance::InternalUpgradeTask.new
47
+
48
+ # Both repositories
49
+ Rake::Gem::Maintenance::DualUpgradeTask.new
50
+
51
+ # Default (rubygems.org) - can also use Repos module
52
+ Rake::Gem::Maintenance::UpgradeTask.new do |t|
53
+ t.gem_repositories = Rake::Gem::Maintenance::Repos.internal # or Repos.all
54
+ end
55
+ ```
56
+
57
+ ## Repository & CI Workflow
58
+
59
+ **GitHub** (`github.com/cbroult/rake-gem-maintenance`) is the canonical source.
60
+ **Forgejo** (`git.cbp-org.internal/forgejo-admin/rake-gem-maintenance`) is a read-only pull mirror.
61
+
62
+ - All pull requests go on **GitHub only**. Never open PRs on Forgejo.
63
+ - Forgejo mirrors GitHub automatically every 10 minutes — never push to the `forgejo` remote manually.
64
+ - **Woodpecker CI** (`ci.cbp-org.internal`) watches Forgejo and runs verify/publish/renew pipelines.
65
+ - Local clone only needs the `origin` (GitHub) remote. Remove `forgejo` if present: `git remote remove forgejo`.
66
+
67
+ ## Code Style
68
+
69
+ - Never add `# rubocop:disable` comments without explicit user permission.
70
+
71
+ ## Commit Conventions
72
+
73
+ - Every commit MUST use the conventional commit format: `type(scope): subject`
74
+ - Allowed types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`, `ci`
75
+ - Scope is optional; use it when the change targets one task class or area (e.g. `fix(upgrade):`)
76
+ - Keep subject line under 50 characters
77
+ - Use present tense ("add feature" not "added feature")
78
+ - Split unrelated changes into separate commits, one logical change per commit
data/CLAUDE.md CHANGED
@@ -1,75 +1,3 @@
1
1
  # CLAUDE.md
2
+ @AGENTS.md
2
3
 
3
- ## Project Overview
4
-
5
- rake-gem-maintenance is a Ruby gem providing reusable Rake::TaskLib subclasses for gem maintenance workflows: dependency upgrades and version bumps.
6
-
7
- ## Common Commands
8
-
9
- ```bash
10
- # Install dependencies
11
- bundle install
12
-
13
- # Run all verification (specs + rubocop)
14
- rake
15
-
16
- # Run RSpec tests only
17
- rake spec
18
-
19
- # Run linter with auto-correct
20
- rake rubocop
21
- ```
22
-
23
- ## Architecture
24
-
25
- ### Core Classes (lib/rake/gem/maintenance/)
26
-
27
- - **UpgradeTask** — Rake::TaskLib subclass defining upgrade:* tasks (branch, gems, commit, push, auto)
28
- - Default repositories: rubygems.org
29
- - **InternalUpgradeTask** — Rake::TaskLib subclass for internal gems only
30
- - Default repositories: gems.cbp-org.internal
31
- - **DualUpgradeTask** — Rake::TaskLib subclass for gems published to both rubygems.org and cbp-org
32
- - Default repositories: both rubygems.org and cbp-org.internal
33
- - **VersionBumpTask** — Rake::TaskLib subclass defining version:bump[type] and bump[type] tasks
34
- - **GemPublisher** — Handles publishing gems to multiple repositories, collecting warnings for failed pushes
35
- - **Repos** — Pre-configured repository sets (internal, all, rubygems, default)
36
-
37
- ### Entry Points
38
-
39
- - `rake/gem/maintenance.rb` — requires all task classes
40
- - `rake/gem/maintenance/install_tasks.rb` — auto-instantiates UpgradeTask and VersionBumpTask with defaults
41
-
42
- ### Quick Usage
43
-
44
- ```ruby
45
- # Internal gems only (cbp-org.internal)
46
- Rake::Gem::Maintenance::InternalUpgradeTask.new
47
-
48
- # Both repositories
49
- Rake::Gem::Maintenance::DualUpgradeTask.new
50
-
51
- # Default (rubygems.org) - can also use Repos module
52
- Rake::Gem::Maintenance::UpgradeTask.new do |t|
53
- t.gem_repositories = Rake::Gem::Maintenance::Repos.internal # or Repos.all
54
- end
55
- ```
56
-
57
- ## Repository & CI Workflow
58
-
59
- **GitHub** (`github.com/cbroult/rake-gem-maintenance`) is the canonical source.
60
- **Forgejo** (`git.cbp-org.internal/forgejo-admin/rake-gem-maintenance`) is a read-only pull mirror.
61
-
62
- - All pull requests go on **GitHub only**. Never open PRs on Forgejo.
63
- - Forgejo mirrors GitHub automatically every 10 minutes — never push to the `forgejo` remote manually.
64
- - **Woodpecker CI** (`ci.cbp-org.internal`) watches Forgejo and runs verify/publish/renew pipelines.
65
- - Local clone only needs the `origin` (GitHub) remote. Remove `forgejo` if present: `git remote remove forgejo`.
66
-
67
- ## Code Style
68
-
69
- - Never add `# rubocop:disable` comments without explicit user permission.
70
-
71
- ## Commit Conventions
72
-
73
- - Use conventional commit format: `type(scope): subject`
74
- - Keep subject line under 50 characters
75
- - Use present tense ("add feature" not "added feature")
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rake-gem-maintenance (0.2.2)
4
+ rake-gem-maintenance (0.3.1)
5
5
  bundler-audit
6
6
  gem-release
7
7
  rake
@@ -10,7 +10,7 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- aruba (2.4.0)
13
+ aruba (2.4.1)
14
14
  bundler (>= 1.17)
15
15
  contracts (>= 0.16.0, < 0.18.0)
16
16
  cucumber (>= 8.0, < 12.0)
@@ -26,7 +26,7 @@ GEM
26
26
  thor (~> 1.0)
27
27
  coderay (1.1.3)
28
28
  contracts (0.17.3)
29
- cucumber (11.0.0)
29
+ cucumber (11.1.1)
30
30
  base64 (~> 0.2)
31
31
  builder (~> 3.2)
32
32
  cucumber-ci-environment (> 9, < 12)
@@ -43,7 +43,7 @@ GEM
43
43
  cucumber-gherkin (> 36, < 40)
44
44
  cucumber-messages (> 31, < 33)
45
45
  cucumber-tag-expressions (> 6, < 9)
46
- cucumber-cucumber-expressions (19.0.0)
46
+ cucumber-cucumber-expressions (19.0.1)
47
47
  bigdecimal
48
48
  cucumber-gherkin (39.1.0)
49
49
  cucumber-messages (>= 31, < 33)
@@ -51,14 +51,13 @@ GEM
51
51
  cucumber-messages (> 23, < 33)
52
52
  cucumber-messages (32.3.1)
53
53
  cucumber-tag-expressions (8.1.0)
54
- date (3.5.1)
55
54
  diff-lcs (1.6.2)
56
- erb (6.0.4)
55
+ erb (6.0.7)
57
56
  ffi (1.17.4-x86_64-linux-gnu)
58
57
  formatador (1.2.3)
59
58
  reline
60
59
  gem-release (2.2.4)
61
- guard (2.20.1)
60
+ guard (2.20.2)
62
61
  formatador (>= 0.2.4)
63
62
  listen (>= 2.7, < 4.0)
64
63
  logger (~> 1.6)
@@ -83,14 +82,14 @@ GEM
83
82
  guard-rubocop (1.5.0)
84
83
  guard (~> 2.0)
85
84
  rubocop (< 2.0)
86
- io-console (0.8.2)
85
+ io-console (0.9.2)
87
86
  irb (1.18.0)
88
87
  pp (>= 0.6.0)
89
88
  prism (>= 1.3.0)
90
89
  rdoc (>= 4.0.0)
91
90
  reline (>= 0.4.2)
92
- json (2.19.5)
93
- language_server-protocol (3.17.0.5)
91
+ json (2.21.2)
92
+ language_server-protocol (3.17.0.6)
94
93
  lint_roller (1.1.0)
95
94
  listen (3.10.0)
96
95
  logger
@@ -108,10 +107,10 @@ GEM
108
107
  shellany (~> 0.0)
109
108
  ostruct (0.6.3)
110
109
  parallel (2.1.0)
111
- parser (3.3.11.1)
110
+ parser (3.3.12.0)
112
111
  ast (~> 2.4.1)
113
112
  racc
114
- pp (0.6.3)
113
+ pp (0.6.4)
115
114
  prettyprint
116
115
  prettyprint (0.2.0)
117
116
  prism (1.9.0)
@@ -119,21 +118,23 @@ GEM
119
118
  coderay (~> 1.1)
120
119
  method_source (~> 1.0)
121
120
  reline (>= 0.6.0)
122
- psych (5.3.1)
123
- date
124
- stringio
125
121
  racc (1.8.1)
126
122
  rainbow (3.1.1)
127
123
  rake (13.4.2)
128
124
  rb-fsevent (0.11.2)
129
125
  rb-inotify (0.11.1)
130
126
  ffi (~> 1.0)
131
- rdoc (7.2.0)
127
+ rbs (4.2.0)
128
+ logger
129
+ prism (>= 1.6.0)
130
+ tsort
131
+ rdoc (8.0.0)
132
132
  erb
133
- psych (>= 4.0.0)
133
+ prism (>= 1.6.0)
134
+ rbs (>= 4.0.0)
134
135
  tsort
135
136
  regexp_parser (2.12.0)
136
- reline (0.6.3)
137
+ reline (0.7.0)
137
138
  io-console (~> 0.5)
138
139
  rotp (6.3.0)
139
140
  rspec (3.13.2)
@@ -149,8 +150,8 @@ GEM
149
150
  diff-lcs (>= 1.2.0, < 2.0)
150
151
  rspec-support (~> 3.13.0)
151
152
  rspec-support (3.13.7)
152
- rubocop (1.86.2)
153
- json (~> 2.3)
153
+ rubocop (1.90.0)
154
+ json (>= 2.3)
154
155
  language_server-protocol (~> 3.17.0.2)
155
156
  lint_roller (~> 1.1.0)
156
157
  parallel (>= 1.10)
@@ -160,18 +161,18 @@ GEM
160
161
  rubocop-ast (>= 1.49.0, < 2.0)
161
162
  ruby-progressbar (~> 1.7)
162
163
  unicode-display_width (>= 2.4.0, < 4.0)
163
- rubocop-ast (1.49.1)
164
+ rubocop-ast (1.50.0)
164
165
  parser (>= 3.3.7.2)
165
166
  prism (~> 1.7)
166
167
  rubocop-rake (0.7.1)
167
168
  lint_roller (~> 1.1)
168
169
  rubocop (>= 1.72.1)
169
- rubocop-rspec (3.9.0)
170
+ rubocop-rspec (3.10.2)
170
171
  lint_roller (~> 1.1)
171
- rubocop (~> 1.81)
172
+ regexp_parser (>= 2.0)
173
+ rubocop (~> 1.86, >= 1.86.2)
172
174
  ruby-progressbar (1.13.0)
173
175
  shellany (0.0.1)
174
- stringio (3.2.0)
175
176
  sys-uname (1.5.1)
176
177
  ffi (~> 1.1)
177
178
  memoist3 (~> 1.0.0)
@@ -201,7 +202,7 @@ DEPENDENCIES
201
202
  rubocop-rspec
202
203
 
203
204
  CHECKSUMS
204
- aruba (2.4.0) sha256=92bb696efb06b1aa1dc3ff8b13ca71cd727e59d27572f9264216b9722b558299
205
+ aruba (2.4.1) sha256=c6821949136bd9c953b3cf553971c4780faa26bb40082ac5ce631c541e0caf0d
205
206
  ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
206
207
  base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
207
208
  bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
@@ -209,30 +210,29 @@ CHECKSUMS
209
210
  bundler-audit (0.9.3) sha256=81c8766c71e47d0d28a0f98c7eed028539f21a6ea3cd8f685eb6f42333c9b4e9
210
211
  coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b
211
212
  contracts (0.17.3) sha256=e72e626413ea47099becb7b5683beb1c2ea902c69f5bad55c9258fe2b48314d7
212
- cucumber (11.0.0) sha256=14bb964cc172999e9010fece2fad9f104044b055b3199230091894637a2a784c
213
+ cucumber (11.1.1) sha256=dedd44f4a14b50af798c13b50c3221afa41be8051f5fce666c37cd09f8564ec4
213
214
  cucumber-ci-environment (11.0.0) sha256=0df79a9e1d0b015b3d9def680f989200d96fef206f4d19ccf86a338c4f71d1e2
214
215
  cucumber-core (16.2.0) sha256=592b58a95cf42feef8e5a349f68e363784ba3b6568ffbcf6776e38e136cf970b
215
- cucumber-cucumber-expressions (19.0.0) sha256=33208ff204732ac9bed42b46993a0a243054f71ece08579d57e53df6a1c9d93a
216
+ cucumber-cucumber-expressions (19.0.1) sha256=648ec09045190d818fb797af46e1648148599fd67a086a34a7f0e647d9e36c8c
216
217
  cucumber-gherkin (39.1.0) sha256=aed12a0c955d8563d80a012633c1a72075525f4d64d4cc983001df2181b379ed
217
218
  cucumber-html-formatter (23.1.0) sha256=7789b4a792c876394b9604aeb66aa5cf4c61514473b7e712c76d5eaedcdd8cdf
218
219
  cucumber-messages (32.3.1) sha256=ddc88e4c1cf7afb96c06005b92a4a6f221a2fa435a8b4ca04677d215fd82771c
219
220
  cucumber-tag-expressions (8.1.0) sha256=9bd8c4b6654f8e5bf2a9c99329b6f32136a75e50cd39d4cfb3927d0fa9f52e21
220
- date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
221
221
  diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
222
- erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9
222
+ erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92
223
223
  ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
224
224
  formatador (1.2.3) sha256=19fa898133c2c26cdbb5d09f6998c1e137ad9427a046663e55adfe18b950d894
225
225
  gem-release (2.2.4) sha256=2f11124c1580c811507c3b47e875e420cf3ed792a98105b49df11971e6e94db3
226
- guard (2.20.1) sha256=ab9cd7873854e6b76080c0589f781ff3e390e441bdda20165804df54f977015a
226
+ guard (2.20.2) sha256=2d0574d35619669f2f71739a0313290810b9cf66b2263f5d97e815fcce598d4d
227
227
  guard-bundler (3.1.0) sha256=d0e60e46d6c06e201e79f61623211f64961cb000188f55fb76e36dc892ff0e35
228
228
  guard-compat (1.2.1) sha256=3ad21ab0070107f92edfd82610b5cdc2fb8e368851e72362ada9703443d646fe
229
229
  guard-cucumber (3.0.0) sha256=6a21b666e2b5a927c7d046f4e6cf609ec057e226bf883f066a650e57e04aeac0
230
230
  guard-rspec (4.7.3) sha256=a47ba03cbd1e3c71e6ae8645cea97e203098a248aede507461a43e906e2f75ca
231
231
  guard-rubocop (1.5.0) sha256=3041d796dcb5ee31e352de74732250826f5f235b4ff48df9dbf424a6dc736251
232
- io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
232
+ io-console (0.9.2) sha256=efa74f891dd03c0939a931dfc6e74c2813d904763d456ea9762b0525e748db08
233
233
  irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
234
- json (2.19.5) sha256=218a18553e4801d579ca7e0f5bc72bafd776d7397238a1fb4e74db5b0a812c59
235
- language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
234
+ json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
235
+ language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
236
236
  lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
237
237
  listen (3.10.0) sha256=c6e182db62143aeccc2e1960033bebe7445309c7272061979bb098d03760c9d2
238
238
  logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
@@ -245,34 +245,33 @@ CHECKSUMS
245
245
  notiffany (0.1.3) sha256=d37669605b7f8dcb04e004e6373e2a780b98c776f8eb503ac9578557d7808738
246
246
  ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912
247
247
  parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356
248
- parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54
249
- pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
248
+ parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828
249
+ pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570
250
250
  prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
251
251
  prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
252
252
  pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e
253
- psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
254
253
  racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
255
254
  rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
256
255
  rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
257
- rake-gem-maintenance (0.2.2)
256
+ rake-gem-maintenance (0.3.1)
258
257
  rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe
259
258
  rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e
260
- rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
259
+ rbs (4.2.0) sha256=51f7b886dcc05bc09e10b901daa6a81829f6adc03101d6ca9ea4aac6103e0674
260
+ rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469
261
261
  regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
262
- reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
262
+ reline (0.7.0) sha256=5b012d8e55dbf9d450f12bde2cf7d15ff546ae80b3f8f3b30e570d431815583d
263
263
  rotp (6.3.0) sha256=75d40087e65ed0d8022c33055a6306c1c400d1c12261932533b5d6cbcd868854
264
264
  rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
265
265
  rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
266
266
  rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
267
267
  rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
268
268
  rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
269
- rubocop (1.86.2) sha256=bb2e97f635eda42c448f2588f4a6ff78f221b8bdfdf65b1e9b07fbd57521b45d
270
- rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
269
+ rubocop (1.90.0) sha256=9eb4c065b5c5154e4ef554c547972f3905a9eb6b53e657e580b6796b54bf8242
270
+ rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db
271
271
  rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
272
- rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2
272
+ rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2
273
273
  ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
274
274
  shellany (0.0.1) sha256=0e127a9132698766d7e752e82cdac8250b6adbd09e6c0a7fbbb6f61964fedee7
275
- stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
276
275
  sys-uname (1.5.1) sha256=784d7e6491b0393c25cbbe5ac38324ac7be9fda083a6094832648af669386d7b
277
276
  thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
278
277
  tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
@@ -32,7 +32,7 @@ module Rake
32
32
 
33
33
  def env_credential(var)
34
34
  value = ENV.fetch(var, nil)
35
- value&.empty? ? nil : value
35
+ value && value.empty? ? nil : value
36
36
  end
37
37
 
38
38
  def persist_to_woodpecker(new_key)
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+ require "rake/tasklib"
5
+ require "net/http"
6
+ require "openssl"
7
+ require "base64"
8
+ require "open3"
9
+
10
+ module Rake
11
+ module Gem
12
+ module Maintenance
13
+ # Defines `version:ci_bump` — auto-bump for CI push pipelines.
14
+ #
15
+ # Checks whether the current version is already published at the configured
16
+ # registry. If yes: patch-bumps, commits with [skip ci], tags, and pushes.
17
+ # If no: assumes the developer already bumped and does nothing.
18
+ # Either way skips if the HEAD commit message contains any skip_pattern.
19
+ #
20
+ # Usage in Rakefile:
21
+ # Rake::Gem::Maintenance::CiVersionBumpTask.new do |t|
22
+ # t.registry_url = 'https://gems.cbp-org.internal'
23
+ # t.ca_cert_env = 'CBP_ORG_CA_CERT' # base64-encoded PEM, optional
24
+ # t.push_token_env = 'FORGEJO_PUSH_TOKEN' # token for git push auth, optional
25
+ # end
26
+ class CiVersionBumpTask < ::Rake::TaskLib
27
+ attr_accessor :registry_url, :ca_cert_env, :push_token_env,
28
+ :skip_patterns, :push_branch, :git_author_email, :git_author_name
29
+
30
+ def initialize
31
+ super
32
+ @registry_url = "https://rubygems.org"
33
+ @ca_cert_env = nil
34
+ @push_token_env = nil
35
+ @skip_patterns = ["[skip bump]", "[skip ci]"]
36
+ @push_branch = "main"
37
+ @git_author_email = "ci@cbp-org.internal"
38
+ @git_author_name = "CBP-Org-CI"
39
+ yield self if block_given?
40
+ define_tasks
41
+ end
42
+
43
+ private
44
+
45
+ def define_tasks
46
+ desc "CI auto-bump: patch-bump if already published; skip if developer already bumped"
47
+ task "version:ci_bump" do
48
+ run_ci_bump
49
+ end
50
+ end
51
+
52
+ def run_ci_bump
53
+ return if head_opts_out?
54
+
55
+ current = current_version
56
+ if already_published?(current)
57
+ puts "auto-bump: #{current} is already published — bumping patch"
58
+ perform_bump(current)
59
+ else
60
+ puts "auto-bump: #{current} not yet published — no action needed"
61
+ end
62
+ end
63
+
64
+ def head_opts_out?
65
+ msg = head_commit_message
66
+ return false unless skip?(msg)
67
+
68
+ puts "auto-bump: HEAD opts out — leaving version alone"
69
+ true
70
+ end
71
+
72
+ def perform_bump(current)
73
+ system("git checkout -- .") or abort("auto-bump: git checkout failed")
74
+ system("bundle exec gem bump --version patch --file #{version_file} --no-commit") or
75
+ abort("auto-bump: gem bump failed")
76
+ new_version = current_version
77
+ abort("auto-bump: gem bump did not change version") if new_version == current
78
+ puts "auto-bump: bumped to #{new_version}"
79
+ commit_and_push(new_version)
80
+ end
81
+
82
+ def commit_and_push(new_version)
83
+ git_cfg = ["-c", "user.email=#{git_author_email}", "-c", "user.name=#{git_author_name}"]
84
+ system("git", *git_cfg, "add", version_file) or abort("auto-bump: git add failed")
85
+ system("git", *git_cfg, "commit", "-m",
86
+ "chore: auto-bump version to #{new_version} [skip ci]") or
87
+ abort("auto-bump: git commit failed")
88
+ system("git", "tag", "v#{new_version}") or abort("auto-bump: git tag failed")
89
+ system("git", "push", authenticated_url(origin_url), "HEAD:#{push_branch}",
90
+ "--tags") or abort("auto-bump: git push failed")
91
+ puts "auto-bump: pushed v#{new_version}"
92
+ end
93
+
94
+ def skip?(message)
95
+ skip_patterns.any? { |pattern| message.include?(pattern) }
96
+ end
97
+
98
+ def head_commit_message
99
+ stdout, status = Open3.capture2("git log -1 --pretty=%B")
100
+ status.success? ? stdout.strip : abort("auto-bump: git log failed")
101
+ end
102
+
103
+ def origin_url
104
+ url, status = Open3.capture2("git remote get-url origin")
105
+ status.success? ? url.strip : abort("auto-bump: could not determine origin URL")
106
+ end
107
+
108
+ def current_version
109
+ content = File.read(version_file)
110
+ content[/VERSION\s*=\s*['"]([^'"]+)['"]/, 1] ||
111
+ abort("auto-bump: could not parse VERSION from #{version_file}")
112
+ end
113
+
114
+ def already_published?(version)
115
+ uri = URI("#{registry_url}/gems/#{gem_name}-#{version}.gem")
116
+ res = Net::HTTP.start(uri.host, uri.port,
117
+ use_ssl: true, cert_store: build_cert_store,
118
+ verify_mode: OpenSSL::SSL::VERIFY_PEER) { |h| h.head(uri.path) }
119
+ res.is_a?(Net::HTTPSuccess)
120
+ rescue StandardError
121
+ false
122
+ end
123
+
124
+ def build_cert_store
125
+ store = OpenSSL::X509::Store.new
126
+ store.set_default_paths
127
+ if ca_cert_env && (b64 = ENV.fetch(ca_cert_env, nil))
128
+ store.add_cert(OpenSSL::X509::Certificate.new(Base64.decode64(b64)))
129
+ end
130
+ store
131
+ end
132
+
133
+ def authenticated_url(url)
134
+ return url unless push_token_env && (token = ENV.fetch(push_token_env, nil))
135
+
136
+ url.sub("https://", "https://x-access-token:#{token}@")
137
+ end
138
+
139
+ def version_file
140
+ @version_file ||= Dir.glob("lib/**/version.rb").first
141
+ end
142
+
143
+ def gem_name
144
+ @gem_name ||= ::Gem::Specification.load(Dir.glob("*.gemspec").first).name
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -8,6 +8,8 @@ module Rake
8
8
  module Maintenance
9
9
  # Publishes gems to multiple gem repositories, with version checking and warning handling.
10
10
  class GemPublisher
11
+ JSON_ACCEPT_HEADER = { "Accept" => "application/json" }.freeze
12
+
11
13
  attr_reader :repositories, :warnings, :failed_repositories, :successful_repos
12
14
 
13
15
  def initialize(repositories = default_repositories,
@@ -42,15 +44,14 @@ module Rake
42
44
  end
43
45
 
44
46
  def versions_on_repository(gem_name, repository)
45
- url = "#{repository[:url]}/api/v1/gems/#{gem_name}.json"
46
- uri = URI.parse(url)
47
- response = uri.read(accept: "application/json")
48
- data = JSON.parse(response)
49
- data["versions"].map { |v| v["number"] }
47
+ response = URI.parse(versions_url(gem_name, repository)).read(JSON_ACCEPT_HEADER)
48
+ version_numbers(JSON.parse(response))
49
+ rescue OpenURI::HTTPError => e
50
+ return [] if gem_not_found?(e)
51
+
52
+ record_fetch_failure(repository, e)
50
53
  rescue StandardError => e
51
- @failed_repositories << repository[:name]
52
- @warnings << { repository: repository[:name], error: "Cannot fetch versions: #{e.message}" }
53
- []
54
+ record_fetch_failure(repository, e)
54
55
  end
55
56
 
56
57
  def next_version(gem_name, current_version)
@@ -74,6 +75,25 @@ module Rake
74
75
 
75
76
  private
76
77
 
78
+ def versions_url(gem_name, repository)
79
+ "#{repository[:url]}/api/v1/versions/#{gem_name}.json"
80
+ end
81
+
82
+ def version_numbers(data)
83
+ versions = data.is_a?(Hash) ? data["versions"] : data
84
+ (versions || []).map { |version| version["number"] }.compact
85
+ end
86
+
87
+ def gem_not_found?(error)
88
+ error.io.status.first.to_s == "404"
89
+ end
90
+
91
+ def record_fetch_failure(repository, error)
92
+ @failed_repositories << repository[:name]
93
+ @warnings << { repository: repository[:name], error: "Cannot fetch versions: #{error.message}" }
94
+ []
95
+ end
96
+
77
97
  def build_and_push(gem_file)
78
98
  repositories.each do |repo|
79
99
  push(gem_file, repository: repo)
@@ -39,7 +39,7 @@ module Rake
39
39
  def prompt_for_otp(repository_name)
40
40
  print "Enter OTP for #{repository_name} (blank to skip): "
41
41
  value = @input.gets&.chomp
42
- value&.empty? ? nil : value
42
+ value && value.empty? ? nil : value
43
43
  end
44
44
  end
45
45
  end
@@ -93,7 +93,7 @@ module Rake
93
93
 
94
94
  def env_credential(env_var)
95
95
  value = ENV.fetch(env_var, nil)
96
- value&.empty? ? nil : value
96
+ value && value.empty? ? nil : value
97
97
  end
98
98
 
99
99
  def prompt_username
@@ -257,37 +257,34 @@ module Rake
257
257
  sh "git push origin #{upgrade_branch}"
258
258
  end
259
259
 
260
- # rubocop:disable Metrics/AbcSize
261
260
  def check_version_on_repositories
262
- unless gem_name && gem_version
263
- puts "[ERROR] No gemspec found - cannot check version/upgrade"
264
- abort
265
- end
261
+ abort_without_gemspec unless gem_name && gem_version
266
262
 
267
263
  publisher = gem_publisher_class.new(gem_repositories)
268
- gemspec_repos = gem_repositories.select { |repo| repo_available?(repo) }
269
-
270
- if gemspec_repos.empty?
271
- puts "[ERROR] No repositories available. Cannot check version."
272
- abort
273
- end
274
-
275
264
  publisher.check_all_repositories(gem_name)
276
265
 
266
+ return unless repos_available?(publisher)
267
+
277
268
  print_failed_repository_warnings(publisher)
278
- version = gem_version
279
- next_ver = publisher.next_version(gem_name, version)
269
+ report_version_status(publisher)
270
+ handle_partial_publish_warning(publisher, gem_version)
271
+ end
280
272
 
281
- if next_ver == version
282
- puts "[INFO] Version #{version} not found on any repository - will publish"
273
+ def abort_without_gemspec
274
+ puts "[ERROR] No gemspec found - cannot check version/upgrade"
275
+ abort
276
+ end
277
+
278
+ def report_version_status(publisher)
279
+ next_ver = publisher.next_version(gem_name, gem_version)
280
+
281
+ if next_ver == gem_version
282
+ puts "[INFO] Version #{gem_version} not found on any repository - will publish"
283
283
  else
284
- puts "[INFO] Version #{version} already published to all repositories"
284
+ puts "[INFO] Version #{gem_version} already published to all repositories"
285
285
  puts "[INFO] Next available version: #{next_ver}"
286
286
  end
287
-
288
- handle_partial_publish_warning(publisher, version)
289
287
  end
290
- # rubocop:enable Metrics/AbcSize
291
288
 
292
289
  def handle_partial_publish_warning(publisher, version)
293
290
  return if publisher.successful_repos.empty?
@@ -3,7 +3,7 @@
3
3
  module Rake
4
4
  module Gem
5
5
  module Maintenance
6
- VERSION = "0.2.2"
6
+ VERSION = "0.3.1"
7
7
  end
8
8
  end
9
9
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "maintenance/version"
4
4
  require_relative "maintenance/version_bump_task"
5
+ require_relative "maintenance/ci_version_bump_task"
5
6
  require_relative "maintenance/ci_environment"
6
7
  require_relative "maintenance/credential_store"
7
8
  require_relative "maintenance/ruby_version_checker"
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/rake/gem/maintenance/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "rake-gem-maintenance"
7
+ spec.version = Rake::Gem::Maintenance::VERSION
8
+ spec.authors = ["Christophe Broult"]
9
+ spec.email = ["cbroult@yahoo.com"]
10
+
11
+ spec.summary = "Rake tasks for gem maintenance: dependency upgrades and version bumps."
12
+ spec.description = "Provides reusable Rake::TaskLib subclasses for upgrading gem dependencies and bumping versions."
13
+ spec.homepage = "https://github.com/cbroult/rake-gem-maintenance"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 3.3.7"
16
+
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = File.join(spec.homepage, "Changelog")
20
+ spec.metadata["rubygems_mfa_required"] = "true"
21
+
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
+ end
26
+ end
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency "bundler-audit"
30
+ spec.add_dependency "gem-release"
31
+ spec.add_dependency "rake"
32
+ spec.add_dependency "rotp"
33
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rake-gem-maintenance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christophe Broult
@@ -78,6 +78,7 @@ files:
78
78
  - ".woodpecker/publish.yml"
79
79
  - ".woodpecker/renew_api_key.yml"
80
80
  - ".woodpecker/verify.yml"
81
+ - AGENTS.md
81
82
  - CLAUDE.md
82
83
  - Gemfile
83
84
  - Gemfile.lock
@@ -89,6 +90,7 @@ files:
89
90
  - lib/rake/gem/maintenance.rb
90
91
  - lib/rake/gem/maintenance/api_key_renewer.rb
91
92
  - lib/rake/gem/maintenance/ci_environment.rb
93
+ - lib/rake/gem/maintenance/ci_version_bump_task.rb
92
94
  - lib/rake/gem/maintenance/credential_store.rb
93
95
  - lib/rake/gem/maintenance/gem_publisher.rb
94
96
  - lib/rake/gem/maintenance/gem_push.rb
@@ -104,6 +106,7 @@ files:
104
106
  - lib/rake/gem/maintenance/version.rb
105
107
  - lib/rake/gem/maintenance/version_bump_task.rb
106
108
  - lib/rake/gem/maintenance/woodpecker_secret_store.rb
109
+ - rake-gem-maintenance.gemspec
107
110
  - scripts/ci_publish_rubygems.rb
108
111
  homepage: https://github.com/cbroult/rake-gem-maintenance
109
112
  licenses:
@@ -127,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
130
  - !ruby/object:Gem::Version
128
131
  version: '0'
129
132
  requirements: []
130
- rubygems_version: 4.0.10
133
+ rubygems_version: 4.0.19
131
134
  specification_version: 4
132
135
  summary: 'Rake tasks for gem maintenance: dependency upgrades and version bumps.'
133
136
  test_files: []