Skip to content

Bundler: update git pins declared on git/github blocks - #16481

Open
matchbookmac wants to merge 6 commits into
dependabot:mainfrom
matchbookmac:bundler-git-block-pin
Open

matchbookmac wants to merge 6 commits into
dependabot:mainfrom
matchbookmac:bundler-git-block-pin

Conversation

@matchbookmac

@matchbookmac matchbookmac commented Oct 5, 2026 •

Copy link
Copy Markdown

What are you trying to accomplish?

Fixes #16435.

GitPinReplacer only rewrote tag:/ref: on gem "x", git: ..., tag: ... declarations. Bundler also lets you declare gems inside a git/github block, with the pin on the block's call:

git "https://github.com/example-org/shared-gems.git", tag: "v1.1.0", glob: "gems/*/*.gemspec" do
  gem "gem-a"
  gem "gem-b"
end

For these gems the Gemfile was never rewritten, so the lockfile re-resolved to the same content and LockfileUpdater#updated_lockfile_content raised RuntimeError: Expected content to change!. In a grouped update, that one failure marks every group member as unknown_error, and no PR gets opened.

Anything you want to highlight for special attention from reviewers?

  • Rewriter#on_block now rewrites the pin on a top-level git/github block call when the block body declares the targeted gem. It then calls super so nested gem declarations are still visited. Blocks that don't declare the gem, and non-git blocks such as group, are left alone.
  • The existing kwargs-rewriting logic was pulled into update_pins so the gem and block paths share it. It also now guards against a call whose last argument isn't a node.
  • GitPinReplacer is also used by UpdateChecker::FilePreparer#replace_git_pin, so block-declared gems get their pin replaced there too during resolution.
  • Custom git_source(:name) helpers aren't handled. That seemed out of scope.

How will you know you've accomplished your goal?

  • New GitPinReplacer unit specs cover: a single-gem git block, a multi-gem block next to an unrelated block (only the matching one changes), a github block, and a non-git block (untouched).
  • A new end-to-end FileUpdater spec uses a git_source_block fixture (dependabot-fixtures/que in a git ..., tag: "v0.11.6" do block, bumped to v0.12.0). It asserts that both the Gemfile tag and the lockfile tag:/revision: change. Without the fix, this spec reproduces the bug: the lockfile is unchanged.
  • Locally, spec/dependabot/bundler/file_updater* and spec/dependabot/bundler/update_checker pass (505 examples, 0 failures), and rubocop is clean on the changed files.

Checklist

  • I have run the complete test suite to ensure all tests and linters pass. (ran the bundler file updater and update checker suites, not the full suite)
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

馃 Generated with Claude Code

GitPinReplacer only rewrote `tag:`/`ref:` on `gem "x", git: ..., tag: ...`
declarations. When a gem is declared inside a `git "...", tag: "..." do`
(or `github`) block, the pin lives on the block's call, so the Gemfile was
left unchanged, the lockfile re-resolved to identical content, and
LockfileUpdater raised "Expected content to change!".

Rewrite the pin on a git/github block when its body declares the targeted
gem.

Fixes dependabot#16435

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matchbookmac
matchbookmac requested a review from a team as a code owner October 5, 2026 18:11
@github-actions github-actions Bot added the L: ruby:bundler RubyGems via bundler label Oct 5, 2026

This branch has not been deployed

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

Labels

L: ruby:bundler RubyGems via bundler

Projects

Status: No status

1 participant