Skip to content

[build] Regenerate Ruby lockfile in rb:pin task - #17768

Closed
diemol wants to merge 1 commit into
trunkfrom
fix/rb-pin-regenerate-lockfile
Closed

[build] Regenerate Ruby lockfile in rb:pin task#17768
diemol wants to merge 1 commit into
trunkfrom
fix/rb-pin-regenerate-lockfile

Conversation

@diemol

@diemol diemol commented Jul 11, 2026

Copy link
Copy Markdown
Member

💥 What does this PR do?

rb:pin only synced gem checksums from the existing Gemfile.lock into MODULE.bazel; it never re-ran bundle to update the lockfile itself. Every other language's :pin task (java, py, dotnet, node, rust) does regenerate its lockfile, so rb:pin was the odd one out.

This let rb/Gemfile.lock drift after a release: the version-bump commit updates rb/lib/selenium/webdriver/version.rb, but the release workflow's reset-dependencies step (./go rb:pin) left the self-referencing selenium-webdriver path-gem entry pinned to the old released version. Bundler's frozen mode then rejects the mismatch, breaking bazel run //rb:rubocop on trunk (e.g. run 29134193142).

Run //rb:bundle-update before syncing checksums so rb:pin is self-sufficient, matching the other languages' :pin contract.

🤖 AI assistance

  • No substantial AI assistance used
  • AI assisted (complete below)
    • Tool(s): Claudio
    • What was generated: The fix after reasoning for a while.
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

🔄 Types of changes

  • Bug fix (backwards compatible)

rb:pin only synced gem checksums from the existing Gemfile.lock into
MODULE.bazel; it never re-ran bundle to update the lockfile itself.
Every other language's :pin task (java, py, dotnet, node, rust) does
regenerate its lockfile, so rb:pin was the odd one out.

This let rb/Gemfile.lock drift after a release: the version-bump commit
updates rb/lib/selenium/webdriver/version.rb, but the release
workflow's reset-dependencies step (./go rb:pin) left the
self-referencing selenium-webdriver path-gem entry pinned to the old
released version. Bundler's frozen mode then rejects the mismatch,
breaking `bazel run //rb:rubocop` on trunk (e.g. run 29134193142).

Run //rb:bundle-update before syncing checksums so rb:pin is
self-sufficient, matching the other languages' :pin contract.
@selenium-ci selenium-ci added the B-build Includes scripting, bazel and CI integrations label Jul 11, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Regenerate Ruby Gemfile.lock during rb:pin

🐞 Bug fix ⚙️ Configuration changes 🕐 Less than 10 minutes

Grey Divider

AI Description

• Run //rb:bundle-update as part of rb:pin before syncing gem checksums.
• Prevent Gemfile.lock drift after releases that breaks Bundler frozen-mode checks.
• Align Ruby pinning behavior with other languages' pin tasks.
Diagram

graph TD
  pin(["rb:pin"]) --> bazel(["Bazel"]) --> upd(["//rb:bundle-update"]) --> lock["rb/Gemfile.lock"]
  lock["rb/Gemfile.lock"] --> pin(["rb:pin"]) --> rubygems{{"RubyGems.org"}} --> module["MODULE.bazel"]
  subgraph Legend
    direction LR
    _task(["Task"]) ~~~ _file["File"] ~~~ _ext{{"External"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Fix only the release workflow (run bundle-update before rb:pin)
  • ➕ Avoids changing rb:pin behavior for local developers
  • ➕ Keeps rb:pin limited to checksum syncing
  • ➖ rb:pin remains inconsistent with other languages’ pin tasks
  • ➖ Future workflows or developers can still trigger the drift/breakage
  • ➖ Harder to reason about the 'pin' contract across the repo
2. Fold checksum syncing into //rb:bundle-update (single Bazel target)
  • ➕ One command becomes the single source of truth for Ruby dependency state
  • ➕ Potentially simpler orchestration (Bazel-only, less rake logic)
  • ➖ Bigger refactor and higher risk than needed for the immediate bug
  • ➖ Blurs responsibility if bundle-update is expected to be a pure lockfile operation

Recommendation: Keep the PR’s approach: making rb:pin run //rb:bundle-update first is the most robust and consistent fix. It eliminates the drift class of failures regardless of which workflow invokes rb:pin, and matches the existing multi-language expectation that ':pin' regenerates the lockfile/lock state before syncing downstream metadata.

Files changed (1) +2 / -0

Bug fix (1) +2 / -0
ruby.rakeRun //rb:bundle-update before syncing gem checksums in rb:pin +2/-0

Run //rb:bundle-update before syncing gem checksums in rb:pin

• Updates the rb:pin rake task to invoke the Bazel //rb:bundle-update target before reading rb/Gemfile.lock and syncing gem checksums into MODULE.bazel. This prevents stale lockfile state (e.g., after version bumps) from producing mismatched dependencies under Bundler frozen mode.

rake_tasks/ruby.rake

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

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

Context used
✅ Compliance rules (platform): 11 rules

Grey Divider


Action required

1. Pin upgrades gem versions 🐞 Bug ≡ Correctness
Description
rb:pin now invokes //rb:bundle-update, but that target runs bundle update, which can change locked
gem versions (not just regenerate the lockfile metadata) and unexpectedly modify rb/Gemfile.lock and
MODULE.bazel when pinning. This is inconsistent with other languages’ pin tasks that regenerate
lockfiles without upgrading dependencies and can introduce unintended dependency bumps in automation
that runs rb:pin.
Code

rake_tasks/ruby.rake[R192-193]

+  Bazel.execute('run', [], '//rb:bundle-update')
+
Evidence
The new rb:pin behavior unconditionally runs //rb:bundle-update, and that Bazel runnable shells
out to bundle update, which upgrades gems rather than simply regenerating a lockfile. Other
language pin tasks show the expected pattern: regenerate lockfiles without upgrading
(install/generate-lockfile vs update/upgrade).

rake_tasks/ruby.rake[190-196]
rb/support/bundle_update.rb[20-39]
rake_tasks/node.rake[42-45]
rake_tasks/dotnet.rake[128-134]
rake_tasks/rust.rake[26-34]

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

### Issue description
`rb:pin` now calls `//rb:bundle-update`, which executes `bundle update` and can upgrade dependency versions as a side effect of pinning.

### Issue Context
Other `:pin` tasks (node/dotnet/rust) regenerate lockfiles without upgrading. For Ruby, the desired behavior is to refresh the lockfile (e.g., to pick up local path-gem version changes) without broad dependency upgrades.

### Fix Focus Areas
- rake_tasks/ruby.rake[190-196]
- rb/support/bundle_update.rb[20-39]
- rb/BUILD.bazel[180-191]

### Suggested fix
- Add a separate Bazel runnable (e.g., `//rb:bundle-install` or `//rb:bundle-lock`) that runs `bundle install` (or `bundle lock`) to refresh `Gemfile.lock` without upgrading versions.
- Update `rb:pin` to call that new target instead of `//rb:bundle-update`.
- Keep `//rb:bundle-update` (running `bundle update`) only for the explicit `rb:update` workflow.

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



Remediation recommended

2. No tests for rb:pin 📘 Rule violation ▣ Testability
Description
The PR changes rb:pin behavior by running //rb:bundle-update, but no regression test is added to
ensure this contract stays enforced. Without coverage, this bug fix can silently regress and break
rb:pin/frozen-bundler workflows again.
Code

rake_tasks/ruby.rake[R190-194]

desc 'Sync gem checksums from Gemfile.lock to MODULE.bazel (use force to re-download all)'
task :pin, [:force] do |_task, arguments|
+  Bazel.execute('run', [], '//rb:bundle-update')
+
  gemfile_lock = 'rb/Gemfile.lock'
Evidence
PR Compliance ID 389273 requires tests for bug fixes/new functionality. The updated rb:pin task
now executes Bazel.execute('run', [], '//rb:bundle-update'), introducing a new behavior that
should be covered by a regression test.

Rule 389273: Require tests for all new functionality and bug fixes
rake_tasks/ruby.rake[190-194]

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

## Issue description
`rb:pin` now runs `//rb:bundle-update` before syncing checksums, but there is no automated test ensuring this behavior remains true.

## Issue Context
This is a bug fix that changes the behavior/contract of the `rb:pin` tooling task; it should be protected by at least one automated regression test that would fail if the `bundle-update` step were removed or reordered.

## Fix Focus Areas
- rake_tasks/ruby.rake[190-246]

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


3. bundle-update executed twice 🐞 Bug ➹ Performance
Description
rb:update runs //rb:bundle-update and then invokes rb:pin, which now runs //rb:bundle-update again,
doubling the work (and network/CPU) in the update flow. This redundancy can significantly slow down
rb:update with no functional benefit.
Code

rake_tasks/ruby.rake[R192-193]

+  Bazel.execute('run', [], '//rb:bundle-update')
+
Evidence
The update task explicitly runs //rb:bundle-update and then calls rb:pin; with the new change,
rb:pin also runs //rb:bundle-update, making the command execute twice per rb:update
invocation.

rake_tasks/ruby.rake[191-193]
rake_tasks/ruby.rake[248-254]

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

### Issue description
`rb:update` currently runs `//rb:bundle-update` and then calls `rb:pin`, but `rb:pin` now also runs `//rb:bundle-update`, causing duplicate work.

### Issue Context
This redundancy was introduced by adding `//rb:bundle-update` to `rb:pin`.

### Fix Focus Areas
- rake_tasks/ruby.rake[191-193]
- rake_tasks/ruby.rake[248-254]

### Suggested fix
Pick one:
- If `rb:pin` remains responsible for lockfile regeneration, remove the explicit `Bazel.execute('run', [], '//rb:bundle-update')` from `rb:update`.
- Or, if you split responsibilities (recommended): make `rb:pin` run a non-upgrading lockfile refresh (e.g., `bundle install`), and keep `rb:update` as the only place that runs `bundle update`.

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


Grey Divider

Qodo Logo

Comment thread rake_tasks/ruby.rake
Comment on lines 190 to 194
desc 'Sync gem checksums from Gemfile.lock to MODULE.bazel (use force to re-download all)'
task :pin, [:force] do |_task, arguments|
Bazel.execute('run', [], '//rb:bundle-update')

gemfile_lock = 'rb/Gemfile.lock'

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.

Remediation recommended

1. No tests for rb:pin 📘 Rule violation ▣ Testability

The PR changes rb:pin behavior by running //rb:bundle-update, but no regression test is added to
ensure this contract stays enforced. Without coverage, this bug fix can silently regress and break
rb:pin/frozen-bundler workflows again.
Agent Prompt
## Issue description
`rb:pin` now runs `//rb:bundle-update` before syncing checksums, but there is no automated test ensuring this behavior remains true.

## Issue Context
This is a bug fix that changes the behavior/contract of the `rb:pin` tooling task; it should be protected by at least one automated regression test that would fail if the `bundle-update` step were removed or reordered.

## Fix Focus Areas
- rake_tasks/ruby.rake[190-246]

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

Comment thread rake_tasks/ruby.rake
Comment on lines +192 to +193
Bazel.execute('run', [], '//rb:bundle-update')

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.

Action required

2. Pin upgrades gem versions 🐞 Bug ≡ Correctness

rb:pin now invokes //rb:bundle-update, but that target runs bundle update, which can change locked
gem versions (not just regenerate the lockfile metadata) and unexpectedly modify rb/Gemfile.lock and
MODULE.bazel when pinning. This is inconsistent with other languages’ pin tasks that regenerate
lockfiles without upgrading dependencies and can introduce unintended dependency bumps in automation
that runs rb:pin.
Agent Prompt
### Issue description
`rb:pin` now calls `//rb:bundle-update`, which executes `bundle update` and can upgrade dependency versions as a side effect of pinning.

### Issue Context
Other `:pin` tasks (node/dotnet/rust) regenerate lockfiles without upgrading. For Ruby, the desired behavior is to refresh the lockfile (e.g., to pick up local path-gem version changes) without broad dependency upgrades.

### Fix Focus Areas
- rake_tasks/ruby.rake[190-196]
- rb/support/bundle_update.rb[20-39]
- rb/BUILD.bazel[180-191]

### Suggested fix
- Add a separate Bazel runnable (e.g., `//rb:bundle-install` or `//rb:bundle-lock`) that runs `bundle install` (or `bundle lock`) to refresh `Gemfile.lock` without upgrading versions.
- Update `rb:pin` to call that new target instead of `//rb:bundle-update`.
- Keep `//rb:bundle-update` (running `bundle update`) only for the explicit `rb:update` workflow.

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

Comment thread rake_tasks/ruby.rake
Comment on lines +192 to +193
Bazel.execute('run', [], '//rb:bundle-update')

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.

Remediation recommended

3. Bundle-update executed twice 🐞 Bug ➹ Performance

rb:update runs //rb:bundle-update and then invokes rb:pin, which now runs //rb:bundle-update again,
doubling the work (and network/CPU) in the update flow. This redundancy can significantly slow down
rb:update with no functional benefit.
Agent Prompt
### Issue description
`rb:update` currently runs `//rb:bundle-update` and then calls `rb:pin`, but `rb:pin` now also runs `//rb:bundle-update`, causing duplicate work.

### Issue Context
This redundancy was introduced by adding `//rb:bundle-update` to `rb:pin`.

### Fix Focus Areas
- rake_tasks/ruby.rake[191-193]
- rake_tasks/ruby.rake[248-254]

### Suggested fix
Pick one:
- If `rb:pin` remains responsible for lockfile regeneration, remove the explicit `Bazel.execute('run', [], '//rb:bundle-update')` from `rb:update`.
- Or, if you split responsibilities (recommended): make `rb:pin` run a non-upgrading lockfile refresh (e.g., `bundle install`), and keep `rb:update` as the only place that runs `bundle update`.

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

@diemol
diemol requested a review from titusfortner July 11, 2026 15:00
@diemol

diemol commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@titusfortner does this change make sense? After merging the release PR, I saw in trunk that the Gemllock file was out of sync. In theory, this fixes it for the next one.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants