Skip to content

Conversation

@water-sucks
Copy link
Collaborator

@water-sucks water-sucks commented Nov 22, 2025

Description

This adds a convenient scaffold for orchestrating NixOS tests in the nix/tests/ directory for testing various scenarios.

Any file created there with the suffix .test.nix is now added as a flake check. Each test MUST use pkgs.runNixOSTest to spin up VM(s) to perform various test cases, which will come in later pull requests.

This also moves all Nix-related files into a dedicated nix/ directory to avoid polluting the toplevel with various Nix files.

Summary by CodeRabbit

  • Documentation

    • Added legacy nix-build/flake-compat usage, testing guide, test naming/placement and reference update for package path.
  • Tests

    • Added test discovery/execution infrastructure, an example integration test, and a test module for wiring per-system checks.
  • Chores

    • Moved Nix configuration into a dedicated directory, migrated flake composition to flake-parts, simplified flake-compat handling, and made package build sources explicit.

✏️ Tip: You can customize this high-level summary in your review settings.

This leaves the required toplevel files alone, and moves all other Nix
files into a dedicated `nix/` directory.

This facilitates adding more Nix code, such as tests, to the directory
without polluting the toplevel with too many files, and also
consolidates all flake-compat usage.
@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

Walkthrough

Refactors flake composition to use flake-parts, moves many Nix files under ./nix/, introduces a test discovery/execution framework under nix/tests, and replaces inline flake-compat fetch logic with a new nix/flake-compat.nix import. Several import paths and package src handling were updated.

Changes

Cohort / File(s) Summary
Flake composition & path migrations
README.md, default.nix, shell.nix, flake.nix, nix/flake-compat.nix
README: docs for legacy nix-build/shell via flake-compat, Tests section, test naming/placement, and package.nix path updated to ./nix/package.nix. default.nix and shell.nix updated to import from ./nix/ (delegate shellNix to nix/flake-compat.nix). flake.nix refactored to use flake-parts.lib.mkFlake, adds inputs.flake-parts, moves nixosModules.nixos-cli wiring inside the flake outputs, and exposes perSystem packages/devShells. New nix/flake-compat.nix implements lock-file-based fetchTarball and exposes the imported flake-compat outputs.
Packaging changes
nix/package.nix
Removed top-level nix-gitignore attr; replaced buildGoModule src from nix-gitignore.gitignoreSource [] ./ to lib.fileset.toSource with an explicit fileset (root, go.mod, go.sum, Makefile, main.go, cmd, doc, internal).
Test discovery & examples
nix/tests/default.nix, nix/tests/example.nix, nix/tests/example.test.nix, nix/tests/flake-module.nix
Added nix/tests/default.nix with findTests (recursive discovery of *.test.nix) and mkTest helper to build test derivations. Added example.nix (NixOS test config) and example.test.nix (test runner using pkgs.testers.runNixOSTest). Added flake-module.nix which supplies perSystem checks importing ./. with {inherit pkgs self;} for integration into flake perSystem checks.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer workspace
  participant Flake as flake.nix (mkFlake)
  participant Parts as flake-parts
  participant Nixpkgs as inputs.nixpkgs
  participant Tests as nix/tests/default.nix

  rect rgba(0,128,128,0.06)
    Dev->>Flake: edit flake.nix (use flake-parts, add perSystem)
    Flake->>Parts: call lib.mkFlake(perSystem -> packages, devShells, imports)
    Parts->>Nixpkgs: resolve system-specific packages (via inputs)
  end

  rect rgba(128,0,128,0.06)
    Dev->>Tests: add tests/*.test.nix
    Tests->>Tests: findTests("./.") => map *.test.nix -> mkTest(test)
    Tests->>Parts: tests can be wired into perSystem checks via flake-module.nix
  end
Loading
sequenceDiagram
  participant shell.nix as shell.nix
  participant compat as nix/flake-compat.nix
  participant lock as flake.lock

  shell.nix->>compat: import ./nix/flake-compat.nix
  compat->>lock: read lock metadata (rev, narHash)
  compat->>GitHub: fetchTarball using lock metadata
  compat->>shell.nix: expose .shellNix from fetched flake-compat outputs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Areas to focus on:
    • flake.nix: verify flake-parts composition, perSystem structure, and new public outputs (nixosModules wiring).
    • nix/flake-compat.nix: ensure lock parsing and fetchTarball usage produce reproducible and secure hashes.
    • nix/tests/default.nix: check recursive discovery, name normalization, and mkTest invocation correctness.
    • nix/package.nix: confirm lib.fileset.toSource fileset includes all required source files and build inputs.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding integration tests infrastructure and reorganizing Nix files into a dedicated directory structure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
nix/flake-compat.nix (1)

1-11: flake-compat pinning via flake.lock looks good; optional readability tweak

This matches the usual flake.lock-driven flake-compat pattern and should work fine as-is. If you want to DRY the long attr paths a bit, you could factor out the locked node:

-import
-(
-  let
-    lock = builtins.fromJSON (builtins.readFile ../flake.lock);
-  in
-    fetchTarball {
-      url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
-      sha256 = lock.nodes.flake-compat.locked.narHash;
-    }
-)
-{src = ../.;}
+import
+(
+  let
+    lock = builtins.fromJSON (builtins.readFile ../flake.lock);
+    compat = lock.nodes.flake-compat.locked;
+  in
+    fetchTarball {
+      url = "https://github.com/edolstra/flake-compat/archive/${compat.rev}.tar.gz";
+      sha256 = compat.narHash;
+    }
+)
+{ src = ../.; }

Purely optional; current code is correct.

nix/tests/example.nix (1)

1-15: Example NixOS test is wired correctly to the flake module

The test shape ({ pkgs, self, }: pkgs.testers.runNixOSTest { ... }) matches the new mkTest contract, imports self.nixosModules.nixos-cli as expected, and exercises the nixos CLI in a VM, which is appropriate for an example test. You can later extend testScript with concrete output checks if you want stronger assertions.

nix/tests/default.nix (1)

1-32: Test discovery logic is solid; consider keeping values as paths

The findTests pipeline correctly:

  • walks ./. recursively,
  • filters *.test.nix,
  • normalizes names by dropping .test.nix and replacing / with -,
  • and mkTest’s { inherit pkgs self; } contract matches the new test files.

One small improvement: you don't need to stringify the file paths for the values. Keeping them as paths makes the intent clearer and avoids relying on import of a string path:

  entries =
    lib.genAttrs' (lib.filesystem.listFilesRecursive dir)
      (name: lib.nameValuePair (builtins.toString name) name);

The rest of the pipeline can stay the same, since only the attribute names depend on string operations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64f7329 and 304901e.

⛔ Files ignored due to path filters (1)
  • flake.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • README.md (2 hunks)
  • default.nix (1 hunks)
  • flake-compat.nix (0 hunks)
  • flake.nix (1 hunks)
  • nix/flake-compat.nix (1 hunks)
  • nix/package.nix (1 hunks)
  • nix/tests/default.nix (1 hunks)
  • nix/tests/example.nix (1 hunks)
  • nix/tests/example.test.nix (1 hunks)
  • nix/tests/flake-module.nix (1 hunks)
  • shell.nix (1 hunks)
💤 Files with no reviewable changes (1)
  • flake-compat.nix
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~64-~64: As an alternative to the over-used intensifier ‘quite’, consider replacing this phrase.
Context: ...on the filename. Since these tests are quite expensive to run, passing them is not an automati...

(EN_WEAK_ADJECTIVE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build/Test
🔇 Additional comments (7)
nix/package.nix (1)

14-25: fileset-based src looks correct; be aware of maintenance overhead

The lib.fileset.toSource setup cleanly restricts the Go build context to exactly what you need (go.mod, cmd/, internal/, docs, etc.), which is a nice replacement for nix-gitignore. The only caveat is that adding new top-level Go directories in future will require updating this list, so just something to keep in mind.

README.md (1)

110-112: Updated package.nix path is consistent with the new nix/ layout

Pointing the versioning docs at [package.nix](./nix/package.nix) matches the refactor that moved Nix files under ./nix/. This keeps the documentation aligned with the new file structure.

flake.nix (1)

12-71: flake-parts migration looks solid; just confirm nix-options-doc supports all systems

The move to flake-parts.lib.mkFlake with systems = lib.systems.flakeExposed;, per-system packages/devShells, and flake.nixosModules.nixos-cli wired via lib.modules.importApply all look consistent and idiomatic.

One thing worth double‑checking: devShells.default unconditionally does

nix-options-doc = inputs.nix-options-doc.packages.${system}.default;

for every system in lib.systems.flakeExposed. If nix-options-doc doesn’t publish a packages.${system}.default for some of those systems, nix develop (or flake evaluation) will fail there. If that’s a concern, you could either narrow systems or guard this with lib.optionalAttrs / similar.

nix/tests/example.test.nix (1)

1-16: Example NixOS test is well-structured and matches the described test harness

The test function signature, use of pkgs.testers.runNixOSTest, importing self.nixosModules.nixos-cli, and the simple machine1.succeed("nixos features") smoke check all line up nicely with the new test scaffolding described in the README and flake module. Looks like a good minimal example for further tests to copy.

nix/tests/flake-module.nix (1)

1-5: Test flake module wiring looks correct

perSystem.checks correctly delegates to ./. with { inherit pkgs self; }, which matches the new tests/default.nix interface and keeps the flake surface minimal.

default.nix (1)

2-14: Path refactor preserves default.nix behavior

Switching to ./nix/flake-compat.nix for flakeSelf and ./nix/module.nix for module keeps the default.nix interface intact while matching the new directory layout; the self/useFlakePkg wiring is unchanged.

shell.nix (1)

1-1: Delegating to nix/flake-compat.nix simplifies shell.nix

Pointing shell.nix directly at (import ./nix/flake-compat.nix).shellNix nicely centralizes flake-compat logic without changing the external entrypoint.

This uses a fileset to restrict the amount of rebuilds that one has
to perform.

For example, if a test is changed, we do not want to rebuild the
`nixos-cli` package, since that's wasteful. Using an explicit opt-in
fileset for src works here because there are only a few files/directories
required to compile the actual package, and they can be specified
manually without much trouble.
@water-sucks water-sucks force-pushed the refactor-nix-structure branch from 304901e to a72666e Compare November 22, 2025 06:33
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 304901e and a72666e.

📒 Files selected for processing (7)
  • README.md (2 hunks)
  • flake.nix (1 hunks)
  • nix/package.nix (1 hunks)
  • nix/tests/default.nix (1 hunks)
  • nix/tests/example.nix (1 hunks)
  • nix/tests/example.test.nix (1 hunks)
  • nix/tests/flake-module.nix (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • flake.nix
🚧 Files skipped from review as they are similar to previous changes (3)
  • nix/tests/example.test.nix
  • nix/tests/flake-module.nix
  • nix/tests/default.nix
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~64-~64: As an alternative to the over-used intensifier ‘quite’, consider replacing this phrase.
Context: ...on the filename. Since these tests are quite expensive to run, passing them is not an automati...

(EN_WEAK_ADJECTIVE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build/Test
🔇 Additional comments (4)
README.md (3)

44-45: LGTM! Helpful documentation for legacy workflows.

The addition of legacy nix-build and nix-shell documentation is valuable for users who haven't migrated to flakes yet.


47-67: Excellent test infrastructure documentation.

The Tests section provides clear, comprehensive guidance on:

  • Test location and naming conventions
  • How to run tests in both flake and non-flake contexts
  • Expectations around test coverage and CI requirements

The documentation correctly references pkgs.testers.runNixOSTest and uses nix-build consistently for the non-flake workflow, addressing the concerns from previous reviews.


111-111: Path update correctly reflects the new directory structure.

The updated reference to ./nix/package.nix aligns with the refactored file organization.

nix/tests/example.nix (1)

1-15: LGTM! Well-structured example test.

This example test provides a clear template for future tests:

  • Uses the correct pkgs.testers.runNixOSTest API
  • Demonstrates proper node configuration with module imports
  • Includes a basic sanity check that verifies the service enables and the CLI works

The minimal scope is appropriate for an example/scaffold test.

@water-sucks water-sucks merged commit d9d29cb into nix-community:main Nov 22, 2025
2 checks passed
@water-sucks water-sucks deleted the refactor-nix-structure branch November 22, 2025 06:43
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.

1 participant