Reproducible Builds for Ruby Gems
Last updated: 2024-01-30
What are they and why do I care?
A reproducible build is one where you can run the build process again and get artifacts that are identical.
Reproducible builds allow people to identify problems such as compromised build environments or releases not using the official source.
What’s it look like in practice?
When gem reproduce
succeeds, it looks like this:
~/test$ git clone --quiet https://github.com/duckinator/okay.git
~/test$ cd okay
~/test/okay$ git checkout v12.0.3
HEAD is now at 40fe265 Merge pull request #16 from duckinator/bump-deps
puppy@orthrus:~/test/okay$ gem rebuild okay 12.0.3
Fetching okay-12.0.3.gem
Downloaded okay version 12.0.3 as /tmp/gem_rebuild20240130-73307-ai5jxs/old/okay-12.0.3.gem.
Successfully built RubyGem
Name: okay
Version: 12.0.3
File: okay-12.0.3.gem
Built at: 2024-01-01 08:05:03 EST (1704114303)
Original build saved to: /tmp/gem_rebuild20240130-73307-ai5jxs/old/okay-12.0.3.gem
Reproduced build saved to: /tmp/gem_rebuild20240130-73307-ai5jxs/new/okay-12.0.3.gem
Working directory: /usr/home/puppy/test/okay
Hash comparison:
c6017966f3498623910f9a4a7bfcbd98ebab881f0e1315491b3340afa2e20b1c /tmp/gem_rebuild20240130-73307-ai5jxs/old/okay-12.0.3.gem
c6017966f3498623910f9a4a7bfcbd98ebab881f0e1315491b3340afa2e20b1c /tmp/gem_rebuild20240130-73307-ai5jxs/new/okay-12.0.3.gem
SUCCESS - original and rebuild hashes matched
~/test/okay$
When it fails, it looks like this:
~/test/okay$ echo "# some change" >> lib/okay.rb
~/test/okay$ gem rebuild okay 12.0.3
Fetching okay-12.0.3.gem
Downloaded okay version 12.0.3 as /tmp/gem_rebuild20240130-73881-x2dknj/old/okay-12.0.3.gem.
WARNING: open-ended dependency on cacert (>= 0) is not recommended
use a bounded requirement, such as "~> x.y"
WARNING: See https://guides.rubygems.org/specification-reference/ for help
Successfully built RubyGem
Name: okay
Version: 12.0.3
File: okay-12.0.3.gem
Built at: 2024-01-01 08:05:03 EST (1704114303)
Original build saved to: /tmp/gem_rebuild20240130-73881-x2dknj/old/okay-12.0.3.gem
Reproduced build saved to: /tmp/gem_rebuild20240130-73881-x2dknj/new/okay-12.0.3.gem
Working directory: /usr/home/puppy/test/okay
Hash comparison:
c6017966f3498623910f9a4a7bfcbd98ebab881f0e1315491b3340afa2e20b1c /tmp/gem_rebuild20240130-73881-x2dknj/old/okay-12.0.3.gem
8910ae67d46e9cccc59c2a2dd08b29ddf03ac703bc95bcc7f69e1722926def94 /tmp/gem_rebuild20240130-73881-x2dknj/new/okay-12.0.3.gem
FAILURE - original and rebuild hashes did not match
~/test/okay$
When --diff
is specified, it’ll run the resulting files through diffoscope
if they don’t match.
How do I make this work for my project?
Check back soon; still working on the details of this part. ♥