Skip to content

Add a Nix flake packaging lc and astra, with a NixOS module - #250

Open
charnock-fr wants to merge 1 commit into
LightconeResearch:mainfrom
charnock-fr:feat/nix-flake
Open

charnock-fr wants to merge 1 commit into
LightconeResearch:mainfrom
charnock-fr:feat/nix-flake

Conversation

@charnock-fr

Copy link
Copy Markdown

Would close #249 . On NixOS, lc run and lc materialize also need
#247; the flake builds and lc init works without it.

Whats in this commit

  • flake.nix
    • packages.default (also packages.lc): lc, astra and git-annex's four executables for x86_64-linux, aarch64-linux and aarch64-darwin. Each is a wrapper around uv tool run --from <wheel>, with lc's wheel built from the flake source. uv installs Python and lc's dependencies on first run, as uv tool install does, with --exclude-newer set to the commit's date so a commit's resolution does not drift as new releases appear. lc's dependency tree is not repackaged for Nix.
    • The package also provides uv and git, first on the wrappers' PATH, so lc, git add and uv add use the same uv and git.
      .override { uv = …; } changes uv.
    • nixosModules.default: programs.lightcone.enable installs the package and sets programs.git.package to the package's git. It also:
      • enables nix-ld, so the interpreters and wheels uv downloads can run;
      • sets python-preference = "only-managed" in /etc/uv/uv.toml, so uv never builds a project on a Nix Python. It is a config file because child_env() scrubs ambient UV_* settings. It is not an install setting, so it moves no env_version and raises no machine-config advisory;
      • fails evaluation if the package's uv is below 0.12, the required-version lightcone projects declare.
  • flake.lock: pins nixpkgs-unstable, which supplies uv, git and the wheel's build tools.
  • .github/workflows/nix.yml
    • builds the package on all three systems and runs lc init and lc init --check with it;
    • checks the flake evaluates on every system;
    • fails when lastRelease falls behind the latest tag, printing the valuu to set.
  • docs/user/install.md: Nix and NixOS tabs for install, upgrade and uninstall.

Versioning

Nix builds see no tags, so hatch-vcs cannot version them. The flake builds <next>.dev0+g<commit>.nix, with <next> derived from lastRelease the way hatch-vcs guesses it. The dev and +g<commit> parts keep _engine_requirement() pinning reruns to the exact commit; I'm using .nix to mark the dev count as unknown rather than believing the zero. After each release lastRelease needs to be set to the new tag. nix.yml fails until it is.

uv versions

Bumping the image's pinned uv (UV_IMAGE, as in #248) changes nothing in the flake, and updating flake.lock changes nothing in images. They are two different uvs, like for the requirement #248 describes for CI which applies to any user whose uv is newer than the images:

  • UV_IMAGE is copied into a containerized project's image, where it installs the interpreter and syncs the environment.
  • The flake's uv comes from nixpkgs through flake.lock (currently 0.12.17). It runs lc itself and, in direct mode, the project's uv lock and uv sync.

The two meet in one place. lc init pins .python-version to the interpreter lc runs on, which the flake's uv chose, and lc build then needs UV_IMAGE's uv to know that Python patch. That holds while the flake's uv is no newer than UV_IMAGE's i.e. 0.12.23 after #248, so a flake.lock update should not move uv past it.

Testing

On NixOS:

aarch64-darwin is evaluated only; the first macOS build would come from the CI job.

Known gaps

  • No Intel macOS build (x86_64-darwin).
  • lc's Python dependencies live in uv's cache, not the Nix store: the first run needs network access, and Nix garbage collection does not reclaim them.

packages.default builds lc's wheel from the flake source and wraps lc,
astra and git-annex's four executables in `uv tool run --from <wheel>`,
so uv installs Python and lc's dependencies at first run, as with uv
tool install. No uv.lock is tracked: dependencies resolve with
--exclude-newer set to the commit's date, so one commit resolves one
set of them. The package also provides uv and git and puts them first
on the wrappers' PATH, so lc, git add and uv add use the same uv and
git. packages.lc is an alias for `nix run ...#lc`.

nixosModules.default adds programs.lightcone.enable. It installs the
package, sets programs.git.package to the package's git, enables
nix-ld, and sets python-preference = "only-managed" in
/etc/uv/uv.toml. NixOS cannot run the interpreters and wheels uv
downloads without nix-ld, and a Nix Python on PATH would otherwise be
picked for project environments. Evaluation fails if the package's uv
is below 0.12; `.override { uv = ...; }` changes it.

hatch-vcs cannot see tags inside a Nix build, so the flake versions
itself <next>.dev0+g<commit>.nix, with <next> derived from lastRelease.
The dev and +g<commit> parts keep lc's rerun pin on the exact commit;
.nix marks the dev count as unknown rather than zero.

lastRelease must be set to the new tag after every release; nix.yml
fails until it is. nix.yml also builds the package on x86_64-linux,
aarch64-linux and aarch64-darwin and runs lc init in a new directory.

Checked on NixOS: nix flake check --all-systems passes, the module
evaluates with the default package and with a uv override, and the
getting-started guide runs end to end in nix shell, including the
fresh-clone check.

Signed-off-by: Tom Charnock <tom@charnock.fr>

This branch has not been deployed

No deployments
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.

Support installing lc with Nix and on NixOS

1 participant