Skip to content

Conversation

@edolstra
Copy link
Collaborator

@edolstra edolstra commented May 1, 2025

Motivation

This PR does two things:

  • It adds a new builtin derivation builder named builtin:fetch-tree, which is similar to builtins.fetchTree but works at build time rather than eval time.

  • It allows flake inputs to be fetched at build time. Example:

    inputs.repo1 = {
      type = "github";
      owner = "DeterminateSystems";
      repo = "blabla";
      flake = false; # <-- currently required
      buildTime = true;
    };

    call-flake.nix maps this to a builtin:fetch-tree derivation. Thus you can pass it to other derivations, and it will be fetched at build time rather than eval time. (It will still be fetched at eval time to create/update locks.)

    Inputs like this can be passed to derivations as usual, e.g.

  outputs = { self, nixpkgs, repo1 }: {
    packages.x86_64-linux.default =
      with import nixpkgs { system = "x86_64-linux"; };
      stdenv.mkDerivation {
        ...
        src = repo1;
      };
  };

Note that trying to access them at evaluation time (e.g. import repo1) will trigger import-from-derivation behaviour, i.e. it will cause a build during evaluation.

Context


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions
Copy link

github-actions bot commented May 1, 2025

@github-actions github-actions bot temporarily deployed to pull request May 1, 2025 17:56 Inactive
@lucperkins

This comment was marked as resolved.

@edolstra edolstra force-pushed the build-time-fetch-tree branch from 88d5913 to d146d3b Compare May 9, 2025 14:35
@github-actions github-actions bot temporarily deployed to pull request May 9, 2025 14:46 Inactive
@edolstra edolstra force-pushed the build-time-fetch-tree branch from d146d3b to 36a25f9 Compare May 12, 2025 11:07
@github-actions github-actions bot temporarily deployed to pull request May 12, 2025 11:19 Inactive
edolstra added 9 commits May 13, 2025 10:31
This builtin builder is similar to `builtins.fetchTree` but works at build time.
This is needed for builtin:fetch-tree to get access to it.
This only works for non-flake inputs. Example:

  inputs.repo1 = {
    type = "github";
    owner = "DeterminateSystems";
    repo = "blabla";
    flake = false;
    buildTime = true;
  };

`call-flake.nix` maps this to a builtin:fetch-tree derivation. Thus
you can pass it to other derivations, and it will be fetched at build
time rather than eval time. (It will still be fetched at eval time to
create/update locks.) Importing from such an input triggers IFD.
@edolstra edolstra force-pushed the build-time-fetch-tree branch from 36a25f9 to febe4de Compare May 13, 2025 08:31
@github-actions github-actions bot temporarily deployed to pull request May 13, 2025 08:44 Inactive
@edolstra edolstra changed the title WIP: Build-time flake inputs Build-time flake inputs May 14, 2025
@github-actions github-actions bot temporarily deployed to pull request May 14, 2025 14:03 Inactive
@github-actions github-actions bot temporarily deployed to pull request May 14, 2025 15:32 Inactive
@github-actions github-actions bot temporarily deployed to pull request July 23, 2025 14:54 Inactive
@github-actions github-actions bot temporarily deployed to pull request August 18, 2025 16:53 Inactive
@github-actions github-actions bot temporarily deployed to pull request August 19, 2025 14:08 Inactive
@github-actions github-actions bot temporarily deployed to pull request August 19, 2025 14:50 Inactive
@github-actions github-actions bot temporarily deployed to pull request August 20, 2025 13:32 Inactive
In the builtin:fetch-tree sandbox, we don't have the `git` executable
available, so let's use libgit2 instead. This generally won't work
very well for SSH, but that currently doesn't work anyway because the
sandbox doesn't have access to SSH keys.
@edolstra edolstra force-pushed the build-time-fetch-tree branch from 3264b8e to 1201c72 Compare August 20, 2025 14:41
@github-actions github-actions bot temporarily deployed to pull request August 20, 2025 14:45 Inactive
Comment on lines +49 to +57
derivation {
name = "source";
builder = "builtin:fetch-tree";
system = "builtin";
__structuredAttrs = true;
input = node.locked;
outputHashMode = "recursive";
outputHash = node.locked.narHash;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My memory is that, because of the way derivations are added to the store by way of registerOutputs, they are scanned for references to the Nix store. Since the eval-time fetcher doesn't do that (and so the retrieved sources can contain paths to the Nix store), the build-time fetcher will reject some of the sources which the eval-time fetcher would accept (since fixed-output derivations are not allowed to contain references to the Nix store).

Is that correct or something to worry about?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nix only scans for references that are part of the input closure of a derivation. It doesn't scan for arbitrary references. For the build-time fetcher, the input closure is empty, so no sources will ever be rejected by the build-time fetcher. This also means Nix won't find references that are "hard-coded" (e.g. part of the tarball), but that's the same for other types of derivations (e.g. fetchurl in Nixpkgs).

Copy link
Member

@cole-h cole-h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from my 1 comment, this looks fine to me!

// FIXME: move FileTransfer into fetchers::Settings.
static auto prevFileTransfer = resetFileTransfer();

// FIXME: disable use of the git/tarball cache
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the implications of not doing this / is it small enough to fix this now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just that it's slower / uses more disk space than necessary, since it will first fetch into the tarball cache and then copy it to the store. But we can improve that later.

@edolstra edolstra added this pull request to the merge queue Aug 25, 2025
Merged via the queue into main with commit 5be74ef Aug 25, 2025
33 checks passed
@edolstra edolstra deleted the build-time-fetch-tree branch August 25, 2025 16:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants