Skip to content

[rb] generate version.rb from the root version.bzl so tests do not read the version - #18164

Merged
titusfortner merged 4 commits into
SeleniumHQ:trunkfrom
titusfortner:rb-generated-version
Oct 13, 2026
Merged

titusfortner merged 4 commits into
SeleniumHQ:trunkfrom
titusfortner:rb-generated-version

Conversation

@titusfortner

@titusfortner titusfortner commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

🔗 Related Issues

Builds on #18138 (Java and .NET versions moved to a root version.bzl that tests do not read)
Equivalent to #18158 for Python
Carries bazel-contrib/rules_ruby#421 as a patch until it is released

💥 What does this PR do?

  • Stops Ruby version bumps from invalidating the bundle install and every Ruby test.
  • This should prevent rerunning ~200 Ruby RBE tests (3.5h of the 17h of test time) on a release PR, which could take ~5 minutes off the RBE job.
  • The Ruby version now lives in the root version.bzl alongside Java and .NET.

🔧 Implementation Notes

  • version.rb is generated from version.rb.tpl: --stamp builds get the real version, unstamped builds get 4.999.0.dev, which has to stay within selenium-devtools' ~> 4.2 requirement or Bundler re-resolves and fails.
  • Ruby can't use VERSION_STUB like Python and .NET because the gemspec reads VERSION and Bundler requires a valid Gem::Version.
  • @bundle previously copied version.rb at fetch time, so every bump reinstalled the bundle; a rules_ruby patch adds generated_srcs, which stages build outputs into the bundle and rewrites path gem versions in its copy of Gemfile.lock to match the gemspecs.
  • Gemfile.lock keeps the real version, and the patch makes it irrelevant whether it matches version.bzl, so the nightly date suffix no longer needs a separate bump target.
  • //rb:bundle-lock, //rb:bundle-update and rb:local_dev write a gitignored version.rb so Bundler still works outside Bazel; generated_srcs never reads it.
  • To roll back, revert this PR and set the restored version.rb to the current version in version.bzl, which makes version.rb the single source again.

🤖 AI assistance

  • AI assisted (complete below)
    • Tool(s): Claude Code (Opus 5.5)
    • What was generated: the comparison of rules_ruby approaches, the RBE timing analysis, the change, the local verification, and this description
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

🔄 Types of changes

  • Cleanup (build configuration; unstamped builds now report 4.999.0.dev as Selenium::WebDriver::VERSION)

@selenium-ci selenium-ci added C-rb Ruby Bindings B-build Includes scripting, bazel and CI integrations labels Oct 13, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Generate Ruby version from the root version file without invalidating tests

✨ Enhancement ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Move Ruby’s release version into the root version file and generate version.rb for Bazel builds.
• Use a stable version in unstamped builds to preserve Ruby test and bundle-install caches across
 releases.
• Stage generated bundle inputs at build time while retaining local Bundler and nightly release
 workflows.
Diagram

graph TD
  A["Root version.bzl"] --> B["Ruby version.bzl"] --> C{"Stamp enabled?"}
  C -->|yes| E["Generated version.rb"] --> F["Stage and normalize"] --> G["Bundle install"] --> H["Ruby tests"]
  C -->|no, use stub| E
  D["Ruby template"] --> E
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep a checked-in Ruby version file
  • ➕ Avoids patching rules_ruby and changing bundle installation.
  • ➖ Every release bump remains an input change to bundle fetching and Ruby tests.
2. Use a project-specific bundle installation rule
  • ➕ Avoids modifying rules_ruby’s general-purpose bundle rules.
  • ➖ Duplicates Bundler integration and requires ongoing maintenance alongside rules_ruby.

Recommendation: The build-time generated-source approach best addresses both test caching and Bundler’s need to evaluate a real gem version. Upstreaming the rules_ruby support is preferable to carrying the patch long-term; review its staged-path and lockfile behavior across supported Ruby platforms before relying on it.

Files changed (10) +440 / -25

Enhancement (1) +14 / -1
BUILD.bazelGenerate version.rb with stamp-aware values +14/-1

Generate version.rb with stamp-aware values

• Adds an 'expand_template' target that substitutes the release version when stamped and a stable development version otherwise. The Ruby version library consumes that generated output.

rb/lib/selenium/webdriver/BUILD.bazel

Refactor (1) +0 / -12
BUILD.bazelRemove the nightly version-bump binary +0/-12

Remove the nightly version-bump binary

• Deletes the Bazel target that edited 'version.rb' for nightly releases. The Rake release task now writes the dated version to the root version file.

rb/BUILD.bazel

Other (8) +426 / -12
release.ymlStop watching the generated Ruby version file +0/-1

Stop watching the generated Ruby version file

• Removes 'version.rb' from release workflow path triggers. The root 'version.bzl' remains the watched source for Ruby version changes.

.github/workflows/release.yml

.gitignoreIgnore the local Ruby version file +1/-0

Ignore the local Ruby version file

• Ignores 'rb/lib/selenium/webdriver/version.rb', which local Rake tasks now write for Bundler outside Bazel.

.gitignore

MODULE.bazelWire generated Ruby sources into bundle fetching +3/-1

Wire generated Ruby sources into bundle fetching

• Applies a new rules_ruby patch and moves 'version.rb' from fetch-time 'srcs' to build-time 'generated_srcs'. This prevents bundle repository fetching from reading the locally generated version file.

MODULE.bazel

ruby.rakeRead Ruby versions from the root and support local Bundler +12/-9

Read Ruby versions from the root and support local Bundler

• Version and nightly release tasks now write the Ruby entry in 'version.bzl' rather than editing 'version.rb'; nightly publishing adds its date suffix there. The pin and local-development tasks generate an ignored 'version.rb' from the template for Bundler outside Bazel.

rake_tasks/ruby.rake

version.rb.tplParameterize the Ruby VERSION constant +1/-1

Parameterize the Ruby VERSION constant

• Replaces the hard-coded nightly version with a template placeholder for Bazel generation and local Rake use.

rb/lib/selenium/webdriver/version.rb.tpl

version.bzlDefine Ruby release and unstamped versions +7/-0

Define Ruby release and unstamped versions

• Exposes the Ruby version from the root 'version.bzl' and defines '4.999.0.dev' for unstamped builds. The stub remains compatible with selenium-devtools’ '~> 4.2' dependency.

rb/version.bzl

rules_ruby_lazy_bundle_srcs.patchStage generated bundle sources and normalize path-gem versions +401/-0

Stage generated bundle sources and normalize path-gem versions

• Adds 'generated_srcs' to rules_ruby bundle fetching so generated files are referenced without being read at repository-fetch time. At build time, the patch stages bundle inputs, rewrites path-gem versions in a staged 'Gemfile.lock' copy to match their gemspecs, and installs from that tree.

third_party/bazel/rules_ruby_lazy_bundle_srcs.patch

version.bzlMake the root version file authoritative for Ruby +1/-0

Make the root version file authoritative for Ruby

• Adds the Ruby nightly version to the shared binding-version map, replacing the checked-in Ruby source file as its release-version source.

version.bzl

@qodo-code-review

qodo-code-review Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Browser updates fail when Ruby lock changes ✓ Resolved
Description
Generating version.rb only as a Bazel output leaves selenium-webdriver.gemspec unable to require
it when Bundler evaluates the source-tree Gemfile. On a fresh checkout, the scheduled browser-update
script reaches //rb:bundle-lock after regenerating Chrome DevTools without first writing the local
file; the documented bundle install command has the same failure.
Code

rb/lib/selenium/webdriver/BUILD.bazel[113]

+    out = "version.rb",
Evidence
The Gemfile loads the gemspec, which requires the version file. The new BUILD target produces that
file in Bazel rather than in the checkout; the browser-update script invokes the source-tree lock
command without either rake task that writes a local copy.

rb/Gemfile[3-5]
rb/selenium-webdriver.gemspec[3-9]
rb/lib/selenium/webdriver/BUILD.bazel[111-124]
scripts/github-actions/update_browsers.sh[45-53]
rb/support/bundle.rb[26-41]
rake_tasks/ruby.rake[10-14]
rb/TESTING.md[81-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Bundler reads the source-tree gemspec, which requires `version.rb`, but a fresh checkout now has only the template and the Bazel-generated output.
## Fix Focus Areas
- scripts/github-actions/update_browsers.sh[45-53]
- rb/lib/selenium/webdriver/BUILD.bazel[111-124]
- rake_tasks/ruby.rake[10-14]
## Recommended Fix
Ensure every workflow that runs Bundler against the source-tree Gemfile generates a local `version.rb` first, including the browser-update script. Provide the same prerequisite for the documented direct Bundler setup path, without making Bazel's generated source depend on that local copy.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. A vendor patch changes third-party code ✗ Dismissed
Description
The PR adds third_party/bazel/rules_ruby_lazy_bundle_srcs.patch, which modifies the vendored Ruby
build rules. Because the changed file is under third_party/, the repository carries a direct
modification to third-party content rather than limiting changes to maintained project files.
Code

third_party/bazel/rules_ruby_lazy_bundle_srcs.patch[R1-4]

+diff --git a/ruby/extensions.bzl b/ruby/extensions.bzl
+index 8507e76b..d1d32dfc 100644
+--- a/ruby/extensions.bzl
++++ b/ruby/extensions.bzl
Evidence
The checklist prohibits modifications to files under third_party/, and this PR adds the rules Ruby
patch at that location.

AGENTS.md: Do Not Modify Third-Party or Generated Output Files
third_party/bazel/rules_ruby_lazy_bundle_srcs.patch[1-4]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR adds a patch under `third_party/`, modifying third-party Ruby build-rule content contrary to the repository compliance requirement.

## Fix Focus Areas
- third_party/bazel/rules_ruby_lazy_bundle_srcs.patch[1-4]

## Recommended Fix
Move the maintained implementation out of the prohibited third-party content area, or update the dependency through its supported upstream/versioning mechanism instead of adding a modified third-party patch file.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: Auto: ⏭️ Skipped: Only Bazel comments changed; no behavioral or configuration semantics changed.

Grey Divider

Tip of the day
💡 Did you know, you can turn these tips off under Display > Comment parts

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit d7b7402

Results up to commit ad9963b ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. A vendor patch changes third-party code ✗ Dismissed
Description
The PR adds third_party/bazel/rules_ruby_lazy_bundle_srcs.patch, which modifies the vendored Ruby
build rules. Because the changed file is under third_party/, the repository carries a direct
modification to third-party content rather than limiting changes to maintained project files.
Code

third_party/bazel/rules_ruby_lazy_bundle_srcs.patch[R1-4]

+diff --git a/ruby/extensions.bzl b/ruby/extensions.bzl
+index 8507e76b..d1d32dfc 100644
+--- a/ruby/extensions.bzl
++++ b/ruby/extensions.bzl
Evidence
The checklist prohibits modifications to files under third_party/, and this PR adds the rules Ruby
patch at that location.

AGENTS.md: Do Not Modify Third-Party or Generated Output Files
third_party/bazel/rules_ruby_lazy_bundle_srcs.patch[1-4]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR adds a patch under `third_party/`, modifying third-party Ruby build-rule content contrary to the repository compliance requirement.

## Fix Focus Areas
- third_party/bazel/rules_ruby_lazy_bundle_srcs.patch[1-4]

## Recommended Fix
Move the maintained implementation out of the prohibited third-party content area, or update the dependency through its supported upstream/versioning mechanism instead of adding a modified third-party patch file.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Browser updates fail when Ruby lock changes ✓ Resolved
Description
Generating version.rb only as a Bazel output leaves selenium-webdriver.gemspec unable to require
it when Bundler evaluates the source-tree Gemfile. On a fresh checkout, the scheduled browser-update
script reaches //rb:bundle-lock after regenerating Chrome DevTools without first writing the local
file; the documented bundle install command has the same failure.
Code

rb/lib/selenium/webdriver/BUILD.bazel[113]

+    out = "version.rb",
Evidence
The Gemfile loads the gemspec, which requires the version file. The new BUILD target produces that
file in Bazel rather than in the checkout; the browser-update script invokes the source-tree lock
command without either rake task that writes a local copy.

rb/Gemfile[3-5]
rb/selenium-webdriver.gemspec[3-9]
rb/lib/selenium/webdriver/BUILD.bazel[111-124]
scripts/github-actions/update_browsers.sh[45-53]
rb/support/bundle.rb[26-41]
rake_tasks/ruby.rake[10-14]
rb/TESTING.md[81-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Bundler reads the source-tree gemspec, which requires `version.rb`, but a fresh checkout now has only the template and the Bazel-generated output.
## Fix Focus Areas
- scripts/github-actions/update_browsers.sh[45-53]
- rb/lib/selenium/webdriver/BUILD.bazel[111-124]
- rake_tasks/ruby.rake[10-14]
## Recommended Fix
Ensure every workflow that runs Bundler against the source-tree Gemfile generates a local `version.rb` first, including the browser-update script. Provide the same prerequisite for the documented direct Bundler setup path, without making Bazel's generated source depend on that local copy.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread third_party/bazel/rules_ruby_lazy_bundle_srcs.patch
Comment thread rb/lib/selenium/webdriver/BUILD.bazel
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 8a2c54a

@selenium-ci

Copy link
Copy Markdown
Member

/agentic_review

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit d7b7402

@titusfortner

Copy link
Copy Markdown
Member Author

I'm going to merge this and we can see how it does with next week's release. If we decide not to implement this in rules_ruby, we should revert this PR rather than maintain the patch.

@titusfortner
titusfortner merged commit 1c6ee4a into SeleniumHQ:trunk Oct 13, 2026
21 of 26 checks passed
@Earlopain

Copy link
Copy Markdown
Contributor

This breaks using the gem as a git source (like gem "selenium-webdriver", git: "https://github.com/SeleniumHQ/selenium" because it tries to load the version file and it won't be available there.

@titusfortner

titusfortner commented Oct 15, 2026 •

Copy link
Copy Markdown
Member Author

@Earlopain it is already broken as a git source for some features (#displayed?, #attribute, all of Selenium Manager). It might actually be better to make it explicitly impossible rather than randomly breaking at runtime in unexpected places.

@titusfortner

Copy link
Copy Markdown
Member Author

We publish nightly gems you can use, see instructions here: https://github.com/SeleniumHQ/selenium/pkgs/rubygems/selenium-webdriver

@Earlopain

Copy link
Copy Markdown
Contributor

Thanks, but currently I'm just reading the source code uri from the gemspec (I'm not specifically testing against selenium). I guess it's better to break early.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations C-rb Ruby Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Sponsor
SponsoredKunjungi sekarang
Promo