From e7108d22b3412a6f109d06e16b3ab660b25309f7 Mon Sep 17 00:00:00 2001 From: Lukas Audzevicius Date: Wed, 12 Aug 2026 12:42:32 +0100 Subject: [PATCH 1/6] (CAT-2590) Prepare for Puppetcore 9 With the arrival of Puppetcore 9, we need to ensure that our tools are compatible with Ruby 4. The Gemfile's puppetcore-source branch was hardcoded to puppet ~> 8.11 / facter ~> 4.11, so it would keep testing 8.x forever even once a Puppet 9 lane exists. This makes it respect PUPPET_GEM_VERSION/FACTER_GEM_VERSION instead, and checks PUPPET_FORGE_TOKEN_PUBLIC alongside PUPPET_FORGE_TOKEN. Also raises the puppet version upper bound in metadata.json so module CI picks up a Puppet 9 test lane. --- Gemfile | 25 ++++++++++++++----------- metadata.json | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index 4d6636d..9e45253 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' -def location_for(place_or_version, fake_version = nil) +def location_for(place_or_version, fake_version = nil, opts = {}) git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} file_url_regex = %r{\Afile:\/\/(?.*)} @@ -9,7 +9,7 @@ def location_for(place_or_version, fake_version = nil) elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] else - [place_or_version, { require: false }] + [place_or_version, { require: false }.merge(opts)] end end @@ -54,15 +54,18 @@ puppet_version = ENV.fetch('PUPPET_GEM_VERSION', nil) facter_version = ENV.fetch('FACTER_GEM_VERSION', nil) hiera_version = ENV.fetch('HIERA_GEM_VERSION', nil) -# If PUPPET_FORGE_TOKEN is set then use authenticated source for both puppet and facter, since facter is a transitive dependency of puppet -# Otherwise, do as before and use location_for to fetch gems from the default source -if !ENV['PUPPET_FORGE_TOKEN'].to_s.empty? - gems['puppet'] = ['~> 8.11', { require: false, source: 'https://rubygems-puppetcore.puppet.com' }] - gems['facter'] = ['~> 4.11', { require: false, source: 'https://rubygems-puppetcore.puppet.com' }] -else - gems['puppet'] = location_for(puppet_version) - gems['facter'] = location_for(facter_version) if facter_version -end +# If PUPPET_FORGE_TOKEN(_PUBLIC) is set then use the authenticated puppetcore source for both +# puppet and facter, since facter is a transitive dependency of puppet. Still respects +# PUPPET_GEM_VERSION/FACTER_GEM_VERSION (e.g. a '~> 9.0' CI lane) rather than pinning a fixed +# version, so this doesn't silently keep testing 8.x once a forge token is present. +puppetcore_opts = if !(ENV['PUPPET_FORGE_TOKEN_PUBLIC'] || ENV['PUPPET_FORGE_TOKEN']).to_s.empty? + { source: 'https://rubygems-puppetcore.puppet.com' } + else + {} + end + +gems['puppet'] = location_for(puppet_version, nil, puppetcore_opts) +gems['facter'] = location_for(facter_version, nil, puppetcore_opts) if facter_version gems['hiera'] = location_for(hiera_version) if hiera_version diff --git a/metadata.json b/metadata.json index 5824056..957f4d4 100644 --- a/metadata.json +++ b/metadata.json @@ -67,7 +67,7 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 8.0.0 < 9.0.0" + "version_requirement": ">= 8.0.0 < 10.0.0" } ], "pdk-version": "3.0.1", From 21b81970a5d56322cf1044f99a37929a9c287db2 Mon Sep 17 00:00:00 2001 From: Lukas Audzevicius Date: Wed, 12 Aug 2026 13:12:23 +0100 Subject: [PATCH 2/6] (CAT-2590) Bump puppet_litmus to enable the Puppet 9 test lane The Puppet 9 lane never appeared because matrix_from_metadata_v3 derives its known collections from puppet_litmus's own bundled matrix.json, not directly from metadata.json. puppet_litmus ~> 1.0 only knows about puppet 7.24/8.0; 2.0+ adds a puppet 9.0 / ruby 4.0 collection entry, which is what actually makes the new metadata.json upper bound take effect. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 9e45253..e11eb88 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,7 @@ group :development do gem "webmock", require: false end group :system_tests do - gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] + gem "puppet_litmus", '>= 2.0', require: false, platforms: [:ruby, :x64_mingw] gem "serverspec", '~> 2.41', require: false end group :release_prep do From 9ee6d3ed2952d69570890eeb378da3c4d9bfd1a5 Mon Sep 17 00:00:00 2001 From: Lukas Audzevicius Date: Wed, 12 Aug 2026 14:24:41 +0100 Subject: [PATCH 3/6] (CAT-2590) Source bolt from puppetcore too puppet_litmus pulls in bolt as a transitive dependency, which otherwise resolves from rubygems.org (currently a stale 4.0.0 dragging in an old faraday/patron native-extension chain). Source it from rubygems-puppetcore.puppet.com when a forge token is present, same as puppet/facter, unconstrained so it resolves to latest. --- Gemfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index e11eb88..18539fe 100644 --- a/Gemfile +++ b/Gemfile @@ -50,20 +50,19 @@ facter_version = ENV['FACTER_GEM_VERSION'] hiera_version = ENV['HIERA_GEM_VERSION'] gems = {} +bolt_version = ENV.fetch('BOLT_GEM_VERSION', nil) puppet_version = ENV.fetch('PUPPET_GEM_VERSION', nil) facter_version = ENV.fetch('FACTER_GEM_VERSION', nil) hiera_version = ENV.fetch('HIERA_GEM_VERSION', nil) -# If PUPPET_FORGE_TOKEN(_PUBLIC) is set then use the authenticated puppetcore source for both -# puppet and facter, since facter is a transitive dependency of puppet. Still respects -# PUPPET_GEM_VERSION/FACTER_GEM_VERSION (e.g. a '~> 9.0' CI lane) rather than pinning a fixed -# version, so this doesn't silently keep testing 8.x once a forge token is present. +# Use the authenticated puppetcore source for bolt/puppet/facter when a forge token is present. puppetcore_opts = if !(ENV['PUPPET_FORGE_TOKEN_PUBLIC'] || ENV['PUPPET_FORGE_TOKEN']).to_s.empty? { source: 'https://rubygems-puppetcore.puppet.com' } else {} end +gems['bolt'] = location_for(bolt_version, nil, puppetcore_opts) gems['puppet'] = location_for(puppet_version, nil, puppetcore_opts) gems['facter'] = location_for(facter_version, nil, puppetcore_opts) if facter_version From e120be9d9628ab3e6f5f3451cea7ef1a082a9179 Mon Sep 17 00:00:00 2001 From: Lukas Audzevicius Date: Wed, 12 Aug 2026 15:03:07 +0100 Subject: [PATCH 4/6] (CAT-2590) Bump voxpupuli-puppet-lint-plugins to fix puppet-lint crash on Ruby 4 puppet-lint 4.3.0's Data.tokens parses Ruby's caller() backtrace with a regex expecting the old backtick format (`method'), which Ruby 3.4+/4.0 changed to plain quotes ('method'). The regex no longer matches, and calling [1..-2] on the nil result raises NoMethodError, crashing the Puppet 9 / Ruby 4 lint job on plans/agents.pp. voxpupuli-puppet-lint-plugins ~> 5.0 only allows puppet-lint ~> 4.0. Bumping to ~> 7.0 pulls in puppet-lint ~> 5.1, which rewrote tokens without any caller-string parsing. Verified locally: full rake syntax/lint/metadata_lint/rubocop suite passes clean with the bumped gems, no new violations from the additional checks 7.0 adds. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 18539fe..77e9bcb 100644 --- a/Gemfile +++ b/Gemfile @@ -17,7 +17,7 @@ group :development do gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) - gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false + gem "voxpupuli-puppet-lint-plugins", '~> 7.0', require: false gem "facterdb", '~> 1.18', require: false gem "metadata-json-lint", '~> 4.0', require: false gem "puppetlabs_spec_helper", '~> 6.0', require: false From b27e38d3f324046eb06a5be81c2574e3e6734293 Mon Sep 17 00:00:00 2001 From: Lukas Audzevicius Date: Wed, 12 Aug 2026 15:09:49 +0100 Subject: [PATCH 5/6] (CAT-2590) Bump tooling ruby_version to 3.2 for ci/mend voxpupuli-puppet-lint-plugins ~> 7.0 requires Ruby >= 3.2. Both the module_ci.yml setup_matrix job and tooling_mend_ruby.yml default their own tooling Ruby to 3.1/2.7, unrelated to the actual per-lane test Ruby versions (3.2/4.0) - so bundle install failed there before any spec lane could even run. Bumping to 3.2 doesn't change what module code gets tested; it's just the Ruby these two jobs use to bundle install / run matrix_from_metadata_v3 and the Mend scan. --- .github/workflows/ci.yml | 2 +- .github/workflows/mend.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 071004a..413a1be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,5 +12,5 @@ jobs: with: # This line enables shellcheck to be run on this repository run_shellcheck: true - ruby_version: '3.1' + ruby_version: '3.2' secrets: "inherit" diff --git a/.github/workflows/mend.yml b/.github/workflows/mend.yml index 095e9e5..002e4aa 100644 --- a/.github/workflows/mend.yml +++ b/.github/workflows/mend.yml @@ -12,4 +12,6 @@ jobs: mend: uses: "puppetlabs/cat-github-actions/.github/workflows/tooling_mend_ruby.yml@main" + with: + ruby_version: '3.2' secrets: "inherit" From 4f5abfc10a0f121e6ea4579c89463193c91a9a90 Mon Sep 17 00:00:00 2001 From: Lukas Audzevicius Date: Fri, 21 Aug 2026 10:15:03 +0100 Subject: [PATCH 6/6] (CAT-2590) Bump puppetlabs_spec_helper to 9.0, drop codecov puppetlabs_spec_helper 9.0.0 was just released and fixes the puppet-lint/rspec-puppet chain we were blocked on (puppet-lint ~> 5.0, rspec-puppet ~> 5.0), and replaces its puppet-syntax dependency with a new puppetlabs-syntax fork (~> 7.2, allows puppet < 10 instead of < 9). Updated the Rakefile's require to match the new gem name. Removed codecov ~> 0.6 - every published version hard-caps Ruby < 4, and it's only ever referenced inside unused test fixture data, not anything this repo's own test run executes. --- Gemfile | 5 ++--- Rakefile | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 77e9bcb..594f245 100644 --- a/Gemfile +++ b/Gemfile @@ -20,13 +20,12 @@ group :development do gem "voxpupuli-puppet-lint-plugins", '~> 7.0', require: false gem "facterdb", '~> 1.18', require: false gem "metadata-json-lint", '~> 4.0', require: false - gem "puppetlabs_spec_helper", '~> 6.0', require: false + gem "puppetlabs_spec_helper", '~> 9.0', require: false gem "rspec-puppet-facts", '~> 2.0', require: false gem "dependency_checker", '~> 1.0.0', require: false gem "parallel_tests", '= 3.12.1', require: false gem "pry", '~> 0.10', require: false gem "simplecov-console", '~> 0.9', require: false - gem "codecov", '~> 0.6', require: false gem "puppet-debugger", '~> 1.0', require: false gem "rubocop", '~> 1.50.0', require: false gem "rubocop-performance", '= 1.16.0', require: false @@ -42,7 +41,7 @@ group :system_tests do end group :release_prep do gem "puppet-strings", '~> 4.0', require: false - gem "puppetlabs_spec_helper", '~> 6.0', require: false + gem "puppetlabs_spec_helper", '~> 9.0', require: false end puppet_version = ENV['PUPPET_GEM_VERSION'] diff --git a/Rakefile b/Rakefile index 6329e75..29f5d5d 100644 --- a/Rakefile +++ b/Rakefile @@ -3,7 +3,7 @@ require 'bundler' require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-syntax/tasks/puppet-syntax' +require 'puppetlabs-syntax/tasks/puppetlabs-syntax' require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' PuppetLint.configuration.send('disable_relative')