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 @@


- - CirrusCI status + + Github Actions status GitHub tag (latest SemVer) 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} +) +''