Use central repository to lock flake inputs

Hi,

I have a few projects I want the CI to build and release weekly.
(The objective is to release OCI images using nix2container, but that’s irrelevant).

  1. I want all projects to use the same nixpkgs, rust-overlay, … versions.
  2. I want to track the pinned versions in a central git repository (call this “my-pins”).
  3. I want to avoid impure builds in the projects.
  4. I want to avoid a weekly “flake.lock: Update” commit in the projects.

Here’s my idea:

  • Every week, the flake.lock in my-pins is updated.
  • my-pins releases a “builder-image” when the pin is updated with a “configured” environment to run “nix build” (registry.json, substituters, …), including pinning the versions in the registry.json.
  • My project’s CI pipeline runs when the “builder-image” or the default branch is updated.

The problem is that I can’t use a pure evaluation mode:

$ nix eval --raw --expr '(builtins.getFlake "nixpkgs").rev'
error:
       … while calling the 'getFlake' builtin
         at «string»:1:2:
            1| (builtins.getFlake "nixpkgs").rev
             |  ^

       error: cannot call 'getFlake' on unlocked flake reference 'nixpkgs', at «none»:0 (use --impure to override)

If I provide the expression via “–file”, this works:

$ nix eval --raw --file =(echo '(builtins.getFlake "nixpkgs").rev')
00c21e4c93d963c50d4c0c89bfa84ed6e0694df2

But it’s also completely impure:

$ nix eval --raw --file =(echo 'builtins.getEnv "PATH"')
/run/wrappers/bin:/var/home/user/.local/bin:/var/home/user/.nix-profile/bin:/nix/profile/bin:/var/home/user/.local/state/nix/profile/bin:/etc/profiles/per-user/user/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin

I understand what I want is not quite pure: I want to use nix expressions from
the registry of the machine evaluating the expression; but I only want the path
resolution impurity, not all of the other possible impurities (e.g. getEnv).

I’m tempted to write add a flake.nix to each downstream project, and not commit the lockfile to version control; then start by running nix flake lock –commit in the ci (and expose the lockfile as a CI artifact).

This goes against all my reflexes while using flakes; plus seems like a pain for any developer. I would find more elegant for developers to add “my-pins” to their user registry.

You don’t have to put flakes into every projects. You can have your flake repo and use the projects as src for the derivations in the flake repo. I feel like that’s the one option that you haven’t dismissed yet.

1 Like

Thanks for the suggestion!

Sorry for the delay, I haven’t had the time to fully test (only a quick-and-dirty test), but I think this is a viable option :slight_smile:
I also discovered flake-parts while playing with it which makes it so much cleaner!

Thank you!

Edit: I’m accepting this as a solution since I think it will work and I don’t want to “forget” to come back and accept it later. Will re-open if I find challenges.