From 75b6aad7a9cd6f3bb896c67a034502291fb8669d Mon Sep 17 00:00:00 2001
From: Dmitriy Kholkin <ataraxiadev@ataraxiadev.com>
Date: Thu, 15 Jun 2023 22:06:44 +0300
Subject: [PATCH] fix for CI

---
 .github/workflows/cache.yml |  4 ++--
 .github/workflows/iso.yml   |  2 +-
 ci.nix                      |  9 +++++----
 flake.nix                   | 24 +++++++++++++++--------
 profiles/nix/default.nix    |  2 ++
 scripts/force_cached.nix    | 39 +++++++++++++++++++++++++++++++++++++
 6 files changed, 65 insertions(+), 15 deletions(-)
 create mode 100644 scripts/force_cached.nix

diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml
index 378552f..c966ae1 100644
--- a/.github/workflows/cache.yml
+++ b/.github/workflows/cache.yml
@@ -29,5 +29,5 @@ jobs:
         nix run github:AtaraxiaSjel/attic#attic -- login dev https://cache.ataraxiadev.com/ ${{ secrets.ATTIC_TOKEN }}
     - name: Build system and push to cache
       run: |
-        nix shell -f . nix-build-uncached -c nix-build-uncached ci.nix
-        nix run github:AtaraxiaSjel/attic#attic -- attic push ataraxiadev ./result*
+        nix develop .#ci -c nix-build-uncached ci.nix
+        nix develop .#ci -c attic push ataraxiadev ./result*
diff --git a/.github/workflows/iso.yml b/.github/workflows/iso.yml
index b0c62ae..1b4c5b1 100644
--- a/.github/workflows/iso.yml
+++ b/.github/workflows/iso.yml
@@ -29,7 +29,7 @@ jobs:
     - name: Push ISO to artifacts
       uses: actions/upload-artifact@v3
       with:
-        name: nix-flakes.iso
+        name: nix-flakes.iso.zip
         path: result/iso/*.iso
         if-no-files-found: error
         retention-days: 30
\ No newline at end of file
diff --git a/ci.nix b/ci.nix
index 5990ade..4e64d59 100644
--- a/ci.nix
+++ b/ci.nix
@@ -1,6 +1,7 @@
 let
   outputs = builtins.getFlake (toString ./.);
-  pkgs = outputs.inputs.nixpkgs;
-  host-workstation = pkgs.lib.collect pkgs.lib.isDerivation outputs.packages.x86_64-linux.host-workstation;
-  host-hypervisor = pkgs.lib.collect pkgs.lib.isDerivation outputs.packages.x86_64-linux.host-hypervisor;
-in host-workstation ++ host-hypervisor
+  system = "x86_64-linux";
+  pkgs = import outputs.inputs.nixpkgs { inherit system; };
+  host-workstation = (pkgs.callPackage ./scripts/force_cached.nix {}) outputs.packages.x86_64-linux.host-workstation;
+  host-hypervisor = (pkgs.callPackage ./scripts/force_cached.nix {}) outputs.packages.x86_64-linux.host-hypervisor;
+in host-workstation // host-hypervisor
diff --git a/flake.nix b/flake.nix
index 99d4e29..a5dcfd1 100644
--- a/flake.nix
+++ b/flake.nix
@@ -159,8 +159,7 @@
     };
 
     outputsBuilder = channels: let
-      pkgs = channels.unstable;
-      pkgs-zfs = channels.unstable-zfs;
+      pkgs = channels.unstable-zfs;
       # FIXME: nixos-rebuild with --flake flag doesn't work with doas
       rebuild = pkgs.writeShellScriptBin "rebuild" ''
         if [[ -z $1 ]]; then
@@ -187,12 +186,21 @@
         nix flake lock --update-input hyprland
       '';
     in {
-      devShells.default = channels.unstable.mkShell {
-        name = "aliases";
-        packages = with pkgs; [
-          rebuild update-vscode upgrade upgrade-hyprland
-          nixfmt nixpkgs-fmt statix vulnix deadnix
-        ];
+      devShells = {
+        default = pkgs.mkShell {
+          name = "aliases";
+          packages = with pkgs; [
+            rebuild update-vscode upgrade upgrade-hyprland
+            nixfmt nixpkgs-fmt statix vulnix deadnix
+          ];
+        };
+        ci = pkgs.mkShell {
+          name = "ci";
+          packages = with pkgs; [
+            inputs.attic.packages.${pkgs.system}.attic
+            nix-build-uncached
+          ];
+        };
       };
       packages = {
         Flakes-ISO = nixos-generators.nixosGenerate {
diff --git a/profiles/nix/default.nix b/profiles/nix/default.nix
index 3e8bec9..f674c9b 100644
--- a/profiles/nix/default.nix
+++ b/profiles/nix/default.nix
@@ -29,6 +29,7 @@ with config.deviceSpecific; {
         "https://hyprland.cachix.org"
         "https://ataraxiadev-foss.cachix.org"
         "https://cache.ataraxiadev.com/ataraxiadev"
+        "https://numtide.cachix.org"
       ];
       trusted-public-keys = [
         "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
@@ -37,6 +38,7 @@ with config.deviceSpecific; {
         "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
         "ataraxiadev-foss.cachix.org-1:ws/jmPRUF5R8TkirnV1b525lP9F/uTBsz2KraV61058="
         "ataraxiadev:V/fCdvz1bMsQzYZcLltcAULST+MoChv53EfedmyJ8Uw="
+        "numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
       ];
       trusted-users = [ "root" config.mainuser "@wheel" ];
       use-xdg-base-directories = true;
diff --git a/scripts/force_cached.nix b/scripts/force_cached.nix
new file mode 100644
index 0000000..274592a
--- /dev/null
+++ b/scripts/force_cached.nix
@@ -0,0 +1,39 @@
+{ coreutils }:
+
+attrs:
+with builtins;
+let
+  # Copied from <nixpkgs/lib>
+  isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
+
+  # Return true if `nix-build` would traverse that attribute set to look for
+  # more derivations to build.
+  hasRecurseIntoAttrs = x: isAttrs x && (x.recurseForDerivations or false);
+
+  # Wraps derivations that disallow substitutes so that they can be cached.
+  toCachedDrv = drv:
+    if !(drv.allowSubstitutes or true) then
+      derivation
+        {
+          name = "${drv.name}-to-cached";
+          system = drv.system;
+          builder = "/bin/sh";
+          args = [ "-c" "${coreutils}/bin/ln -s ${drv} $out; exit 0" ];
+        }
+    else
+      drv;
+
+  op = _: val:
+    if isDerivation val then
+      toCachedDrv val
+    else if hasRecurseIntoAttrs val then
+      forceCached val
+    else
+      val
+  ;
+
+  # Traverses a tree of derivation and wrap all of those that disallow
+  # substitutes.
+  forceCached = attrs: mapAttrs op attrs;
+in
+forceCached attrs