diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bcd970c..ffaca1c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -131,6 +131,10 @@ jobs: runs-on: ubuntu-latest env: + NIXPKGS_CHANNEL: nixos-25.05 + NIX_EXTRA_CONFIG: | + keep-env-derivations = true + keep-outputs = true NIX_EXTRA_CONFIG_ACT: | sandbox = false filter-syscalls = false @@ -145,14 +149,33 @@ jobs: steps: - uses: actions/checkout@v5 + - name: Determine CI configuration + id: config + env: + CI_CONFIG: ci/configs/${{ matrix.config }}.bash + run: ci/scripts/config.sh + - name: Install Nix uses: cachix/install-nix-action@v31 # 2025-05-27, from https://github.com/cachix/install-nix-action/tags with: - nix_path: nixpkgs=channel:nixos-25.05 # latest release + nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/${{ steps.config.outputs.nixpkgs_rev }}.tar.gz # Act executes inside an unprivileged container (Docker or Podman), # so KVM support isn't available. enable_kvm: "${{ github.actor != 'nektos/act' }}" - extra_nix_config: ${{ github.actor == 'nektos/act' && env.NIX_EXTRA_CONFIG_ACT || '' }} + extra_nix_config: | + ${{ env.NIX_EXTRA_CONFIG }} + ${{ github.actor == 'nektos/act' && env.NIX_EXTRA_CONFIG_ACT || '' }} + + - name: Cache Nix store + if: steps.config.outputs.cache_nix_store == 'true' + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ matrix.config }}-${{ steps.config.outputs.nixpkgs_rev }}-${{ hashFiles('shell.nix', 'ci/patches/*.patch', format('ci/configs/{0}.bash', matrix.config)) }} + restore-prefixes-first-match: | + nix-${{ runner.os }}-${{ matrix.config }}-${{ steps.config.outputs.nixpkgs_rev }}- + nix-${{ runner.os }}-${{ matrix.config }}- + nix-${{ runner.os }}- + gc-max-store-size-linux: 10G - name: Run CI script env: diff --git a/ci/configs/gnu32.bash b/ci/configs/gnu32.bash index 961821c..04d78a2 100644 --- a/ci/configs/gnu32.bash +++ b/ci/configs/gnu32.bash @@ -1,5 +1,7 @@ CI_DESC="CI job cross-compiling to 32-bit" CI_DIR=build-gnu32 +# Cache the heaviest Nix job to stay within GitHub's cache budget. +CI_CACHE_NIX_STORE=true NIX_ARGS=( --arg minimal true --arg crossPkgs 'import { crossSystem = { config = "i686-unknown-linux-gnu"; }; }' diff --git a/ci/scripts/config.sh b/ci/scripts/config.sh new file mode 100755 index 0000000..f115ad5 --- /dev/null +++ b/ci/scripts/config.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# Source CI configuration and output variables needed by the workflow. + +set -o errexit -o nounset -o pipefail -o xtrace + +readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" + +source "${SCRIPT_DIR}/ci_helpers.sh" + +[ "${CI_CONFIG+x}" ] && source "$CI_CONFIG" + +# Resolve the nixpkgs channel to a specific revision for use in cache keys. +if [[ -n "${NIXPKGS_CHANNEL:-}" ]]; then + rev="$(curl --fail --location --silent --show-error "https://channels.nixos.org/${NIXPKGS_CHANNEL}/git-revision")" + test -n "${rev}" + write_output_var nixpkgs_rev "${rev}" +fi + +write_output_var cache_nix_store "${CI_CACHE_NIX_STORE:-false}" diff --git a/ci/scripts/run.sh b/ci/scripts/run.sh index 4b78083..04ac859 100755 --- a/ci/scripts/run.sh +++ b/ci/scripts/run.sh @@ -11,3 +11,14 @@ set -o errexit -o nounset -o pipefail -o xtrace [ "${CI_CONFIG+x}" ] && source "$CI_CONFIG" nix develop --ignore-environment --keep CI_CONFIG --keep CI_CLEAN "${NIX_ARGS[@]+"${NIX_ARGS[@]}"}" -f shell.nix --command ci/scripts/ci.sh + +# Create a GC root for the shell closure so the cache-nix-action save step +# does not garbage-collect it. +if [ -n "${CI_CACHE_NIX_STORE-}" ]; then + nix-build shell.nix \ + -o "$CI_DIR/gcroot" \ + "${NIX_ARGS[@]+"${NIX_ARGS[@]}"}" + # Verify the closure is complete so the cache-nix-action save step has + # everything it needs. + nix-store --query --requisites "$CI_DIR/gcroot" >/dev/null +fi