Skip to content

Remove openssl gem requirement - #5736

Merged
mokagio merged 4 commits into
mainfrom
mokagio/ruby-file
Aug 14, 2026
Merged

Remove openssl gem requirement#5736
mokagio merged 4 commits into
mainfrom
mokagio/ruby-file

Conversation

@mokagio

@mokagio mokagio commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Tweaking #5733 to remove faraday, I noticed openssl was in Gemfile still.

I recalled the requirement was due to a compatibility issue between openssl and earlier versions of Ruby.

I asked Opus 5 to validate and it pointed out that, while the removal was appropriate, there was no way enforcing the 3.4.9 Ruby version, so a machine with no tooling to read and respect .ruby-version might end up on an old version that still has the issue.

It suggested to force the Ruby version in Gemfile via ruby file: .ruby-version. That was a TIL for me.

While it's quite unlikely we'd run in a machine with old Ruby version running the automation, the idea of ensuring the version is respected seem valuable. I think we should adopt it.

Let's use this PR to see how it looks like.

mokagio and others added 2 commits August 13, 2026 21:19
Nothing tied the Gemfile to `.ruby-version` before, so resolving under an older
Ruby was silently allowed.
That became load-bearing when 75d3bd3 dropped the explicit `openssl` gem: the
workaround for ruby/openssl#949 now comes from the
default `openssl` 3.3.1 that ships with Ruby 3.4.9, and an older Ruby would
bring back the CRL verification failures without any signal.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Code Opus 5 <noreply@anthropic.com>
@claude

claude Bot commented Aug 13, 2026

Copy link
Copy Markdown

Claude Code is working…

I'll analyze this and get back to you.

View job run

@mokagio
mokagio marked this pull request as ready for review August 13, 2026 11:30
@mokagio
mokagio requested a review from a team as a code owner August 13, 2026 11:30
Copilot AI lite review requested due to automatic review settings August 13, 2026 11:30
@claude

claude Bot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mokagio's task in 3m 59s —— View job


Review

Nice change — ruby file: is the right way to keep .ruby-version as the single source of truth, and the mechanics here are correct (.ruby-version is a bare 3.4.9\n, Bundler resolves the path relative to the Gemfile so subdirectory invocations work, and BUNDLED WITH 4.0.17 is far past the Bundler 2.3 that introduced the file: form). No blockers. A few things I'd verify before merging, plus one trade-off worth naming explicitly.

I left two inline comments on Gemfilethe pin semantics + a comment suggestion and whether the openssl removal is really a no-op. Summarising the rest here.

1. The openssl removal is a downgrade, not just a deletion

Gemfile.lock had openssl (4.0.2); without the pin you fall back to the default gem shipped with Ruby 3.4 (3.3.x line). "Unnecessary in Ruby 3.4.9" holds only if the ruby/openssl#949 fix is in that version. I have no network access in this job, so I couldn't check the issue or the default gem version — details and a one-liner to check in the inline comment.

2. Every Buildkite step now hard-fails on a Ruby patch mismatch

install_gems runs in all 14 CI entry points (.buildkite/commands/lint.sh:10, run-instrumented-tests.sh:11, release-build.sh:8, and the six release-pipelines/*.yml), across two agent queues (android and linter). Where a mismatched image Ruby previously just… worked, it now stops the build. The PR CI covers the android/linter queues, but the release pipelines only run at code-freeze/finalize time — if those use a different image, the first failure would land in the middle of a release. Worth a glance at the image Ruby for the queues used by .buildkite/release-pipelines/. I couldn't check Buildkite from here (external to Actions, and the sandbox blocked the commit-status API call).

3. Dependabot's bundler updater is the most likely thing to break

.github/dependabot.yml runs the bundler ecosystem daily. Dependabot's updater image ships its own Ruby patch versions, and an exact = 3.4.9 requirement can make it fail to resolve. I'm not certain current dependabot-core relaxes this — but the feedback loop is a day, so: if bundler PRs stop appearing after merge, check the Dependabot run logs (Insights → Dependency graph → Dependabot) before assuming it's quiet upstream.

4. .ruby-version bumps are now two-step

Gemfile.lock gained a RUBY VERSION stanza. Bumping .ruby-version alone leaves it stale. There's no BUNDLE_FROZEN in .bundle/config, so CI won't error — install_gems will just silently rewrite the lock in the build directory, which is the quieter and more confusing failure mode. Worth a line in whatever runbook covers Ruby upgrades: bump .ruby-version, run bundle install, commit the lock together.

5. Minor: the guard is cryptic on the Rubies it's guarding against

On a Ruby old enough to ship Bundler < 2.3 (i.e. 3.0 and earlier), ruby file: isn't understood, so you get a Bundler parse error rather than the clear "Your Ruby version is 3.0.0, but your Gemfile specified 3.4.9". Not worth changing anything over — just noting the enforcement isn't a clean message in the very case it exists for.


Security / performance: nothing beyond the openssl point in §1 — the change is build tooling only, no app code paths touched.
· branch mokagio/ruby-file

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes the explicit openssl gem dependency from the Bundler setup and ensures the repository’s intended Ruby version is enforced by Bundler (via .ruby-version), preventing accidental use of older Rubies that may hit the prior OpenSSL compatibility issues.

Changes:

  • Drop the openssl gem from Gemfile and Gemfile.lock.
  • Enforce Ruby version by adding ruby file: '.ruby-version' to Gemfile.
  • Record the Ruby version (3.4.9) in Gemfile.lock under RUBY VERSION.

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.

File Description
Gemfile Enforces Ruby version from .ruby-version and removes the explicit openssl gem requirement.
Gemfile.lock Removes openssl from the resolved dependency set and records the enforced Ruby version.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Gemfile Outdated

source 'https://rubygems.org'

ruby file: '.ruby-version'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruby file: resolves the file relative to the Gemfile's directory and strips whitespace/a ruby- prefix, so with .ruby-version containing 3.4.9\n this works from any subdirectory. Two things worth being deliberate about:

It's an exact pin, not a floor. Bundler turns this into = 3.4.9, so anyone on 3.4.10 (or 3.5.x) gets a hard Your Ruby version is X, but your Gemfile specified 3.4.9 on every bundle exec. That's stricter than what the PR description motivates (guarding against old Ruby). It's consistent with .ruby-version already being exact for rbenv/mise users, so it's a defensible choice — just be aware the newly-affected population is exactly the "no version manager" crowd this targets, and for them the failure mode is now a hard stop rather than "it worked". If you'd rather express a floor while keeping a single source of truth, there isn't a file:-based way to do it — you'd have to write ruby '>= 3.4.9', '< 4' literally and accept the duplication.

Nit: this PR removes the only comment that documented the TLS history, and the new line's intent isn't self-evident. Consider:

Suggested change
ruby file: '.ruby-version'
# Enforce the version declared in `.ruby-version`, so that machines without a
# Ruby version manager can't silently run the automation on an older Ruby.
ruby file: '.ruby-version'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems strange, I've never seen us needing to do this in any other project, why thus would we really start needing to do this in this repo?

@AliSoftware AliSoftware Aug 13, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read the rationale in the commit message:

Nothing tied the Gemfile to .ruby-version before, so resolving under an older
Ruby was silently allowed.
That became load-bearing when 75d3bd3 dropped the explicit openssl gem: the workaround for ruby/openssl#949 now comes from the default openssl 3.3.1 that ships with Ruby 3.4.9, and an older Ruby would bring back the CRL verification failures without any signal.

But I'm still not 100% convinced. I mean, sure, that's an extra "belt and suspenders" pinning that reduces that risk. But I think it's fair to assume that all the environments in which we use that Gemfile (especially on CI and on AppsInfra engineers' machines) we all use rbenv to begin with, which will always rely on .ruby-version automatically. And if we decide this extra explicit pinning in the Gemfile is really important to add, we should add it on every repo (but I'm not convinced it's worth it?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, the requirement is not needed, just something I thought it be good to try out for size.

I asked Opus 5 to validate my openssl removal and it pointed out the no-guarantee on which Ruby version would be in use and therefore that the openssl issue would be address at runtime.

It suggested to force the Ruby version in Gemfile via ruby file: .ruby-version. That was a TIL for me.

While it's quite unlikely we'd run in a machine with old Ruby version running the automation, the idea of ensuring the version is respected seem valuable.

I decided to try it out for size in this PR and I'm glad I got your feedback on it—and Claude's, as I hand't considered the "it's a pin, not a floor."

Looking at this one day later, I still think it's useful in principle, but maybe not as useful as I imagined in our instance, given:

  • We aim for devs not to need Ruby
  • We manage all the infra that needs Ruby and therefore can ensure a Ruby version manager and other such things

Putting it all together, it's really downgrades the usefulness of this condition.

I'll remove it.

Comment thread Gemfile
# SSL_connect returned=1 errno=0 peeraddr=3.5.132.155:443 state=error: certificate verify failed (unable to get certificate CRL)
#
# See https://github.com/ruby/openssl/issues/949
gem 'openssl', '~> 4.0'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth double-checking the premise here: removing this doesn't leave you with "no openssl gem", it drops you back to the default gem bundled with Ruby. Gemfile.lock had openssl (4.0.2); Ruby 3.4 ships openssl as a default gem in the 3.3.x line, so this is effectively a downgrade of the TLS stack, not just deleting a redundant entry.

So "unnecessary in Ruby 3.4.9" holds only if the fix for ruby/openssl#949 is present in the 3.3.x default gem, not merely in 4.0. Quick check on a 3.4.9 install:

ruby -ropenssl -e 'puts [RUBY_VERSION, OpenSSL::VERSION, OpenSSL::OPENSSL_LIBRARY_VERSION].join(" / ")'

Two caveats on how to validate:

  • SSL_connect ... unable to get certificate CRL is sensitive to the system OpenSSL library and cert store, so a green Linux Buildkite run does not prove macOS dev machines are fine. Reproduce on the environment where it originally bit (I couldn't find the commit that added the pin — the checkout here is shallow — but the wording suggests a local/dev-machine failure).
  • After this change the openssl version is no longer recorded in Gemfile.lock at all, so it becomes implicit per-environment, and you pick up openssl fixes only on Ruby patch releases / .ruby-version bumps rather than on the gem's own cadence. Minor, but it's the reproducibility trade-off you're making.

@mokagio mokagio Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified. Everything is good for our usage in Ruby 3.4.9.

3.4.9 ships openssl 3.3.1, which contains the fix for the issue.

Image
AI-performed research details

The fix is ruby/openssl#950, which
removes V_FLAG_CRL_CHECK_ALL from the default cert store. It shipped in
openssl 3.1.2 / 3.2.2 / 3.3.1
(maintainer confirmation),
and Ruby picked it up as a default-gem backport in 3.4.8
(Bo98).

Same file, two tags — this is the whole argument:

Confirmed on a local 3.4.9 install:

$ bundle exec ruby -ropenssl -e 'puts [RUBY_VERSION, OpenSSL::VERSION].join(" / ")'
3.4.9 / 3.3.1

That also dates the pin: it landed in #4929 (2026-01-30) while .ruby-version
was 3.2.2, i.e. openssl 3.1.0, which predates the fix. It was load-bearing then
and stopped being so at #5605, when we moved to 3.4.9.

On "downgrade of the TLS stack" — the gem is a binding, not the TLS
implementation. The stack is the system OpenSSL library (unchanged by this
diff); 4.0.2 → 3.3.1 is a binding-API downgrade, and both sides carry the CRL
fix. And you're right that a green CI run proves nothing here: my machine links
OpenSSL 3.5.5, which doesn't trigger the bug at all. The source anchors above
are the environment-independent proof.

The reproducibility point stands, though: the
developers being on Ruby >= 3.4.8

See discussion at
https://github.com/Automattic/pocket-casts-android/pull/5736/changes#r3775036237

TL;DR: Sure it seems useful, but in practice it's overly cautious. Our
setup is such that we can trust Ruby version respect in all the runtimes
where it's important to have it.
@claude

claude Bot commented Aug 14, 2026

Copy link
Copy Markdown

Claude finished @mokagio's task in 1m 56s —— View job


Review (updated for 24de909)

  • Read the new commit and re-diff against origin/main
  • Check the Gemfile/Gemfile.lock are consistent after the revert
  • Re-check the openssl removal for leftover references
  • Post findings

The PR is now back to its original, narrow scope: drop the openssl pin. ruby file: '.ruby-version' is gone, and I agree with the reasoning in 24de909 — given devs aren't expected to need Ruby and the Ruby-bearing runtimes are infra you control, an exact pin buys little and costs a hard stop on any patch-version drift.

One leftover from the revert. 24de909 only touched Gemfile. Gemfile.lock still carries the RUBY VERSION / ruby 3.4.9 stanza that 8156757 added:

Gemfile.lock:394  RUBY VERSION
Gemfile.lock:395    ruby 3.4.9

Bundler emits that section only when the Gemfile declares a Ruby version, so it's now unbacked. Practical effect is small but annoying: the next bundle install re-resolves and drops it, so an unrelated PR picks up a stray lockfile diff. And a lockfile that doesn't match the Gemfile is the sort of thing frozen/deployment mode can refuse rather than quietly fix — install_gems runs in all 14 Buildkite entry points, so it's worth not finding out. Suggestion posted inline.

Everything else checks out:

  • No openssl/OpenSSL references anywhere in the repo outside the lockfile, and after this change the lockfile has none either — no dangling transitive dependency on it.
  • DEPENDENCIES and the GEM spec list are consistent with each other; openssl (4.0.2) was only present because of the direct pin.

Standing caveat from my previous review, unchanged and still worth a sanity check before merge: this isn't "delete a redundant entry", it's a fall back from openssl 4.0.2 to the default gem in Ruby 3.4's 3.3.x line, so the unable to get certificate CRL fix needs to be present there. ruby -ropenssl -e 'puts [RUBY_VERSION, OpenSSL::VERSION].join(" / ")' on a 3.4.9 install answers it. I still have no network access in this job, so I couldn't verify it myself. That failure is also sensitive to the system OpenSSL and cert store, so a green Linux CI run doesn't prove macOS is fine — reproduce where it originally bit.

No blockers beyond the stale lockfile stanza. Nothing security- or performance-relevant; build tooling only.


· branch mokagio/ruby-file

Comment thread Gemfile.lock Outdated
Comment on lines 392 to 396
google-apis-sheets_v4 (~> 0.48)
openssl (~> 4.0)

RUBY VERSION
ruby 3.4.9

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This RUBY VERSION stanza is a leftover from 8156757 — the last commit (24de909) removed ruby file: '.ruby-version' from the Gemfile but only touched the Gemfile, so the lockfile still records a Ruby requirement that no longer exists.

Bundler writes this section only when the Gemfile declares a Ruby version, so the next bundle install / bundle lock will drop it again and produce an unrelated lockfile diff in whatever PR happens to run it next. If any environment runs Bundler in frozen/deployment mode, a lockfile that doesn't match the Gemfile is also the kind of mismatch that can hard-fail rather than silently re-resolve.

Cheapest fix is to drop it here so the committed lock matches what bundle install would generate:

Suggested change
google-apis-sheets_v4 (~> 0.48)
openssl (~> 4.0)
RUBY VERSION
ruby 3.4.9
google-apis-sheets_v4 (~> 0.48)

Fix this →

@claude

claude Bot commented Aug 14, 2026

Copy link
Copy Markdown

Claude finished @mokagio's task in 49s —— View job


Review (updated for 9384850)

  • Re-diff against origin/main and read the new commit
  • Verify the Gemfile/Gemfile.lock are now consistent
  • Check for leftovers from the reverted ruby file: commits
  • Post findings

The stale stanza I flagged last round is gone, and it was removed the right way — 9384850 is the output of an actual bundle install, not a hand-edit, so the committed lock is what Bundler would regenerate. No findings; this is good to merge from my side.

The four commits now collapse to a two-line net diff against origin/main:

 Gemfile        -7   # the openssl pin and its comment
 Gemfile.lock   -2   #   openssl (4.0.2)   /   openssl (~> 4.0)

Verified:

  • grep -i openssl returns nothing anywhere in the repo — no Gemfile, no lockfile, no scripts. Nothing transitively pulls it either; openssl (4.0.2) appeared in the GEM block only because of the direct pin, so removing it from DEPENDENCIES correctly removed the spec too.
  • Gemfile ends at the google-apis-sheets_v4 line — no residue from 8156757/24de909.
  • The RUBY VERSION stanza is gone (Gemfile.lock:391-393), so lock and Gemfile agree again. The BUNDLED WITH 4.0.17 and everything above it are untouched — bundle install didn't opportunistically bump anything else.

On the openssl premise — my earlier caveat is resolved, and by better evidence than I asked for. Your source-anchored check settles it: the V_FLAG_CRL_CHECK_ALL line is present in ext/openssl/lib/openssl/ssl.rb at v3_2_2 and absent at v3_4_9, and 3.4.9's default gem is 3.3.1, which carries ruby/openssl#950. That's environment-independent in a way the runtime check isn't, and your point that the gem is a binding rather than the TLS implementation is the correct framing — I overstated it as a "downgrade of the TLS stack" when the system library is what actually changed behaviour here. Dating the pin to #4929 under Ruby 3.2.2 also explains why it was load-bearing then and isn't now.

The one residual is the one you named: correctness now depends on Ruby >= 3.4.8 rather than being enforced by the Gemfile. Given the earlier discussion — devs aren't expected to need Ruby, and the Ruby-bearing runtimes are infra you control with rbenv reading .ruby-version — that's a reasonable place to land, and the ruby file: experiment answered its own question.

Nothing security- or performance-relevant; build tooling only, no app code paths touched.


· branch mokagio/ruby-file

@mokagio mokagio added this to the 8.19 milestone Aug 14, 2026
@mokagio mokagio added [Type] Tooling Related to the Gradle build scripts and the setup or maintenance of the project build process. [Area] Tooling labels Aug 14, 2026
@mokagio mokagio self-assigned this Aug 14, 2026
@mokagio mokagio changed the title Remove openssl gem requirement and force Ruby version in Gemfile Remove openssl gem requirement Aug 14, 2026
@mokagio
mokagio requested a review from AliSoftware August 14, 2026 02:50
@mokagio
mokagio merged commit 2fdd592 into main Aug 14, 2026
24 of 26 checks passed
@mokagio
mokagio deleted the mokagio/ruby-file branch August 14, 2026 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Area] Tooling [Type] Tooling Related to the Gradle build scripts and the setup or maintenance of the project build process.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants