From 681ac9fcb2bd4310cd6ad083866593bad0360558 Mon Sep 17 00:00:00 2001 From: jetcookies <226018678+jetcookies@users.noreply.github.com> Date: Wed, 11 Feb 2026 11:10:57 +0800 Subject: [PATCH] ci: let nix build and populate cache The cachix-related variables need to be modified to their actual values. --- .github/workflows/nix-binary-cache.yml | 62 ++++++++++++++++++++++++++ ci.nix | 56 +++++++++++++++++++++++ default.nix | 13 ++++++ flake.nix | 13 +++++- 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/nix-binary-cache.yml create mode 100644 ci.nix create mode 100644 default.nix diff --git a/.github/workflows/nix-binary-cache.yml b/.github/workflows/nix-binary-cache.yml new file mode 100644 index 0000000..ce0b5e0 --- /dev/null +++ b/.github/workflows/nix-binary-cache.yml @@ -0,0 +1,62 @@ +name: "Build and populate cache" +on: + push: + branches: + - main + paths: + - package.nix + schedule: + - cron: '45 3 * * *' + workflow_dispatch: +jobs: + tests: + strategy: + matrix: + # Set this to cache your build results in cachix for faster builds + # in CI and for everyone who uses your cache. + # + # Format: Your cachix cache host name without the ".cachix.org" suffix. + # Example: mycache (for mycache.cachix.org) + # + # For this to work, you also need to set the CACHIX_SIGNING_KEY or + # CACHIX_AUTH_TOKEN secret in your repository secrets settings in + # Github found at + # https://github.com//nur-packages/settings/secrets + cachixName: + - + nixPath: + - nixpkgs=https://github.com/NixOS/nixpkgs/archive/refs/heads/nixpkgs-unstable.tar.gz + - nixpkgs=https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-unstable.tar.gz + - nixpkgs=https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-25.11.tar.gz + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + - name: Install nix + uses: cachix/install-nix-action@v31 + with: + nix_path: "${{ matrix.nixPath }}" + extra_nix_config: | + experimental-features = nix-command flakes + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Show nixpkgs version + run: nix-instantiate --eval -E '(import {}).lib.version' + - name: Setup cachix + uses: cachix/cachix-action@v16 + # Don't replace here! + if: ${{ matrix.cachixName != '' }} + with: + name: ${{ matrix.cachixName }} + signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Check evaluation + run: | + nix-env -f . -qa \* --meta --xml \ + --allowed-uris https://static.rust-lang.org \ + --option restrict-eval true \ + --option allow-import-from-derivation true \ + --drv-path --show-trace \ + -I nixpkgs=$(nix-instantiate --find-file nixpkgs) \ + -I $PWD + - name: Build nix packages + run: nix shell -f '' nix-build-uncached -c nix-build-uncached ci.nix -A cacheOutputs diff --git a/ci.nix b/ci.nix new file mode 100644 index 0000000..f84dd96 --- /dev/null +++ b/ci.nix @@ -0,0 +1,56 @@ +# This file provides all the buildable and cacheable packages and +# package outputs in your package set. These are what gets built by CI, +# so if you correctly mark packages as +# +# - broken (using `meta.broken`), +# - unfree (using `meta.license.free`), and +# - locally built (using `preferLocalBuild`) +# +# then your CI will be able to build and cache only those packages for +# which this is possible. + +{ pkgs ? import { } }: + +with builtins; +let + isReserved = n: n == "lib" || n == "overlays" || n == "modules"; + isDerivation = p: isAttrs p && p ? type && p.type == "derivation"; + isBuildable = p: let + licenseFromMeta = p.meta.license or []; + licenseList = if builtins.isList licenseFromMeta then licenseFromMeta else [licenseFromMeta]; + in !(p.meta.broken or false) && builtins.all (license: license.free or true) licenseList; + isCacheable = p: !(p.preferLocalBuild or false); + shouldRecurseForDerivations = p: isAttrs p && p.recurseForDerivations or false; + + nameValuePair = n: v: { name = n; value = v; }; + + concatMap = builtins.concatMap or (f: xs: concatLists (map f xs)); + + flattenPkgs = s: + let + f = p: + if shouldRecurseForDerivations p then flattenPkgs p + else if isDerivation p then [ p ] + else [ ]; + in + concatMap f (attrValues s); + + outputsOf = p: map (o: p.${o}) p.outputs; + + nurAttrs = import ./default.nix { inherit pkgs; }; + + nurPkgs = + flattenPkgs + (listToAttrs + (map (n: nameValuePair n nurAttrs.${n}) + (filter (n: !isReserved n) + (attrNames nurAttrs)))); + +in +rec { + buildPkgs = filter isBuildable nurPkgs; + cachePkgs = filter isCacheable buildPkgs; + + buildOutputs = concatMap outputsOf buildPkgs; + cacheOutputs = concatMap outputsOf cachePkgs; +} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..41736ae --- /dev/null +++ b/default.nix @@ -0,0 +1,13 @@ +# This file describes your repository contents. +# It should return a set of nix derivations. +# It should NOT import . Instead, you should take pkgs as an argument. +# Having pkgs default to is fine though, and it lets you use short +# commands such as: +# nix-build -A mypackage + +{ pkgs ? import { } }: + +rec { + picoforge = pkgs.callPackage ./package.nix { }; + default = picoforge; +} diff --git a/flake.nix b/flake.nix index b1f6a9b..ecb72c8 100644 --- a/flake.nix +++ b/flake.nix @@ -6,12 +6,21 @@ flake-parts.url = "github:hercules-ci/flake-parts"; }; - outputs = inputs@{ flake-parts, fenix, ... }: + outputs = inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" "x86_64-darwin" ]; perSystem = { config, self', inputs', pkgs, system, ... }: { - packages.default = pkgs.callPackage ./package.nix { }; + packages = import ./default.nix { inherit pkgs; }; devShells.default = import ./shell.nix { inherit pkgs; }; }; }; + + nixConfig = { + extra-substituters = [ + "https://.cachix.org" + ]; + extra-trusted-public-keys = [ + "" + ]; + }; }