Nix copy that only builds what it needs to copy

Is there something like nix copy that only realizes things in the --from store if they are not present in the --to store? My application is a CI runner whose job is to populate a binary cache.

It doesn’t need to have the packages locally, just needs to copy/build the new ones to put them in the binary cache. I can achieve the same thing with

OUTPATH=$(nix eval --raw ".#p.outPath");
if ! nix store ls --store '' "${OUTPATH}"; then
  nix copy -L --to '' ".#p"

but then I pay the evaluation costs twice in the uncached case.

1 Like

cachix is able to do this, but I’m not sure the underlying mechanism. IIRC, it might be using it’s own protocol.

1 Like

nix-fast-build can also do this, with --copy-to and --skip-cached. (It also will recurseForDerivations by default, very handy for flake outputs! I :heart: :heart: nix-fast-build)

(It also can mix “smart” remote building in, where the flake source is copied to builder, eval’d there, which avoids all sorts of headaches with how remote building usually otherwise works)