From 7d33e9d5e9dc89415eab7688c02fb6957f8eeadf Mon Sep 17 00:00:00 2001
From: Erik Arvstedt
Date: Thu, 26 Jun 2025 23:22:50 +0200
Subject: [PATCH 1/2] tests: extract fn `instantiateTestsFromStr`
Fn `instantiateTests` now takes an array of strings.
It is used in the following commit.
---
test/run-tests.sh | 2 +-
test/tests.nix | 19 +++++++++----------
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/test/run-tests.sh b/test/run-tests.sh
index 09caffe..48abf8e 100755
--- a/test/run-tests.sh
+++ b/test/run-tests.sh
@@ -193,7 +193,7 @@ buildTests() {
# TODO-EXTERNAL:
# Simplify and switch to pure build when `nix build` can instantiate flake function outputs
# shellcheck disable=SC2207
- drvs=($(nixInstantiate "pkgs.instantiateTests \"${tests[*]}\""))
+ drvs=($(nixInstantiate "pkgs.instantiateTestsFromStr \"${tests[*]}\""))
for i in "${!tests[@]}"; do
testName=${tests[$i]}
drv=${drvs[$i]}
diff --git a/test/tests.nix b/test/tests.nix
index af6e30c..cee3b7b 100644
--- a/test/tests.nix
+++ b/test/tests.nix
@@ -459,16 +459,15 @@ in {
};
});
+ instantiateTestsFromStr = testNamesStr: instantiateTests (lib.splitString " " testNamesStr);
+
instantiateTests = testNames:
- let
- testNames' = lib.splitString " " testNames;
- in
- map (name:
- let
- test = tests.${name};
- in
- builtins.seq (builtins.trace "Evaluating test '${name}'" test.outPath)
- test
- ) testNames';
+ map (name:
+ let
+ test = tests.${name};
+ in
+ builtins.seq (builtins.trace "Evaluating test '${name}'" test.outPath)
+ test
+ ) testNames;
};
}
From 5516bcc43bd2c73a5035c81344447f6e8c801496 Mon Sep 17 00:00:00 2001
From: Erik Arvstedt
Date: Thu, 26 Jun 2025 23:22:51 +0200
Subject: [PATCH 2/2] ci: switch from Cirrus to Github Actions
---
.cirrus.yml | 42 ----------------------------
.github/workflows/test.yml | 46 +++++++++++++++++++++++++++++++
README.md | 5 ++--
flake.nix | 2 ++
helper/update-flake.sh | 1 -
test/ci/build-to-cachix.sh | 4 ++-
test/ci/build.sh | 6 ++--
test/ci/build_test_drivers.sh | 52 +++++++++++++++++++++++++++++++++++
test/ci/test-info.nix | 22 +++++++++++++++
9 files changed, 130 insertions(+), 50 deletions(-)
delete mode 100644 .cirrus.yml
create mode 100644 .github/workflows/test.yml
create mode 100755 test/ci/build_test_drivers.sh
create mode 100644 test/ci/test-info.nix
diff --git a/.cirrus.yml b/.cirrus.yml
deleted file mode 100644
index b1d2036..0000000
--- a/.cirrus.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-task:
- environment:
- CACHIX_SIGNING_KEY: ENCRYPTED[!cec502ed813cbcd0237697d2031f750186ff20eed5815b1ad950ad2f2d701702ae6ba2f0cb4cb1985687a696c8ee492c!]
- # Save some traffic by excluding the full git history
- CIRRUS_CLONE_DEPTH: 1
-
- # Use the maximum timeout. Needed when rebuilding packages on a channel update.
- timeout_in: 120m
-
- container:
- # Defined in https://github.com/nix-community/docker-nixpkgs
- image: nixpkgs/nix-flakes:nixos-25.05
-
- matrix:
- - name: modules_test
- container:
- # Besides virtualization, this also enables privileged containers which are required for
- # sandboxed builds
- kvm: true
- # Needed for package builds
- memory: 8G
- # A maximum of 16 CPUs is shared among all concurrent tasks.
- # https://cirrus-ci.org/faq/#are-there-any-limits
- cpu: 4
- environment:
- matrix:
- - scenario: default
- - scenario: netns
- - scenario: netnsRegtest
- # This script is run as root
- build_script:
- - printf '%s\n' 'sandbox = true' 'max-jobs = auto' >> /etc/nix/nix.conf
- - nix shell --inputs-from . nixpkgs#{bash,coreutils,cachix} -c ./test/ci/build.sh $scenario
-
- - name: flake
- build_script:
- - nix flake check --all-systems
- - ./test/nixos-search/ci-test.sh
-
- - name: shellcheck
- build_script:
- - ./test/shellcheck.sh
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..9b93f6c
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,46 @@
+name: nix-bitcoin tests
+
+on: [push, pull_request]
+
+env:
+ CACHIX_SIGNING_KEY: ${{ secrets.CACHIX_SIGNING_KEY }}
+
+# Strategy:
+# Job `build_test_drivers` evals all VM tests and builds all test drivers in a single Nix build.
+# Compared to launching a separate build job for each VM test, this avoids duplicated
+# builds of derivations that the test drivers have in common.
+#
+# The job matrix `test_scenario` runs the VM tests.
+# When job `build_test_drivers` determines that all tests have already been built successfully,
+# job `test_scenario` is skipped via output variable `run_scenario_tests`.
+jobs:
+ build_test_drivers:
+ runs-on: ubuntu-latest
+ outputs:
+ run_scenario_tests: ${{ steps.main.outputs.run_scenario_tests }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: cachix/install-nix-action@v31
+ - id: main
+ run: nix shell --inputs-from . nixpkgs#{bash,coreutils,cachix} -c ./test/ci/build_test_drivers.sh
+
+ test_scenario:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ scenario: [default, netns, netnsRegtest]
+ needs: build_test_drivers
+ if: needs.build_test_drivers.outputs.run_scenario_tests == 'true'
+ steps:
+ - uses: actions/checkout@v4
+ - uses: cachix/install-nix-action@v31
+ - run: nix shell --inputs-from . nixpkgs#{bash,coreutils,cachix} -c ./test/ci/build.sh ${{ matrix.scenario }}
+
+ check_flake:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: cachix/install-nix-action@v31
+ - run: nix flake check --all-systems
+ - run: ./test/nixos-search/ci-test.sh
+ - run: ./test/shellcheck.sh
diff --git a/README.md b/README.md
index 09f494d..dbac287 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,9 @@
-
-
+
+
diff --git a/flake.nix b/flake.nix
index fd7aec5..7077d50 100644
--- a/flake.nix
+++ b/flake.nix
@@ -111,6 +111,8 @@
(test.pkgs self pkgs) //
{
extra-container = self.inputs.extra-container.packages.${system}.default;
+
+ ciTestInfo = import ./test/ci/test-info.nix pkgs legacyPackages.instantiateTests;
};
apps = rec {
diff --git a/helper/update-flake.sh b/helper/update-flake.sh
index 5206e54..cc5f976 100755
--- a/helper/update-flake.sh
+++ b/helper/update-flake.sh
@@ -62,7 +62,6 @@ if [[ $nixosVersion ]]; then
setVersion 'system.stateVersion = "' ../examples/configuration.nix
setVersion 'nix-bitcoin.url = .*?/nixos-' ../examples/flakes/flake.nix
setVersion 'nix-bitcoin.url = .*?/nixos-' ../examples/container/flake.nix
- setVersion 'image: nixpkgs.*?nixos-' ../.cirrus.yml
setVersion 'update-flake.sh ' ../dev/README.md
nix flake update nixpkgs --flake ..
else
diff --git a/test/ci/build-to-cachix.sh b/test/ci/build-to-cachix.sh
index dcea712..5ad2142 100755
--- a/test/ci/build-to-cachix.sh
+++ b/test/ci/build-to-cachix.sh
@@ -28,7 +28,9 @@ fi
## Build
-if [[ -v CIRRUS_CI ]]; then
+if [[ -v GITHUB_ACTIONS ]]; then
+ # Avoid cachix warning message
+ mkdir -p ~/.config/nix && touch ~/.config/nix/nix.conf
cachix use "$cachixCache"
fi
diff --git a/test/ci/build.sh b/test/ci/build.sh
index 90d6b4f..87a1f19 100755
--- a/test/ci/build.sh
+++ b/test/ci/build.sh
@@ -3,19 +3,17 @@
# This script can also be run locally for testing:
# ./build.sh
#
-# When variable CIRRUS_CI is unset, this script leaves no persistent traces on the host system.
+# When variable GITHUB_ACTIONS is unset, this script leaves no persistent traces on the host system.
set -euo pipefail
scenario=$1
-if [[ -v CIRRUS_CI ]]; then
+if [[ -v GITHUB_ACTIONS ]]; then
if [[ ! -e /dev/kvm ]]; then
>&2 echo "No KVM available on VM host."
exit 1
fi
- # Enable KVM access for nixbld users
- chmod o+rw /dev/kvm
fi
cd "${BASH_SOURCE[0]%/*}"
diff --git a/test/ci/build_test_drivers.sh b/test/ci/build_test_drivers.sh
new file mode 100755
index 0000000..23f0cde
--- /dev/null
+++ b/test/ci/build_test_drivers.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+cd "${BASH_SOURCE[0]%/*}"
+
+cachixCache=nix-bitcoin
+
+# Declare variables for shellcheck
+driverDrvs=()
+drivers=()
+scenarioTests=()
+
+# Call ./test-info.nix
+testInfo=$(time nix eval --raw --show-trace ../..#ciTestInfo)
+# This sets variables `driverDrvs`, `drivers`, `scenarioTests`
+eval "$testInfo"
+
+if nix path-info --store "https://${cachixCache}.cachix.org" "${scenarioTests[@]}" &>/dev/null; then
+ echo
+ echo "All tests have already been built successfully:"
+ printf '%s\n' "${scenarioTests[@]}"
+ exit 0
+fi
+
+echo "run_scenario_tests=true" >> "$GITHUB_OUTPUT"
+
+## Build test drivers
+
+if nix path-info --store "https://${cachixCache}.cachix.org" "${drivers[@]}" &>/dev/null; then
+ echo
+ echo "All test drivers have already been built successfully:"
+ exit 0
+fi
+
+if [[ -v GITHUB_ACTIONS ]]; then
+ # Avoid cachix warning message
+ mkdir -p ~/.config/nix && touch ~/.config/nix/nix.conf
+ cachix use "$cachixCache"
+fi
+
+if [[ $CACHIX_SIGNING_KEY ]]; then
+ # Speed up task by uploading store paths as soon as they are created
+ buildCmd="cachix watch-exec $cachixCache nix -- build"
+else
+ buildCmd="nix build"
+fi
+
+$buildCmd --no-link --print-build-logs "${driverDrvs[@]}"
+
+if [[ $CACHIX_SIGNING_KEY ]]; then
+ cachix push "$cachixCache" "${drivers[@]}"
+fi
diff --git a/test/ci/test-info.nix b/test/ci/test-info.nix
new file mode 100644
index 0000000..3333804
--- /dev/null
+++ b/test/ci/test-info.nix
@@ -0,0 +1,22 @@
+pkgs: instantiateTests:
+
+let
+ # `instantiateTests` prints the test name before evaluating, which is useful for debugging
+ ciTests = instantiateTests [
+ "default"
+ "netns"
+ "netnsRegtest"
+ ];
+ drivers = map (x: x.driver) ciTests;
+ driverDrvs = map (x: ''"${x.drvPath}^*"'') drivers;
+in ''
+driverDrvs=(
+${builtins.concatStringsSep "\n" driverDrvs}
+)
+drivers=(
+${builtins.concatStringsSep "\n" drivers}
+)
+scenarioTests=(
+${builtins.concatStringsSep "\n" ciTests}
+)
+''