kettle-dev 3.1.5 → 3.1.7

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: 0e99b028eb7b7f955a4d4c6bc4d62b812d9e8a6a6399d0aadf448e525d9680a4
4
- data.tar.gz: f5432081e590c22460c4876eb1e2e35406bcb1617881eb9814eccd3449e4fb45
3
+ metadata.gz: 2de1266e7cdbbfd6174c040d8602cf8c3349a423bc301f071ba45da206cba969
4
+ data.tar.gz: f93264ee009dbede2c2ff3273a396916a31d51a70b1ac1cab817532e11f396f5
5
5
  SHA512:
6
- metadata.gz: bffb2a5e07b7cb6ea1c225808e4a011c670a6768905052447112e4de5a9e15122fb9f0d3a1f65ed1a3cc80d290271e1844133cd4b64cb2c050b01d7d2f200552
7
- data.tar.gz: 666f1974ea5d780e5b845039dc7923c769869faa50075074986cf165d9773e72848cfd2c200ced47a376ce08f15c01e317294e31a0811895880a25567d033059
6
+ metadata.gz: 6a10b65136115e119f2b24eea184c114ea09ae969bed38f71005f39f0fe2f1f0ef1a9869449cf70cf895f075c0c01387918b02bafb914237ca3136d2f4ef868f
7
+ data.tar.gz: 9e14f9945043f4f104c65e34dae30e11301e84caa63f474555d0befe80a35508d604b331da62306808a927eb881e2a41a66562582896b4145cf22e9051db8c65
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,52 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [3.1.7] - 2026-10-04
34
+
35
+ - TAG: [v3.1.7][3.1.7t]
36
+ - COVERAGE: 91.75% -- 6261/6824 lines in 49 files
37
+ - BRANCH COVERAGE: 76.08% -- 2388/3139 branches in 49 files
38
+ - 51.34% documented
39
+
40
+ ### Added
41
+
42
+ - kettle-release warns when the current branch is not among the release branches its family declares, naming the declaring config and the declared branches, instead of silently treating it as a feature branch destined for trunk.
43
+
44
+ ### Fixed
45
+
46
+ - Branch-stack release detection now also reads `release.member_target_branches.<gem>` from the family root config, so a member whose templated local `.kettle-family.yml` is absent (a fresh branch, or a linked worktree) no longer degrades silently into a trunk pull request and a merge into trunk.
47
+
48
+ - Branch-stack release detection no longer uses block-level `rescue` or `Array#filter_map`, which are Ruby 2.6+ and 2.7+ constructs; the gem supports Ruby 2.4. YAML loading is isolated in `safe_load_kettle_family_config` with a method-level rescue, restoring the explicit `begin`/`end` contract the surrounding code relies on.
49
+
50
+ - Preserve the selected Gemfile and lockfile when Bundler restarts during release lockfile reset.
51
+
52
+ ### Changed
53
+
54
+ - [kc] kettle-jem/prepare: updated 13 project files:
55
+ - dependencies (13)
56
+
57
+ - [kc] kettle-jem/template: updated 7 project files:
58
+ - code and tests (2)
59
+ - dependencies (1)
60
+ - documentation (1)
61
+ - other (2)
62
+ - workflows (1)
63
+
64
+ ## [3.1.6] - 2026-10-02
65
+
66
+ - TAG: [v3.1.6][3.1.6t]
67
+ - COVERAGE: 91.66% -- 6210/6775 lines in 49 files
68
+ - BRANCH COVERAGE: 76.13% -- 2370/3113 branches in 49 files
69
+ - 51.34% documented
70
+
71
+ ### Fixed
72
+
73
+ - Branch-stack releases now dispatch selected GitHub Actions workflows directly on the release branch instead of relying on a possibly conflicted validation PR.
74
+
75
+ - Branch-stack release workflow validation now supports the older Psych API bundled with Ruby 2.4.
76
+
77
+ - YAML loading now selects the supported Psych API by version, including Ruby 2.5 environments that report misleading keyword parameters.
78
+
33
79
  ## [3.1.5] - 2026-09-28
34
80
 
35
81
  - TAG: [v3.1.5][3.1.5t]
@@ -3938,7 +3984,11 @@ Please file a bug if you notice a violation of semantic versioning.
3938
3984
  - Selecting will run the selected workflow via `act`
3939
3985
  - This may move to its own gem in the future.
3940
3986
 
3941
- [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.5...HEAD
3987
+ [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.7...HEAD
3988
+ [3.1.7]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.6...v3.1.7
3989
+ [3.1.7t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.1.7
3990
+ [3.1.6]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.5...v3.1.6
3991
+ [3.1.6t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.1.6
3942
3992
  [3.1.5]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.4...v3.1.5
3943
3993
  [3.1.5t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.1.5
3944
3994
  [3.1.4]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.3...v3.1.4
data/README.md CHANGED
@@ -420,7 +420,8 @@ What it does:
420
420
  - Enable with env: `K_RELEASE_LOCAL_CI="true"` (run automatically) or `K_RELEASE_LOCAL_CI="ask"` (prompt \[Y/n\]).
421
421
  - Select workflow with `K_RELEASE_LOCAL_CI_WORKFLOW` (with or without .yml/.yaml). Defaults to `locked_deps.yml` if present; otherwise the first workflow discovered.
422
422
  - On failure, the release prep commit is soft-rolled-back (`git reset --soft HEAD^`) and the process aborts.
423
- - Ensures trunk sync and rebases feature as needed, pushes, monitors GitHub Actions with a progress bar, and merges feature to trunk on success.
423
+ - Ensures trunk sync and rebases feature branches as needed, pushes, monitors GitHub Actions with a progress bar, and merges feature to trunk on success.
424
+ - For release branches listed in `.kettle-family.yml` branch-stack targets, it intentionally does not pull/rebase from trunk or merge the leaf branch into trunk. Instead, it starts the selected GitHub Actions workflows directly on the pushed release branch; each selected workflow must declare `workflow_dispatch`. This validates the exact branch-stack commit without requiring an often-conflicting PR to trunk.
424
425
  - Exports `SOURCE_DATE_EPOCH`, builds (optionally signed), creates gem checksums, and runs `bundle exec rake release` (prompts for signing key + RubyGems MFA OTP as needed).
425
426
  - Options:
426
427
  - `start_step` map (skip directly to a phase):
@@ -433,11 +434,11 @@ What it does:
433
434
  (or appraisal:update with --appraisal-update)
434
435
  6. Ensure git user configured; commit release prep
435
436
  7. Optional local CI with `act` (controlled by `K_RELEASE_LOCAL_CI`)
436
- 8. Ensure trunk in sync across remotes; rebase feature as needed
437
+ 8. Ensure trunk in sync across remotes; rebase feature as needed (skipped for configured branch-stack release targets)
437
438
  9. Push current branch to remotes (or 'all' remote)
438
- 10. Monitor CI after push; abort on failures
439
- 11. Merge feature into trunk and push
440
- 12. Checkout trunk and pull latest
439
+ 10. Monitor CI after push; configured branch-stack releases dispatch each selected workflow directly on the release branch
440
+ 11. Merge feature into trunk and push (skipped for branch-stack release targets)
441
+ 12. Checkout trunk and pull latest (skipped for branch-stack release targets)
441
442
  13. Gem signing checks/guidance (skip with `SKIP_GEM_SIGNING=true`)
442
443
  14. Build gem (bundle exec rake build)
443
444
  15. Release gem (bundle exec rake release)
@@ -1066,7 +1067,7 @@ Thanks for RTFM. ☺️
1066
1067
  [📌gitmoji]: https://gitmoji.dev
1067
1068
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1068
1069
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1069
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.748-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1070
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.824-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1070
1071
  [🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
1071
1072
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1072
1073
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -201,6 +201,13 @@ module Kettle
201
201
  "BUNDLE_GEMFILE" => gemfile,
202
202
  "BUNDLE_LOCKFILE" => path
203
203
  )
204
+ if update_bundler
205
+ # Bundler's `update --bundler` restarts itself using its original
206
+ # environment. Preserve this reset's selected bundle across that
207
+ # restart instead of falling back to the member's default Gemfile.
208
+ env["BUNDLER_ORIG_BUNDLE_GEMFILE"] = gemfile
209
+ env["BUNDLER_ORIG_BUNDLE_LOCKFILE"] = path
210
+ end
204
211
  env["KETTLE_DEV_SKIP_CHANGELOG_DEPENDENCY"] = "true" if skip_changelog_dependency
205
212
  if isolated_gem_home
206
213
  env["GEM_HOME"] = isolated_gem_home
@@ -1419,7 +1419,7 @@ module Kettle
1419
1419
  end
1420
1420
 
1421
1421
  def monitor_workflows_after_push!
1422
- ensure_github_pull_request_for_ci!
1422
+ ensure_ci_trigger_for_release_branch!
1423
1423
  keep_release_secrets_alive!("CI monitoring")
1424
1424
  restart_hint = "bundle exec kettle-release --start-step 10"
1425
1425
  emit_ci_monitor_event(action: "start", status: "started", workflows: @ci_workflows, restart_hint: restart_hint)
@@ -1452,13 +1452,18 @@ module Kettle
1452
1452
  end
1453
1453
  end
1454
1454
 
1455
- def ensure_github_pull_request_for_ci!
1455
+ def ensure_ci_trigger_for_release_branch!
1456
1456
  branch = current_branch
1457
1457
  return if branch.to_s.empty?
1458
1458
 
1459
1459
  trunk = detect_trunk_branch
1460
1460
  return if branch == trunk
1461
1461
 
1462
+ if branch_stack_release_branch?(branch, trunk)
1463
+ dispatch_github_workflows!(branch: branch)
1464
+ return
1465
+ end
1466
+
1462
1467
  gh_remote = preferred_github_remote
1463
1468
  return unless gh_remote
1464
1469
 
@@ -1487,6 +1492,44 @@ module Kettle
1487
1492
  }
1488
1493
  end
1489
1494
 
1495
+ def dispatch_github_workflows!(branch:)
1496
+ gh_remote = preferred_github_remote
1497
+ return unless gh_remote
1498
+
1499
+ owner, repo = parse_github_owner_repo(remote_url(gh_remote))
1500
+ return unless owner && repo
1501
+
1502
+ root = Kettle::Dev::CIHelpers.ci_project_root
1503
+ workflows = @ci_workflows.empty? ? Kettle::Dev::CIHelpers.workflows_list(root) : @ci_workflows
1504
+ unsupported = workflows.reject { |workflow| workflow_dispatch_configured?(root, workflow) }
1505
+ unless unsupported.empty?
1506
+ abort("Branch-stack release CI requires workflow_dispatch in every selected workflow; unsupported: #{unsupported.join(", ")}")
1507
+ end
1508
+
1509
+ workflows.each do |workflow|
1510
+ gh_output!("workflow", "run", workflow, "--repo", "#{owner}/#{repo}", "--ref", branch)
1511
+ puts "Dispatched GitHub Actions workflow #{workflow} on branch #{branch}."
1512
+ end
1513
+ end
1514
+
1515
+ def workflow_dispatch_configured?(root, workflow)
1516
+ path = File.join(root, ".github", "workflows", workflow)
1517
+ return false unless File.file?(path)
1518
+
1519
+ document = Kettle::Dev.safe_load_yaml(File.read(path), aliases: true)
1520
+ triggers = document.is_a?(Hash) ? (document["on"] || document[true]) : nil
1521
+ case triggers
1522
+ when Hash
1523
+ triggers.key?("workflow_dispatch") || triggers.key?(:workflow_dispatch)
1524
+ when Array
1525
+ triggers.any? { |trigger| trigger.to_s == "workflow_dispatch" }
1526
+ else
1527
+ false
1528
+ end
1529
+ rescue Psych::Exception
1530
+ false
1531
+ end
1532
+
1490
1533
  def github_pull_request_for_branch(owner:, repo:, branch:, base:)
1491
1534
  output = gh_output!(
1492
1535
  "pr",
@@ -1561,9 +1604,9 @@ module Kettle
1561
1604
 
1562
1605
  exit_code = status.respond_to?(:exitstatus) ? status.exitstatus : 1
1563
1606
  diag = stderr_str.to_s.empty? ? "" : "\n--- STDERR ---\n#{stderr_str}".rstrip
1564
- abort("GitHub pull request setup failed: gh #{args.join(" ")} (exit #{exit_code})#{diag}")
1607
+ abort("GitHub CLI command failed: gh #{args.join(" ")} (exit #{exit_code})#{diag}")
1565
1608
  rescue Errno::ENOENT
1566
- abort("GitHub pull request setup failed: gh CLI is required to create or find the release PR.")
1609
+ abort("GitHub CLI command failed: gh CLI is required for release CI setup.")
1567
1610
  end
1568
1611
 
1569
1612
  def run_cmd!(cmd, resume_step: @release_resume_step)
@@ -2885,23 +2928,117 @@ module Kettle
2885
2928
  return false if branch.to_s.empty?
2886
2929
  return false if trunk && branch == trunk
2887
2930
 
2888
- local_kettle_family_release_target_branches.include?(branch)
2931
+ targets = local_kettle_family_release_target_branches
2932
+ return true if targets.include?(branch)
2933
+
2934
+ warn_undeclared_branch_stack_release(branch, targets)
2935
+ false
2889
2936
  end
2890
2937
 
2938
+ # A member whose family declares a branch stack, releasing a branch that
2939
+ # is not in that list, gets merged into trunk and validated by a trunk
2940
+ # PR. That is almost always a wrong-branch release, not a feature
2941
+ # branch, so say so loudly instead of silently degrading.
2942
+ def warn_undeclared_branch_stack_release(branch, targets)
2943
+ declaring_root = family_declared_branch_stack_roots.first
2944
+ return unless declaring_root
2945
+ return if Array(@warned_undeclared_stack_branches).include?(branch)
2946
+
2947
+ @warned_undeclared_stack_branches = Array(@warned_undeclared_stack_branches) + [branch]
2948
+ warn(
2949
+ "[kettle-release] #{branch} is not a declared release branch for #{family_stack_gem_name.inspect} " \
2950
+ "in #{Kettle::Dev.display_path(declaring_root)}; it will be treated as a feature branch and merged into trunk. " \
2951
+ "Declared release branches: #{targets.join(", ")}"
2952
+ )
2953
+ end
2954
+
2955
+ # The member-local `.kettle-family.yml` is a templated copy that can be
2956
+ # absent on a fresh branch or in a worktree. The family root is the
2957
+ # authoritative declaration (`release.member_target_branches.<gem>`), so
2958
+ # consult it too and union the two. Silently returning [] when a family
2959
+ # config *does* declare a stack for this gem is what produced
2960
+ # PR-against-trunk releases and trunk merges for branch-stack members.
2891
2961
  def local_kettle_family_release_target_branches
2962
+ branches = []
2892
2963
  local_kettle_family_config_paths.each do |path|
2893
2964
  next unless File.file?(path)
2894
2965
 
2895
- begin
2896
- data = Kettle::Dev.safe_load_yaml_file(path) || {}
2897
- branches = Array(dig_string_keys(data, "release", "target_branches")) +
2898
- Array(dig_string_keys(data, "branches", "release_targets"))
2899
- return branches.map(&:to_s).reject(&:empty?) unless branches.empty?
2900
- rescue Psych::Exception => e
2901
- warn("Ignoring invalid kettle-family config #{Kettle::Dev.display_path(path)}: #{e.message}")
2902
- end
2966
+ data = safe_load_kettle_family_config(path)
2967
+ next unless data
2968
+
2969
+ branches.concat(
2970
+ Array(dig_string_keys(data, "release", "target_branches")),
2971
+ Array(dig_string_keys(data, "branches", "release_targets"))
2972
+ )
2973
+ end
2974
+ branches.concat(family_root_release_target_branches)
2975
+ branches.map(&:to_s).reject(&:empty?).uniq
2976
+ end
2977
+
2978
+ def family_root_release_target_branches
2979
+ family_declared_branch_stack_roots.flat_map do |path|
2980
+ data = safe_load_kettle_family_config(path) || {}
2981
+ Array(dig_string_keys(data, "release", "member_target_branches", family_stack_gem_name))
2982
+ end
2983
+ end
2984
+
2985
+ # Family-root configs that declare a non-empty branch stack for this gem.
2986
+ def family_declared_branch_stack_roots
2987
+ gem_name = family_stack_gem_name
2988
+ return [] unless gem_name
2989
+
2990
+ family_root_config_paths.select do |path|
2991
+ data = safe_load_kettle_family_config(path)
2992
+ next false unless data
2993
+
2994
+ declared_stack_branches(data, gem_name).any?
2995
+ end
2996
+ end
2997
+
2998
+ # Only treat a parent directory as the family root when its config
2999
+ # actually lists this checkout as a member root.
3000
+ def family_root_config_paths
3001
+ [File.expand_path("..", @root)].map do |candidate|
3002
+ path = File.join(candidate, ".kettle-family.yml")
3003
+ next nil unless File.file?(path)
3004
+
3005
+ data = safe_load_kettle_family_config(path)
3006
+ next nil unless data
3007
+
3008
+ roots = Array(dig_string_keys(data, "members", "roots")).map(&:to_s)
3009
+ path if roots.include?(File.basename(@root))
3010
+ end.compact
3011
+ end
3012
+
3013
+ def declared_stack_branches(data, gem_name)
3014
+ Array(dig_string_keys(data, "release", "member_target_branches", gem_name)).map(&:to_s).reject(&:empty?)
3015
+ end
3016
+
3017
+ # YAML loading is isolated in a method body so a malformed config is
3018
+ # reported once instead of raising inside a block. Block-level `rescue`
3019
+ # is a Ruby 2.6+ construct and this gem supports Ruby 2.4.
3020
+ def safe_load_kettle_family_config(path)
3021
+ Kettle::Dev.safe_load_yaml_file(path) || {}
3022
+ rescue Psych::Exception => e
3023
+ warn("Ignoring invalid kettle-family config #{Kettle::Dev.display_path(path)}: #{e.message}")
3024
+ nil
3025
+ end
3026
+
3027
+ def family_stack_gem_name
3028
+ @family_stack_gem_name ||= begin
3029
+ name = ENV.fetch("K_CHANGELOG_GEM_NAME", "").to_s.strip
3030
+ name = detect_family_stack_gem_name_from_gemspec if name.empty?
3031
+ name.empty? ? nil : name
2903
3032
  end
2904
- []
3033
+ end
3034
+
3035
+ def detect_family_stack_gem_name_from_gemspec
3036
+ gemspecs = Dir[File.join(@root, "*.gemspec")]
3037
+ path = gemspecs.min
3038
+ return "" unless path
3039
+
3040
+ match = File.read(path).match(/spec\.name\s*=\s*(["'])([^"']+)\1/)
3041
+ match ? match[2].to_s : ""
2905
3042
  end
2906
3043
 
2907
3044
  def local_kettle_family_config_paths
@@ -5,7 +5,7 @@ module Kettle
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = "3.1.5"
8
+ VERSION = "3.1.7"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
data/lib/kettle/dev.rb CHANGED
@@ -115,10 +115,11 @@ module Kettle
115
115
  text.to_s.gsub(VAR_HOME_TEXT, "/home")
116
116
  end
117
117
 
118
- def safe_load_yaml(content)
119
- YAML.safe_load(content, permitted_classes: [], aliases: false)
120
- rescue ArgumentError
121
- YAML.safe_load(content, [], [], false)
118
+ def safe_load_yaml(content, aliases: false)
119
+ supports_keyword_options = Gem::Version.new(Psych::VERSION) >= Gem::Version.new("4.0")
120
+ return YAML.safe_load(content, permitted_classes: [], aliases: aliases) if supports_keyword_options
121
+
122
+ YAML.safe_load(content, [], [], aliases)
122
123
  end
123
124
 
124
125
  def safe_load_yaml_file(path)
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: 3.1.5
4
+ version: 3.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -256,7 +256,7 @@ dependencies:
256
256
  version: '3.2'
257
257
  - - ">="
258
258
  - !ruby/object:Gem::Version
259
- version: 3.2.4
259
+ version: 3.2.5
260
260
  type: :development
261
261
  prerelease: false
262
262
  version_requirements: !ruby/object:Gem::Requirement
@@ -266,7 +266,7 @@ dependencies:
266
266
  version: '3.2'
267
267
  - - ">="
268
268
  - !ruby/object:Gem::Version
269
- version: 3.2.4
269
+ version: 3.2.5
270
270
  - !ruby/object:Gem::Dependency
271
271
  name: turbo_tests2
272
272
  requirement: !ruby/object:Gem::Requirement
@@ -276,7 +276,7 @@ dependencies:
276
276
  version: '3.2'
277
277
  - - ">="
278
278
  - !ruby/object:Gem::Version
279
- version: 3.2.11
279
+ version: 3.2.13
280
280
  type: :development
281
281
  prerelease: false
282
282
  version_requirements: !ruby/object:Gem::Requirement
@@ -286,7 +286,7 @@ dependencies:
286
286
  version: '3.2'
287
287
  - - ">="
288
288
  - !ruby/object:Gem::Version
289
- version: 3.2.11
289
+ version: 3.2.13
290
290
  - !ruby/object:Gem::Dependency
291
291
  name: stone_checksums
292
292
  requirement: !ruby/object:Gem::Requirement
@@ -316,7 +316,7 @@ dependencies:
316
316
  version: '2.0'
317
317
  - - ">="
318
318
  - !ruby/object:Gem::Version
319
- version: 2.0.13
319
+ version: 2.0.15
320
320
  type: :development
321
321
  prerelease: false
322
322
  version_requirements: !ruby/object:Gem::Requirement
@@ -326,7 +326,7 @@ dependencies:
326
326
  version: '2.0'
327
327
  - - ">="
328
328
  - !ruby/object:Gem::Version
329
- version: 2.0.13
329
+ version: 2.0.15
330
330
  description: "\U0001F372 Kettle::Dev is a meta tool from kettle-dev to streamline
331
331
  development and testing. Acts as a shim dependency, pulling in many other dependencies,
332
332
  to give you OOTB productivity with a RubyGem, or Ruby app project. Configures a
@@ -422,10 +422,10 @@ licenses:
422
422
  - AGPL-3.0-only
423
423
  metadata:
424
424
  homepage_uri: https://kettle-dev.galtzo.com
425
- source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.1.5
426
- changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.1.5/CHANGELOG.md
425
+ source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.1.7
426
+ changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.1.7/CHANGELOG.md
427
427
  bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
428
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.1.5
428
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.1.7
429
429
  funding_uri: https://github.com/sponsors/pboling
430
430
  wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
431
431
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
Binary file