From 4eb27543e5e088a1dc6d3f64b5d2200bb738b525 Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 28 Oct 2026 17:55:25 +0100 Subject: [PATCH] move vm tests out of checks into a nightly vmTests workflow --- .forgejo/workflows/vm-nightly.yml | 49 +++++++++++++++++++++++++++++++ docs/scheduler/ci.md | 13 +++++++- flake.nix | 6 ++++ nix/checks.nix | 2 -- nix/vm-tests.nix | 7 +++++ nix/vm-tests/hive-squid.nix | 2 +- 6 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 .forgejo/workflows/vm-nightly.yml create mode 100644 nix/vm-tests.nix diff --git a/.forgejo/workflows/vm-nightly.yml b/.forgejo/workflows/vm-nightly.yml new file mode 100644 index 00000000..ec8f4746 --- /dev/null +++ b/.forgejo/workflows/vm-nightly.yml @@ -0,0 +1,49 @@ +name: vm-nightly + +# Builds the `vmTests` flake output: tests that boot NixOS VMs and need KVM. +# They are not `checks`, so the per-PR `nix flake check` job never runs them. +# Nightly plus manual dispatch; a failing test fails the run, which the forge +# shows as a failed scheduled run. +# +# Run one by hand from the forge UI (Actions, vm-nightly, "Run workflow", +# `test` input) or locally with `nix build .#vmTests.x86_64-linux.`. +# +# ⚠️ The hour is deliberate: at the default job capacity of 1 +# (`services.hyperhive.deploy.ci-runner.concurrency`) this job holds the +# runner for its whole run and everything else queues behind it. It sits +# between coverage (02:00) and flake-update (03:00). +# +# Separate from ci.yml because a `workflow_dispatch` trigger there fires every +# job in that file, and this must not run per pull request. +on: + workflow_dispatch: + inputs: + test: + description: "vmTests attribute to build (empty builds all)" + required: false + default: "" + schedule: + - cron: "30 2 * * *" + +jobs: + vm-tests: + name: nix build vmTests + if: vars.PUBLIC_FORGE != 'true' + runs-on: ${{ vars.PUBLIC_FORGE == 'true' && 'nixos' || 'hive-ci' }} + steps: + - uses: actions/checkout@v3 + - name: build + env: + TEST: ${{ inputs.test }} + run: | + set -eu + system=x86_64-linux + tests="$TEST" + if [ -z "$tests" ]; then + tests="$(nix eval --raw ".#vmTests.$system" --apply 'ts: builtins.concatStringsSep " " (builtins.attrNames ts)')" + fi + set -- + for t in $tests; do + set -- "$@" ".#vmTests.$system.$t" + done + nix build --no-link --keep-going --print-build-logs "$@" diff --git a/docs/scheduler/ci.md b/docs/scheduler/ci.md index 9ac02299..62a82ddf 100644 --- a/docs/scheduler/ci.md +++ b/docs/scheduler/ci.md @@ -54,7 +54,7 @@ table can assert ahead of it happening. | Job | What it runs | Required? | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| **nix flake check** | `scripts/ci-flake-check.sh`: nix-eval-jobs, then builds each check (treefmt, clippy, tests, module eval) | yes | +| **nix flake check** | `scripts/ci-flake-check.sh`: nix-eval-jobs, then builds each check (treefmt, clippy, tests, module eval); no VM tests | yes | | **tracker-tag lint** | flags `#NNN` issue tags in source and comments (`scripts/check-issue-refs.sh`) | yes | | **comment-block lint** | flags contiguous comment blocks over 30 lines (`scripts/check-comment-blocks.sh`) | yes | | **doc-pointer lint** | flags `docs/…md` paths and relative markdown links that no longer resolve (`scripts/check-doc-refs.sh`) | yes | @@ -110,6 +110,17 @@ diagnostic if either fails — catching the issue locally before CI sees it. Note that the hook does **not** run `cargo clippy` or `cargo test` (those are slow); run those manually before pushing Rust changes. +### VM tests + +Tests that boot NixOS VMs are the `vmTests..` flake output +(`nix/vm-tests.nix`), not `checks`, so the per-PR **nix flake check** job never +builds them. [`.forgejo/workflows/vm-nightly.yml`](../../.forgejo/workflows/vm-nightly.yml) +builds all of them nightly at 02:30; a failing test fails that run. To run one +by hand, start the workflow from the forge UI (Actions, vm-nightly, Run +workflow, optional `test` input), or run +`nix build .#vmTests.x86_64-linux.` on a host with KVM. Current tests: +`hive-squid`. + ## Configuration reference `services.hyperhive.deploy.ci-runner.enable = true` on the host that runs it diff --git a/flake.nix b/flake.nix index c55cdb7b..d619917a 100644 --- a/flake.nix +++ b/flake.nix @@ -18,6 +18,7 @@ # nix/rust.nix shared crane wiring (cleanSrc, cargoArtifacts) # nix/packages/ every package output # nix/checks.nix flake checks + # nix/vm-tests.nix VM tests, the `vmTests` output # nix/devshell.nix dev shell # nix/treefmt.nix formatter config # nix/host-modules/, nix/agent-modules/, nix/container-modules/, @@ -224,6 +225,11 @@ formatter = forAllSystems ({ treefmt-eval, ... }: treefmt-eval.config.build.wrapper); + # Tests that boot a NixOS VM and need KVM. Not `checks`, so `nix flake + # check` and the per-PR CI job never build them; + # `.forgejo/workflows/vm-nightly.yml` does. + vmTests = forAllSystems ({ pkgs, ... }: import ./nix/vm-tests.nix { inherit pkgs; }); + checks = forAllSystems ( { pkgs, diff --git a/nix/checks.nix b/nix/checks.nix index 6ff29e1d..88c2907d 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -144,8 +144,6 @@ in inherit (pkgs) lib; shared = moduleEvalShared; }; - # Runs the squid module in a VM; needs KVM, unlike every check above. - vm-hive-squid = import ./vm-tests/hive-squid.nix { inherit pkgs; }; module-eval-hive-otel = import ./module-eval/hive-otel.nix { inherit pkgs self nixosSystem; inherit (pkgs) lib; diff --git a/nix/vm-tests.nix b/nix/vm-tests.nix new file mode 100644 index 00000000..c1e97acb --- /dev/null +++ b/nix/vm-tests.nix @@ -0,0 +1,7 @@ +# NixOS VM tests: one derivation per test, exposed as `vmTests..`. +# Kept out of `checks` because each boots VMs and needs KVM; the nightly +# workflow `.forgejo/workflows/vm-nightly.yml` builds them. +{ pkgs }: +{ + hive-squid = import ./vm-tests/hive-squid.nix { inherit pkgs; }; +} diff --git a/nix/vm-tests/hive-squid.nix b/nix/vm-tests/hive-squid.nix index 7824985f..0d624c86 100644 --- a/nix/vm-tests/hive-squid.nix +++ b/nix/vm-tests/hive-squid.nix @@ -1,4 +1,4 @@ -# `checks.vm-hive-squid`: runs ../host-modules/hive-squid.nix in a VM, which +# `vmTests..hive-squid`: runs ../host-modules/hive-squid.nix in a VM, which # the module-eval suite can only read, and checks that an agent with the proxy # variables of nix/agent-modules/egress-proxy.nix reaches squid and skips it # where it should. Three nodes on two networks: