Ruby 3.3 support across the Foreman ecosystem

Hello everyone,

I’d like to share an update on the Ruby 3.3 support effort across the Foreman ecosystem. This post serves as a heads-up, especially for plugin developers and maintainers.

Why Ruby 3.3

Ruby 3.0 reached EOL on 2024-04-23, Ruby 3.1 on 2025-03-26. On top of that, EL10 ships Ruby 3.3 as the default version. We need to make sure the ecosystem is ready.

To be clear — we’re not dropping Ruby 3.0 support just yet. The goal for now is to add Ruby 3.3 to the CI matrix so we can verify compatibility across the board.

What’s been done so far

Before touching Foreman’s matrix, we had to verify its key dependencies work on Ruby 3.3:

  • scoped_search — test suite passes on Ruby 3.3/Rails 7, no regressions on 3.0.

  • safemode — this was the biggest risk. safemode depends on ruby_parser [0], which is EOL and only partially supports Ruby 3.1. Ruby 3.3 ships with Prism [1] as the built-in parser, so migrating safemode’s parser backend from ruby_parser to Prism was required. This is done and available in safemode 2.0, backward compatibility with Ruby 3.0 is preserved. Plugin developers don’t need to do anything regarding this change — it’s fully handled in safemode itself.

  • hammer-cli and smart-proxy (with their plugins) — already run their test suites on Ruby 3.3 since they share a common workflow action. No issues there.

What’s next

Since the dependencies are verified, the next step is adding “3.3” to Foreman’s .github/matrix.json. Ideally this needs to happen during the current Foreman 5.0 development cycle. Once that’s merged, all plugins using the centralized reusable workflow [2] will automatically get Ruby 3.3 CI runs.

Impact on plugin developers

This is the part that affects you directly. There are two approaches we could take:

  1. Merge the matrix change into Foreman and let plugins pick it up. Some plugins might have their CI red for some time, which just means the plugin is not Ruby 3.3 ready yet.

  2. Prepare everything beforehand — test every plugin against the matrix PR first and merge roughly at the same time.

I’m leaning towards the first approach — I’m working on this and plan to go through the plugins under theforeman org one by one, so I’ll be opening PRs for affected plugins anyway. But I don’t have a strong opinion here, so if you’d prefer the second approach or have other thoughts, please share.

Common issues to expect

If your plugin CI goes red on Ruby 3.3, here are the most likely causes:

  • Bundler resolution failures — newer Bundler is stricter about duplicate gem declarations with conflicting version constraints. If your plugin Gemfile duplicates a development dependency already declared in Foreman’s Gemfile with a different version, Bundler will complain. The fix is to remove or align the duplicate.

  • require ‘set’Set became a core class in Ruby 3.2, so explicit require ‘set’ is redundant on 3.2+. It won’t cause CI failures on 3.3 right now, but it’s worth knowing for the future when Ruby 3.3 becomes the minimum version — at that point those requires can be safely removed.

  • Kernel#=~ removal [3] — Ruby 3.2 removed Kernel#=~, which was deprecated since Ruby 2.6. Code that uses =~ on objects that don’t define it (e.g. some_integer =~ /pattern/) will now raise a NoMethodError instead of silently returning nil. This might surface in places where a variable could be nil or a non-String type and =~ was used without checking.

  • Keyword argument / splat changes — unlikely but possible edge cases from Ruby 3.2 changes.

If you run into something else, please reply here and I’ll try to help.

[0] - GitHub - seattlerb/ruby_parser: ruby_parser is a ruby parser written in pure ruby. It outputs s-expressions which can be manipulated and converted back to ruby via the ruby2ruby gem. · GitHub

[1] - GitHub - ruby/prism: Prism Ruby parser · GitHub

[2] - actions/.github/workflows/foreman_plugin.yml at v1 · theforeman/actions · GitHub

[3] - Feature #15231: Remove `Object#=~` - Ruby - Ruby Issue Tracking System

6 Likes

Do you have a bit more of a timeline? It sounds like we’re ready to open the PR to expand the matrix. Then do you want to keep that open for a certain amount of time, allowing plugin authors to open the testing PR themselves?

Then we also have Foreman Proxy. I just rebased my PR and I think we should choose the same approach for both Foreman and Foreman Proxy.

Is that something RuboCop would find once we drop Ruby < 3.2?

1 Like

Once you start doing it, please ping us in the channel in advance, so we can include the efforts in our sprint.

Thanks!

We could keep the PR open for a week or two, but not sure if it’s enough for all the maintainers. I just don’t like the idea of a ready-for-merge PR being open for a long time, thus I proposed to “break” CI for plugins for a while and fix them one by one.

Not sure how it’s related, especially if we target Ruby 3.3 only (Foreman Proxy already supports it).

Hopefully? :slight_smile: The thing is that our theforeman-rubocop gem seems to be outdated a bit or at least not proactively maintained, so we’d need to revisit it first.

2 Likes

How about we keep it open for a week and see what the results are. During that week we expect plugin authors to review the compatibility. After that week we decide the path forward.

Oh yes, my bad. We already had Refs #38357 - Support of ruby version 3.4 · theforeman/smart-proxy@a1c20c7 · GitHub with Foreman 3.16.

3 Likes

UPD: The PR is up: Fixes #39361 - Add Ruby 3.3 support to Foreman by ofedoren · Pull Request #11004 · theforeman/foreman · GitHub

Sure, that might be helpful. I put the due date (04.06.2026) to the PR. In the meantime I’ll visit some plugins myself :slight_smile:

1 Like

I’ve opened some PRs:

2 Likes

Just a heads-up: Fixes #39361 - Add Ruby 3.3 support to Foreman by ofedoren · Pull Request #11004 · theforeman/foreman · GitHub will be merged on Wednesday 10.06.2026.

3 Likes