Skip to content

Sorting files in metadata for build reproducibility#8569

Merged
duckinator merged 2 commits intoruby:masterfrom
giacomobenedetti:master
Mar 31, 2025
Merged

Sorting files in metadata for build reproducibility#8569
duckinator merged 2 commits intoruby:masterfrom
giacomobenedetti:master

Conversation

@giacomobenedetti
Copy link
Copy Markdown
Contributor

What was the end-user or developer problem that led to this PR?

Files sorting is system-dependent making a build not reproducible. This behavior can be seen using reprotest to manipulate the file ordering during a build.

What is your fix for the problem, implemented in this PR?

Adding a sort while reading files listed in metadata fixes this issue.

Make sure the following tasks are checked

@welcome
Copy link
Copy Markdown

welcome bot commented Mar 14, 2025

Thanks for opening a pull request and helping make RubyGems and Bundler better! Someone from the RubyGems team will take a look at your pull request shortly and leave any feedback. Please make sure that your pull request has tests for any changes or added functionality.

We use GitHub Actions to test and make sure your change works functionally and uses acceptable conventions, you can review the current progress of GitHub Actions in the PR status window below.

If you have any questions or concerns that you wish to ask, feel free to leave a comment in this PR or join our #rubygems or #bundler channel on Slack.

For more information about contributing to the RubyGems project feel free to review our CONTRIBUTING guide

@deivid-rodriguez
Copy link
Copy Markdown
Contributor

This PR seems fine to me.

The failing CI highlights in my opinion, a deficiency in gem exec. Currently, if foo includes several executables, and none of them is named foo, gem exec foo will run the first executable defined in spec.executables. This PR sorts that so one spec starts running a different executable. In my opinion, this case should be rejected as ambiguous and raise an error.

@deivid-rodriguez
Copy link
Copy Markdown
Contributor

I created #8573 to fix this gem exec issue. With that PR in place, I think this patch should pass cleanly.

@giacomobenedetti
Copy link
Copy Markdown
Contributor Author

Thank you @deivid-rodriguez!

@duckinator
Copy link
Copy Markdown
Contributor

duckinator commented Mar 25, 2025

I made #8587 so gem exec output isn't affected by metadata sort order. That should fix the remaining test failure.

This looks good aside from that!

@duckinator
Copy link
Copy Markdown
Contributor

Thank you for the help with this, @giacomobenedetti!

@duckinator duckinator merged commit 84d0dea into ruby:master Mar 31, 2025
84 checks passed
@deivid-rodriguez deivid-rodriguez changed the title Sorting files in metadata for reproducibility Sorting files in metadata for build reproducibility Apr 2, 2025
deivid-rodriguez pushed a commit that referenced this pull request Apr 2, 2025
Sorting files in metadata for reproducibility

(cherry picked from commit 84d0dea)
deivid-rodriguez pushed a commit that referenced this pull request Apr 2, 2025
Sorting files in metadata for reproducibility

(cherry picked from commit 84d0dea)
@JasonLunn
Copy link
Copy Markdown
Contributor

Apologies for being very late to the party, but I discovered today that this change is breaking for gems that build multiple native extensions where at least one of them isn't rake-based.

Sorting extensions here means that gem authors cannot control the order that extensions are listed in the serialized gem spec, which in turn influences what order native extensions are built. I wouldn't have thought it mattered, but once a gem extension has been built with rake, no other extensions are built. See this line in builder.rb, which has been in place for over a decade.

This is more than a hypothetical - the Google Protobuf gem I work on does exactly this - we have an extconf-based extension for the core implementation, and a rakefile-based extension that we use with ffi-compiler for our FFI implementation.

If I run gem build under ruby 3.4.1 today (implicitly with a version of rubygems that predates this change), the gem spec serialized into the .gem has the extconf.rb extension listed first, so at install time, the extconf extension is built first, then the rake one.

If I run gem build under ruby 4.0 (or any version where this change is included), the gem spec serialized into the .gem has the Rakefile extension listed first, so at install time, the it is built first, and then nothing else.

What I don't know is the best way to fix this. I don't know why builder.rb thinks it is okay to stop building extensions after the first time it builds a rake-based one. That seems wrong on its face, but the behavior has been there so long it seems like it must be there for a reason. The trivial fix would be to simply stop sorting extensions during validation, but I also don't know the history of this issue and why it was important to sort it in the first place.

@colby-swandale
Copy link
Copy Markdown
Member

colby-swandale commented Jan 13, 2026

@JasonLunn Would you be able to move this into a new issue with some steps to reproduce, so that we can track it and help debug?

copybara-service bot pushed a commit to protocolbuffers/protobuf that referenced this pull request Jan 13, 2026
Note: Building the protobuf gem with versions of rubygems that include ruby/rubygems#8569 is broken due to the issue reported in ruby/rubygems#9244. Workaround is to use a rubygems version below 3.7.0 to build the gem.

Closes #25051

COPYBARA_INTEGRATE_REVIEW=#25051 from frederikspang:main 83f91c7
FUTURE_COPYBARA_INTEGRATE_REVIEW=#25051 from frederikspang:main 83f91c7
PiperOrigin-RevId: 853462400
copybara-service bot pushed a commit to protocolbuffers/protobuf that referenced this pull request Jan 20, 2026
Note: Building the protobuf gem with versions of rubygems that include ruby/rubygems#8569 is broken due to the issue reported in ruby/rubygems#9244. Workaround is to use a rubygems version below 3.7.0 to build the gem.

Closes #25051

COPYBARA_INTEGRATE_REVIEW=#25051 from frederikspang:main 83f91c7
FUTURE_COPYBARA_INTEGRATE_REVIEW=#25051 from frederikspang:main 83f91c7
PiperOrigin-RevId: 853462400
copybara-service bot pushed a commit to protocolbuffers/protobuf that referenced this pull request Jan 20, 2026
Note: Building the protobuf gem with versions of rubygems that include ruby/rubygems#8569 is broken due to the issue reported in ruby/rubygems#9244. Workaround is to use a rubygems version below 3.7.0 to build the gem.

Closes #25051

COPYBARA_INTEGRATE_REVIEW=#25051 from frederikspang:main 83f91c7
PiperOrigin-RevId: 858713403
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants