cc422e321e
Before this, the tool for CI would update when nixos-unstable updated, which is kind of terrible because you don't know when it happens, and it might break master. In fact, the tooling _right now_ has a serious bug and shouldn't be used! This PR addresses this by _pinning_ the tooling in Nixpkgs itself. Updating the tooling now requires two PRs: - The first PR to update the tooling source - (wait for Hydra to build and publish it in nixos-unstable) - The second PR to update the pinned tooling In turn you know exactly when the changes are going to take effect. This change however has additional benefits: - It makes CI more reproducible, because it doesn't depend on the state of nixos-unstable anymore - Updates to the tooling can be tested with the workflow itself, because PRs that update the pinned tool will be tested on the updated version - CI gets a sizable speed boost, because there's no need to download and evaluate a channel anymore - It makes it more realistic to move the source of the tool into a separate repository - It removes the brittle branch-specific logic that was previously needed to ensure that release branches use their own version of the tooling. |
||
---|---|---|
.. | ||
scripts | ||
src | ||
tests | ||
.envrc | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
default.nix | ||
README.md | ||
shell.nix |
Nixpkgs pkgs/by-name checker
This directory implements a program to check the validity of the pkgs/by-name
Nixpkgs directory.
It is being used by this GitHub Actions workflow.
This is part of the implementation of RFC 140.
Interface
The interface of the tool is shown with --help
:
cargo run -- --help
The interface may be changed over time only if the CI workflow making use of it is adjusted to deal with the change appropriately.
Validity checks
These checks are performed by this tool:
File structure checks
pkgs/by-name
must only contain subdirectories of the form${shard}/${name}
, called package directories.- The
name
's of package directories must be unique when lowercased. name
is a string only consisting of the ASCII charactersa-z
,A-Z
,0-9
,-
or_
.shard
is the lowercased first two letters ofname
, expressed in Nix:shard = toLower (substring 0 2 name)
.- Each package directory must contain a
package.nix
file and may contain arbitrary other files.
Nix parser checks
- Each package directory must not refer to files outside itself using symlinks or Nix path expressions.
Nix evaluation checks
Evaluate Nixpkgs with system
set to x86_64-linux
and check that:
- For each package directory, the
pkgs.${name}
attribute must be defined ascallPackage pkgs/by-name/${shard}/${name}/package.nix args
for someargs
. - For each package directory,
pkgs.lib.isDerivation pkgs.${name}
must betrue
.
Ratchet checks
Furthermore, this tool implements certain ratchet checks.
This allows gradually phasing out deprecated patterns without breaking the base branch or having to migrate it all at once.
It works by not allowing new instances of the pattern to be introduced, but allowing already existing instances.
The existing instances are coming from <BASE_NIXPKGS>
, which is then checked against <NIXPKGS>
for new instances.
Ratchets should be removed eventually once the pattern is not used anymore.
The current ratchets are:
- New manual definitions of
pkgs.${name}
(e.g. inpkgs/top-level/all-packages.nix
) withargs = { }
(see nix evaluation checks) must not be introduced. - New top-level packages defined using
pkgs.callPackage
must be defined with a package directory.- Once a top-level package uses
pkgs/by-name
, it also can't be moved back out of it.
- Once a top-level package uses
Development
Enter the development environment in this directory either automatically with direnv
or with
nix-shell
Then use cargo
:
cargo build
cargo test
cargo fmt
cargo clippy
Tests
Tests are declared in ./tests
as subdirectories imitating Nixpkgs with these files:
-
default.nix
: Always containsimport ../mock-nixpkgs.nix { root = ./.; }
which makes
nix-instantiate <subdir> --eval -A <attr> --arg overlays <overlays>
work very similarly to the real Nixpkgs, just enough for the program to be able to test it.
-
pkgs/by-name
: Thepkgs/by-name
directory to check. -
all-packages.nix
(optional): Contains an overlay of the formself: super: { # ... }
allowing the simulation of package overrides to the real
pkgs/top-level/all-packages.nix
. The default is an empty overlay. -
base
(optional): Contains another subdirectory imitating Nixpkgs with potentially any of the above structures. This is used for ratchet checks. -
expected
(optional): A file containing the expected standard output. The default is expecting an empty standard output.
Hydra builds
This program will always be available pre-built for x86_64-linux
on the nixos-unstable
channel and nixos-XX.YY
channels.
This is ensured by including it in the tested
jobset description in nixos/release-combined.nix
.
This allows CI for PRs to development branches master
and release-XX.YY
to fetch the pre-built program from the corresponding channel and use that to check the PR. This has the following benefits:
- It allows CI to check all PRs, even if they would break the CI tooling.
- It makes the CI check very fast, since no Nix builds need to be done, even for mass rebuilds.
- It improves security, since we don't have to build potentially untrusted code from PRs. The tool only needs a very minimal Nix evaluation at runtime, which can work with readonly-mode and restrict-eval.
- It allows anybody to make updates to the tooling and for those updates to be automatically used by CI without needing a separate release mechanism.
The tradeoff is that there's a delay between updates to the tool and those updates being used by CI. This needs to be considered when updating the API.