I have built a script that takes Cargo.lock
, downloads crates listed there and tries to reproduce them: GitHub - link2xt/cargo-repack: Utility to test reproducibility of crates from Cargo.lock
It works by downloading the crate from static.crates.io, looking up the repository
from Cargo.toml
packaged inside and git revision from .cargo_vcs_info.json
, then rebuilding the crate locally using cargo package
.
It then compares built crate using to the one downloaded from crates.io and runs diffoscope
if the result is different.
I ran it on GitHub - deltachat/deltachat-core-rust: Delta Chat Rust Core library, used by Android/iOS/desktop apps, bindings and bots 📧 and it managed to reproduce 523 out of 569 crates. Failures are mostly due to:
- Old crates that have been published with older versions of
cargo
and have different format of.cargo_vcs_info.json
. - Publishing from a dirty worktree.
- Publishing from a commit that is not pushed to the repository afterwards.
I think Rust does not discourage --allow-dirty
flag or even suggests it when worktree is dirty. The result is that a lot of developers publish crates that are slightly different from the repository, e.g. have different Cargo.lock
or debug
settings locally modified in Cargo.toml
like in pgp-0.12.0-alpha.1 crate is published with modified Cargo.toml · Issue #327 · rpgp/rpgp · GitHub
If you publish crates to crates.io, make sure you always publish from a clean worktree.
I would also like to modify the way I build crates in a reproducible way, e.g. by running cargo package
inside Nix, but then there is apparently no way to upload built package to crates.io afterwards with another command.