kettle-dev 2.0.8 → 2.1.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: 4cd7fe54eb870c3b29cd7f317c335f06dd69d4c3d924686b835bbba97f42bbed
4
- data.tar.gz: 1ce512b94f7fbd3089ae283c51128e526c9b48d825204409795e1c60d9c689dd
3
+ metadata.gz: 41074cb0fabc348cfb17e29cfb521661c4492792a7c5e3fab1ff32815f960355
4
+ data.tar.gz: d65ce417666381f6cf72ac7f6cdcd6bea0be35c996c820d16765789229408bc9
5
5
  SHA512:
6
- metadata.gz: deb60bf014b1a739225b8478d9337a06c94ae40fa57edaa0a654603a3dd04eca76ad8bc88086bbde824de19477f82a8c6bd4537c6a59dd76d3b6a51304888005
7
- data.tar.gz: 78e31f3c9ae1052e3009d8055d1ac17dcf93def82827c3fe3ca7d026115195802b9cebf91dd4b29d48990993bf174f5e11616e1e454107eaaa0a42f831730858
6
+ metadata.gz: 100dc6197c4a9329d3ae4e483feb7e3c643160a9a446939c7a3d6bb789a0ca8ba6c41f8231971548b4ba91916e55481469d17b6623998046a1cc302bf96e7825
7
+ data.tar.gz: cd82a9b3ad27598611f94798fa1187171092017cbf8d28b44ff5fd3c82ed021251ba35053683276ac8dc49a77c33035ec02f3c379a42d79fbabd749d25221bba
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,42 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [2.1.1] - 2026-06-06
34
+
35
+ - TAG: [v2.1.1][2.1.1t]
36
+ - COVERAGE: 93.11% -- 2988/3209 lines in 25 files
37
+ - BRANCH COVERAGE: 77.58% -- 1218/1570 branches in 25 files
38
+ - 75.93% documented
39
+
40
+ ### Added
41
+
42
+ - `kettle-release --local-ci` for sensitive releases that run `act` locally,
43
+ publish the gem before any git push, create the release tag locally, and push
44
+ commits and tags only after publishing succeeds.
45
+
46
+ ### Changed
47
+
48
+ - Refreshed kettle-jem template output, including Appraisal2 plugin wiring and
49
+ current dependency floors for `appraisal2`, `appraisal2-rubocop`, and
50
+ `version_gem`.
51
+
52
+ ## [2.1.0] - 2026-06-06
53
+
54
+ - TAG: [v2.1.0][2.1.0t]
55
+ - COVERAGE: 93.52% -- 2973/3179 lines in 25 files
56
+ - BRANCH COVERAGE: 77.58% -- 1204/1552 branches in 25 files
57
+ - 75.93% documented
58
+
59
+ ### Changed
60
+
61
+ - `appraisal:install` now uses `appraisal generate-install`, and
62
+ `appraisal:update` now uses `appraisal generate-update`, preserving
63
+ generation-before-resolution behavior after Appraisal2 split pure install and
64
+ update commands from generation.
65
+ - Appraisal gemfile cleanup is no longer run directly by kettle-dev appraisal
66
+ tasks; projects that need generated gemfile normalization should load an
67
+ Appraisal2 plugin hook such as `appraisal2-rubocop`.
68
+
33
69
  ## [2.0.8] - 2026-06-02
34
70
 
35
71
  - TAG: [v2.0.8][2.0.8t]
@@ -1877,7 +1913,11 @@ Please file a bug if you notice a violation of semantic versioning.
1877
1913
  - Selecting will run the selected workflow via `act`
1878
1914
  - This may move to its own gem in the future.
1879
1915
 
1880
- [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v2.0.8...HEAD
1916
+ [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v2.1.1...HEAD
1917
+ [2.1.1]: https://github.com/kettle-rb/kettle-dev/compare/v2.1.0...v2.1.1
1918
+ [2.1.1t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v2.1.1
1919
+ [2.1.0]: https://github.com/kettle-rb/kettle-dev/compare/v2.0.8...v2.1.0
1920
+ [2.1.0t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v2.1.0
1881
1921
  [2.0.8]: https://github.com/kettle-rb/kettle-dev/compare/v2.0.7...v2.0.8
1882
1922
  [2.0.8t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v2.0.8
1883
1923
  [2.0.7]: https://github.com/kettle-rb/kettle-dev/compare/v2.0.6...v2.0.7
data/LICENSE.md CHANGED
@@ -9,4 +9,4 @@ If none of the above licenses fit your use case, please [contact us](mailto:flos
9
9
 
10
10
  ## Copyright Notice
11
11
 
12
- Copyright (c) 2023, 2025-2026 Peter H. Boling
12
+ - Copyright (c) 2023, 2025-2026 Peter H. Boling
data/README.md CHANGED
@@ -811,7 +811,7 @@ Thanks for RTFM. ☺️
811
811
  [📌gitmoji]: https://gitmoji.dev
812
812
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
813
813
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
814
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.181-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
814
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.209-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
815
815
  [🔐security]: https://github.com/kettle-rb/kettle-dev/blob/main/SECURITY.md
816
816
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
817
817
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -839,7 +839,7 @@ Thanks for RTFM. ☺️
839
839
  | Package | kettle-dev |
840
840
  | Description | 🍲 Kettle::Dev is a meta tool from kettle-rb to streamline development and testing. Acts as a shim dependency, pulling in many other dependencies, to give you OOTB productivity with a RubyGem, or Ruby app project. Configures a complete set of Rake tasks, for all the libraries is brings in, so they arrive ready to go. Fund overlooked open source projects - bottom of stack, dev/test dependencies: floss-funding.dev |
841
841
  | Homepage | https://github.com/kettle-rb/kettle-dev |
842
- | Source | https://github.com/kettle-rb/kettle-dev/tree/v2.0.8 |
842
+ | Source | https://github.com/kettle-rb/kettle-dev/tree/v2.1.0 |
843
843
  | License | `AGPL-3.0-only` |
844
844
  | Funding | https://github.com/sponsors/pboling, https://issuehunt.io/u/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/kettle-rb, https://patreon.com/galtzo, https://polar.sh/pboling, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/kettle-dev, https://www.buymeacoffee.com/pboling |
845
845
  <!-- kettle-jem:metadata:end -->
data/SECURITY.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |----------|-----------|
7
- | 2.0.latest | ✅ |
7
+ | 2.1.latest | ✅ |
8
8
 
9
9
  ## Security contact information
10
10
 
data/exe/kettle-release CHANGED
@@ -43,7 +43,7 @@ end
43
43
  # Do not guard with __FILE__ == $PROGRAM_NAME because binstubs use Kernel.load.
44
44
  if ARGV.include?("-h") || ARGV.include?("--help")
45
45
  puts <<~USAGE
46
- Usage: kettle-release [start_step=<1-19>]
46
+ Usage: kettle-release [--local-ci] [start_step=<1-19>]
47
47
 
48
48
  Automates the release flow for a Ruby gem in the host project.
49
49
 
@@ -70,6 +70,8 @@ if ARGV.include?("-h") || ARGV.include?("--help")
70
70
 
71
71
  Options:
72
72
  start_step=<number> # Begin at the numbered step above (e.g., 10 to resume at CI monitoring)
73
+ --local-ci # Sensitive release mode: run act locally, publish before any git push,
74
+ # create the git tag locally, then push commits and tags after publish
73
75
 
74
76
  Environment:
75
77
  SKIP_GEM_SIGNING=true # Build/release unsigned; avoids PEM password prompts
@@ -82,6 +84,7 @@ if ARGV.include?("-h") || ARGV.include?("--help")
82
84
 
83
85
  Examples:
84
86
  kettle-release # full flow from the top (start_step=1)
87
+ kettle-release --local-ci # run local act CI, publish gem, then push commits/tags
85
88
  kettle-release start_step=10 # resume by monitoring CI for the current branch
86
89
  SKIP_GEM_SIGNING=true kettle-release start_step=14 # build+release without signing
87
90
  USAGE
@@ -89,11 +92,12 @@ if ARGV.include?("-h") || ARGV.include?("--help")
89
92
  end
90
93
 
91
94
  # Parse start_step=<n> from ARGV
95
+ local_ci = ARGV.include?("--local-ci")
92
96
  start_step_arg = ARGV.find { |a| a.start_with?("start_step=") }
93
97
  start_step = start_step_arg ? start_step_arg.split("=", 2)[1].to_i : 1
94
98
 
95
99
  begin
96
- Kettle::Dev::ReleaseCLI.new(start_step: start_step).run
100
+ Kettle::Dev::ReleaseCLI.new(start_step: start_step, local_ci: local_ci).run
97
101
  rescue LoadError => e
98
102
  warn("#{script_basename}: could not load dependency: #{e.class}: #{e.message}")
99
103
  warn(Array(e.backtrace).join("\n")) if ENV["DEBUG"]
@@ -4,24 +4,76 @@
4
4
  begin
5
5
  require "appraisal/task"
6
6
 
7
- desc("Install Appraisal gemfiles (initial setup for projects that didn't previously use Appraisal)")
8
- task("appraisal:install") do
9
- bundle = "bundle"
7
+ bundle = "bundle"
8
+ appraisal_env = {"BUNDLE_GEMFILE" => "Appraisal.root.gemfile"}
10
9
 
11
- run_in_unbundled = proc do
12
- env = {"BUNDLE_GEMFILE" => "Appraisal.root.gemfile"}
10
+ run_command = lambda do |failure_message, *args|
11
+ ok = system(*args)
12
+ raise(failure_message) unless ok
13
+ end
13
14
 
14
- # 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
15
- ok = system(env, bundle, "install")
16
- abort("appraisal:install failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install") unless ok
15
+ run_generate_steps = lambda do
16
+ # 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
17
+ run_command.call(
18
+ "appraisal:generate failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install",
19
+ appraisal_env,
20
+ bundle,
21
+ "install"
22
+ )
23
+
24
+ # 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate
25
+ run_command.call(
26
+ "appraisal:generate failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate",
27
+ appraisal_env,
28
+ bundle,
29
+ "exec",
30
+ "appraisal",
31
+ "generate"
32
+ )
33
+ end
17
34
 
18
- # 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal install
19
- ok = system(env, bundle, "exec", "appraisal", "install")
20
- abort("appraisal:install failed: bundle exec appraisal install") unless ok
35
+ run_appraisal_task = lambda do |task_name, primary_steps = nil|
36
+ begin
37
+ if primary_steps
38
+ begin
39
+ primary_steps.call
40
+ rescue RuntimeError => e
41
+ warn("[kettle-dev][#{task_name}] #{e.message}; falling back to appraisal:generate")
42
+ run_generate_steps.call
43
+ end
44
+ else
45
+ run_generate_steps.call
46
+ end
47
+ rescue RuntimeError => e
48
+ abort(e.message)
49
+ end
50
+ end
21
51
 
22
- # 3) bundle exec rake rubocop_gradual:autocorrect
23
- ok = system(bundle, "exec", "rake", "rubocop_gradual:autocorrect")
24
- abort("appraisal:update failed: rubocop_gradual:autocorrect") unless ok
52
+ desc("Install Appraisal gemfiles (initial setup for projects that didn't previously use Appraisal)")
53
+ task("appraisal:install") do
54
+ run_in_unbundled = proc do
55
+ run_appraisal_task.call(
56
+ "appraisal:install",
57
+ lambda do
58
+ # 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
59
+ run_command.call(
60
+ "appraisal:install failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install",
61
+ appraisal_env,
62
+ bundle,
63
+ "install"
64
+ )
65
+
66
+ # 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate-install
67
+ run_command.call(
68
+ "appraisal:install failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate-install",
69
+ appraisal_env,
70
+ bundle,
71
+ "exec",
72
+ "appraisal",
73
+ "generate-install"
74
+ )
75
+ end
76
+ )
25
77
  end
26
78
 
27
79
  if defined?(Bundler)
@@ -33,18 +85,8 @@ begin
33
85
 
34
86
  desc("Generate Appraisal gemfiles without resolving appraisal locks")
35
87
  task("appraisal:generate") do
36
- bundle = "bundle"
37
-
38
88
  run_in_unbundled = proc do
39
- env = {"BUNDLE_GEMFILE" => "Appraisal.root.gemfile"}
40
-
41
- # 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
42
- ok = system(env, bundle, "install")
43
- abort("appraisal:generate failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install") unless ok
44
-
45
- # 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate
46
- ok = system(env, bundle, "exec", "appraisal", "generate")
47
- abort("appraisal:generate failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate") unless ok
89
+ run_appraisal_task.call("appraisal:generate")
48
90
  end
49
91
 
50
92
  if defined?(Bundler)
@@ -54,32 +96,48 @@ begin
54
96
  end
55
97
  end
56
98
 
57
- desc("Update Appraisal gemfiles and run RuboCop Gradual autocorrect")
99
+ desc("Generate and update Appraisal gemfiles")
58
100
  task("appraisal:update") do
59
- bundle = "bundle"
60
-
61
101
  run_in_unbundled = proc do
62
- env = {"BUNDLE_GEMFILE" => "Appraisal.root.gemfile"}
63
-
64
- # 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
65
- ok = system(env, bundle, "install")
66
- abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install") unless ok
67
-
68
- # 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler
69
- ok = system(env, bundle, "update", "--bundler")
70
- abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler") unless ok
71
-
72
- # 3) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
73
- ok = system(env, bundle, "install")
74
- abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install") unless ok
75
-
76
- # 4) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal update
77
- ok = system(env, bundle, "exec", "appraisal", "update")
78
- abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal update") unless ok
79
-
80
- # 5) bundle exec rake rubocop_gradual:autocorrect
81
- ok = system(bundle, "exec", "rake", "rubocop_gradual:autocorrect")
82
- abort("appraisal:update failed: rubocop_gradual:autocorrect") unless ok
102
+ run_appraisal_task.call(
103
+ "appraisal:update",
104
+ lambda do
105
+ # 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
106
+ run_command.call(
107
+ "appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install",
108
+ appraisal_env,
109
+ bundle,
110
+ "install"
111
+ )
112
+
113
+ # 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler
114
+ run_command.call(
115
+ "appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler",
116
+ appraisal_env,
117
+ bundle,
118
+ "update",
119
+ "--bundler"
120
+ )
121
+
122
+ # 3) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
123
+ run_command.call(
124
+ "appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install",
125
+ appraisal_env,
126
+ bundle,
127
+ "install"
128
+ )
129
+
130
+ # 4) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate-update
131
+ run_command.call(
132
+ "appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal generate-update",
133
+ appraisal_env,
134
+ bundle,
135
+ "exec",
136
+ "appraisal",
137
+ "generate-update"
138
+ )
139
+ end
140
+ )
83
141
  end
84
142
 
85
143
  if defined?(Bundler)
@@ -70,11 +70,12 @@ module Kettle
70
70
 
71
71
  public
72
72
 
73
- def initialize(start_step: 1)
73
+ def initialize(start_step: 1, local_ci: false)
74
74
  @root = Kettle::Dev::CIHelpers.project_root
75
75
  @git = Kettle::Dev::GitAdapter.new
76
76
  @start_step = (start_step || 1).to_i
77
77
  @start_step = 1 if @start_step < 1
78
+ @local_ci = !!local_ci
78
79
  end
79
80
 
80
81
  def run
@@ -206,31 +207,33 @@ module Kettle
206
207
  end
207
208
 
208
209
  # 7. optional local CI via act
209
- maybe_run_local_ci_before_push!(committed) if @start_step <= 7
210
+ maybe_run_local_ci_before_push!(committed, force: local_ci?) if @start_step <= 7
210
211
 
211
212
  # 8. ensure trunk synced
212
- if @start_step <= 8
213
+ if @start_step <= 8 && !local_ci?
213
214
  trunk = detect_trunk_branch
214
215
  feature = current_branch
215
216
  puts "Trunk branch detected: #{trunk}"
216
217
  ensure_trunk_synced_before_push!(trunk, feature)
218
+ elsif @start_step <= 8
219
+ puts "Local CI release mode: skipping remote trunk sync before publishing."
217
220
  end
218
221
 
219
222
  # 9. push branches
220
- push! if @start_step <= 9
223
+ push! if @start_step <= 9 && !local_ci?
221
224
 
222
225
  # 10. monitor CI after push
223
- monitor_workflows_after_push! if @start_step <= 10
226
+ monitor_workflows_after_push! if @start_step <= 10 && !local_ci?
224
227
 
225
228
  # 11. merge feature into trunk and push
226
- if @start_step <= 11
229
+ if @start_step <= 11 && !local_ci?
227
230
  trunk ||= detect_trunk_branch
228
231
  feature ||= current_branch
229
232
  merge_feature_into_trunk_and_push!(trunk, feature)
230
233
  end
231
234
 
232
235
  # 12. checkout trunk and pull
233
- if @start_step <= 12
236
+ if @start_step <= 12 && !local_ci?
234
237
  trunk ||= detect_trunk_branch
235
238
  checkout!(trunk)
236
239
  pull!(trunk)
@@ -265,8 +268,13 @@ module Kettle
265
268
 
266
269
  # 15. release and tag
267
270
  if @start_step <= 15
268
- puts "Running release (you may be prompted for signing key password and RubyGems MFA OTP)..."
269
- run_cmd!("bundle exec rake release")
271
+ if local_ci?
272
+ version ||= detect_version
273
+ release_gem_and_tag_locally!(version)
274
+ else
275
+ puts "Running release (you may be prompted for signing key password and RubyGems MFA OTP)..."
276
+ run_cmd!("bundle exec rake release")
277
+ end
270
278
  end
271
279
 
272
280
  # 16. generate checksums
@@ -281,7 +289,10 @@ module Kettle
281
289
  end
282
290
 
283
291
  # 17. push checksum commit (gem_checksums already commits)
284
- push! if @start_step <= 17
292
+ if @start_step <= 17
293
+ push!
294
+ push_tags! if local_ci?
295
+ end
285
296
 
286
297
  # 18. create GitHub release (optional)
287
298
  if @start_step <= 18
@@ -290,7 +301,7 @@ module Kettle
290
301
  end
291
302
 
292
303
  # 19. push tags to remotes (final step)
293
- push_tags! if @start_step <= 19
304
+ push_tags! if @start_step <= 19 && !local_ci?
294
305
 
295
306
  # Final success message
296
307
  begin
@@ -306,6 +317,10 @@ module Kettle
306
317
 
307
318
  private
308
319
 
320
+ def local_ci?
321
+ @local_ci
322
+ end
323
+
309
324
  # Update the README KLOC badge number based on the denominator in the current version's COVERAGE line in CHANGELOG.md.
310
325
  # - Parses the current version section of CHANGELOG.md
311
326
  # - Finds a line matching: "- COVERAGE: ... -- <tested>/<total> lines ..."
@@ -552,17 +567,22 @@ module Kettle
552
567
  end
553
568
  end
554
569
 
555
- def maybe_run_local_ci_before_push!(committed)
570
+ def maybe_run_local_ci_before_push!(committed, force: false)
556
571
  mode = (ENV["K_RELEASE_LOCAL_CI"] || "").strip.downcase
557
- run_it = case mode
558
- when "true", "1", "yes", "y" then true
559
- when "ask"
560
- print("Run local CI with 'act' before pushing? [Y/n] ")
561
- ans = Kettle::Dev::InputAdapter.gets&.strip
562
- ans.nil? || ans.empty? || /\Ay(es)?\z/i.match?(ans)
563
- else
564
- false
565
- end
572
+ run_it =
573
+ if force
574
+ true
575
+ else
576
+ case mode
577
+ when "true", "1", "yes", "y" then true
578
+ when "ask"
579
+ print("Run local CI with 'act' before pushing? [Y/n] ")
580
+ ans = Kettle::Dev::InputAdapter.gets&.strip
581
+ ans.nil? || ans.empty? || /\Ay(es)?\z/i.match?(ans)
582
+ else
583
+ false
584
+ end
585
+ end
566
586
  return unless run_it
567
587
 
568
588
  act_ok = begin
@@ -572,6 +592,8 @@ module Kettle
572
592
  false
573
593
  end
574
594
  unless act_ok
595
+ msg = "Local CI requires 'act'. Install https://github.com/nektos/act to enable."
596
+ abort(msg) if force
575
597
  puts "Skipping local CI: 'act' command not found. Install https://github.com/nektos/act to enable."
576
598
  return
577
599
  end
@@ -594,12 +616,16 @@ module Kettle
594
616
  end
595
617
 
596
618
  unless chosen
619
+ msg = "Local CI requires at least one workflow under .github/workflows."
620
+ abort(msg) if force
597
621
  puts "Skipping local CI: no workflows found under .github/workflows."
598
622
  return
599
623
  end
600
624
 
601
625
  file_path = File.join(workflows_dir, chosen)
602
626
  unless File.file?(file_path)
627
+ msg = "Local CI selected workflow not found: #{Kettle::Dev.display_path(file_path)}"
628
+ abort(msg) if force
603
629
  puts "Skipping local CI: selected workflow not found: #{Kettle::Dev.display_path(file_path)}"
604
630
  return
605
631
  end
@@ -618,6 +644,25 @@ module Kettle
618
644
  end
619
645
  end
620
646
 
647
+ def release_gem_and_tag_locally!(version)
648
+ tag = "v#{version}"
649
+ gem_path = gem_file_for_version(version)
650
+ unless gem_path && File.file?(gem_path)
651
+ abort("Unable to locate built gem for version #{version} in pkg/. Did the build succeed?")
652
+ end
653
+
654
+ _out, tag_exists = git_output(["rev-parse", "-q", "--verify", "refs/tags/#{tag}"])
655
+ if tag_exists
656
+ puts "Local tag #{tag} already exists."
657
+ else
658
+ puts "Creating local git tag #{tag} without pushing it."
659
+ run_cmd!("git tag -a #{Shellwords.escape(tag)} -m #{Shellwords.escape(tag)}")
660
+ end
661
+
662
+ puts "Publishing #{File.basename(gem_path)} to RubyGems without pushing git refs..."
663
+ run_cmd!("gem push #{Shellwords.escape(gem_path)}")
664
+ end
665
+
621
666
  def detect_version
622
667
  Kettle::Dev::Versioning.detect_version(@root)
623
668
  end
@@ -3,7 +3,7 @@
3
3
  module Kettle
4
4
  module Dev
5
5
  module Version
6
- VERSION = "2.0.8"
6
+ VERSION = "2.1.1"
7
7
  end
8
8
  VERSION = Version::VERSION # Traditional Constant Location
9
9
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kettle-dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.8
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -66,7 +66,7 @@ dependencies:
66
66
  version: '1.1'
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 1.1.9
69
+ version: 1.1.11
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '1.1'
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
- version: 1.1.9
79
+ version: 1.1.11
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: bundler-audit
82
82
  requirement: !ruby/object:Gem::Requirement
@@ -131,20 +131,20 @@ dependencies:
131
131
  requirements:
132
132
  - - "~>"
133
133
  - !ruby/object:Gem::Version
134
- version: '3.0'
134
+ version: '3.1'
135
135
  - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: 3.0.6
137
+ version: 3.1.1
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '3.0'
144
+ version: '3.1'
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
- version: 3.0.6
147
+ version: 3.1.1
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: turbo_tests2
150
150
  requirement: !ruby/object:Gem::Requirement
@@ -332,10 +332,10 @@ licenses:
332
332
  - AGPL-3.0-only
333
333
  metadata:
334
334
  homepage_uri: https://kettle-dev.galtzo.com
335
- source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v2.0.8
336
- changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v2.0.8/CHANGELOG.md
335
+ source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v2.1.1
336
+ changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v2.1.1/CHANGELOG.md
337
337
  bug_tracker_uri: https://github.com/kettle-rb/kettle-dev/issues
338
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.0.8
338
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.1.1
339
339
  funding_uri: https://github.com/sponsors/pboling
340
340
  wiki_uri: https://github.com/kettle-rb/kettle-dev/wiki
341
341
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
Binary file