diff --git a/.github/workflows/nix-binary-cache.yml b/.github/workflows/nix-binary-cache.yml new file mode 100644 index 0000000..483118e --- /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: + - librekeys + 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/README.md b/README.md index 9226484..97c0bdf 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,9 @@ Or simply build it and link to the current directory: nix build github:librekeys/picoforge ``` +> [!TIP] +> You can use our binary cache to save build time by allowing Nix to set extra-substitutes. + #### b. without Flakes Download the package definition: 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/docs/Building.md b/docs/Building.md index 8e96a6b..95d871f 100644 --- a/docs/Building.md +++ b/docs/Building.md @@ -94,6 +94,9 @@ Or simply build it and link to the current directory: nix build github:librekeys/picoforge ``` +> [!TIP] +> You can use our binary cache to save build time by allowing Nix to set extra-substitutes. + #### b. without Flakes Download the package definition: diff --git a/flake.lock b/flake.lock index a457d30..98cd8d9 100644 --- a/flake.lock +++ b/flake.lock @@ -1,23 +1,5 @@ { "nodes": { - "fenix": { - "inputs": { - "nixpkgs": "nixpkgs", - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1770188896, - "narHash": "sha256-ZBpEh6aTvdoZvIM8sojnr43FPyegq/sjUkNWtF4kDO8=", - "owner": "nix-community", - "repo": "fenix", - "rev": "6dbe5750c68a55e7cb3f8b62883c4dbfeecf14d5", - "type": "github" - }, - "original": { - "id": "fenix", - "type": "indirect" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -38,15 +20,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1770115704, - "narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=", - "owner": "nixos", + "lastModified": 1770562336, + "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "e6eae2ee2110f3d31110d5c222cd395303343b08", + "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", "type": "github" }, "original": { - "owner": "nixos", + "owner": "NixOS", "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" @@ -67,44 +49,10 @@ "type": "github" } }, - "nixpkgs_2": { - "locked": { - "lastModified": 1770115704, - "narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "e6eae2ee2110f3d31110d5c222cd395303343b08", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "root": { "inputs": { - "fenix": "fenix", "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs_2" - } - }, - "rust-analyzer-src": { - "flake": false, - "locked": { - "lastModified": 1770092556, - "narHash": "sha256-DcUKN1nzz7LhyZGJMhSBhY5zrl8/GjJJ9SNqqTd77OQ=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "a84d92ff213e30fb00d7b812e07c4f67e99dcd29", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index b1f6a9b..5e2841d 100644 --- a/flake.nix +++ b/flake.nix @@ -6,12 +6,34 @@ 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 { }; - devShells.default = import ./shell.nix { inherit pkgs; }; - }; + systems = [ + "x86_64-linux" + "x86_64-darwin" + ]; + perSystem = + { + config, + self', + inputs', + pkgs, + system, + ... + }: + { + packages = import ./default.nix { inherit pkgs; }; + devShells.default = import ./shell.nix { inherit pkgs; }; + }; }; + + nixConfig = { + extra-substituters = [ + "https://librekeys.cachix.org" + ]; + extra-trusted-public-keys = [ + "librekeys.cachix.org-1:q+NyQsZgHyIMhYCIxyfpGs5jMU0/WHK7JTYgVbN3Iuk=" + ]; + }; }