diff --git a/ci/flake-cron.nix b/ci/flake-cron.nix index b2d3d399..3f1b6c80 100644 --- a/ci/flake-cron.nix +++ b/ci/flake-cron.nix @@ -12,7 +12,10 @@ in { name = "flake-update"; gh-actions = { - env.CACHIX_SIGNING_KEY = "\${{ secrets.CACHIX_SIGNING_KEY }}"; + env = { + CACHIX_SIGNING_KEY = "\${{ secrets.CACHIX_SIGNING_KEY }}"; + DISCORD_WEBHOOK_LINK = "\${{ secrets.DISCORD_WEBHOOK_LINK }}"; + }; on = let paths = [ "default.nix" # sourceCache @@ -40,6 +43,7 @@ in { run = "nix run .#nf-update"; env = { CACHIX_SIGNING_KEY = "\${{ secrets.CACHIX_SIGNING_KEY }}"; + DISCORD_WEBHOOK_LINK = "\${{ secrets.DISCORD_WEBHOOK_LINK }}"; NF_UPDATE_GIT_COMMIT = "1"; NF_UPDATE_CACHIX_PUSH = "1"; NF_CONFIG_ROOT = "\${{ github.workspace }}"; diff --git a/ci/nodes.nix b/ci/nodes.nix index f938b4dc..91eeb729 100644 --- a/ci/nodes.nix +++ b/ci/nodes.nix @@ -11,18 +11,32 @@ with lib; { name = "nodes"; jobs = let - enabledSystems = filterAttrs (_: system: system.config.nixpkgs.system == "x86_64-linux") channels.nixfiles.nixosConfigurations; - mkSystemJob = name: system: nameValuePair "${name}" { - tasks.system = { - inputs = channels.nixfiles.nixosConfigurations.${name}.config.system.build.toplevel; - #warn = system.config.ci.allowFailure; + enabledNixOSSystems = filterAttrs (_: system: system.config.ci.enable) channels.nixfiles.systems; + mkNixOSSystemJob = name: system: nameValuePair "${name}" { + step.build-system-wrapper = { + name = "Build ${name} system closure"; + order = 500; + run = "nix run .#nf-build-system -- nixosConfigurations.${name}.config.system.build.topLevel ${name} NixOS"; + env = { + CACHIX_SIGNING_KEY = "\${{ secrets.CACHIX_SIGNING_KEY }}"; + DISCORD_WEBHOOK_LINK = "\${{ secrets.DISCORD_WEBHOOK_LINK }}"; + NF_UPDATE_GIT_COMMIT = "1"; + NF_UPDATE_CACHIX_PUSH = "1"; + NF_CONFIG_ROOT = "\${{ github.workspace }}"; + }; + }; + tasks = { + system = { + inputs = channels.nixfiles.nixosConfigurations.${name}.config.system.build.toplevel; + warn = system.config.ci.allowFailure; + }; }; }; - systemJobs = mapAttrs' mkSystemJob enabledSystems; + nixOSSystemJobs = mapAttrs' mkNixOSSystemJob enabledNixOSSystems; in { packages = { ... }: { imports = [ ./packages.nix ]; }; - } // systemJobs; + } // nixOSSystemJobs; }; } diff --git a/ci/secrets.yaml b/ci/secrets.yaml index f53bd4ab..85fb6217 100644 --- a/ci/secrets.yaml +++ b/ci/secrets.yaml @@ -1,3 +1,4 @@ +DISCORD_WEBHOOK_LINK: ENC[AES256_GCM,data:kXi3OD8JbBxC2efNKcoKqzkiMN2MSjkalXf+62On9H8bbAXwD6oel7U6VaNyqTdmmG/7l+zo/uDKt/fdtKnaihlnaJJNlSwBXgm686RwKnuRR+5JEom0vCijrUCuGuvZj6AGimJYC01B47/MmTafm3rZmVZGwOwfIg==,iv:XI+u68gWqzVQ6dv7GyCkWP5LnViCLUwIKevyEnozVis=,tag:LIIB+FEg5mMfRmJ7SLGGRQ==,type:str] CACHIX_AUTH_TOKEN: ENC[AES256_GCM,data:oezH26CAPPAXFvbtqlmEfa/X6XADQHCoObajgoaUKB8cdtI6mVnsZfmYNVgcyQzmyPhcKcqG7X1d0SYNuJW1dI2eByKvWSWUwY5N2f0994/Hd1NB3s7E3dq1EZtkZqDyFJMSchQT7xkJtEMqzdQnQhL3Au2zaP0+m6hhmkxqIet6H1Yu4n+hGBkunzF26l0VTPsPiek=,iv:ODlzphfJOsrPp0Vb/vABkES74a2wbesrRFQKGeCY2Qs=,tag:/wAItpFQmQ4KNT0ZNo1ehg==,type:str] sops: shamir_threshold: 1 @@ -69,8 +70,8 @@ sops: S1dxenc5M3ZhMTR3SEpqR3FxT20rdGMK4YtZe6NDBx5/LM6rbGuoXLrBEicOhDSx azOPjHWLN+B2JdgBpemI9NDOfBWL+t/VGx00w40PUq7FsCYdoBmHtQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-07-13T18:21:10Z" - mac: ENC[AES256_GCM,data:6vjYEY6WsfXGHxryL3ypqlmRGbsgEse0WohV9N4Oepl+NDsmhsXraeSJsfQNwDgXHc7Hk6n7ORTeogXeVABMpeYZyOJnbzzfm5recAaXtB8Jq2yDC69KvS4Xuk9WzqmacLieeaZ5K1vET4hD0q52cBJtvRzgmJ2SAfEyXIeucO0=,iv:mzMAOI+aTzuGfQ4qyMTIv2QYYbXcaKcx9Wlfv7aY0CY=,tag:kwwdh7Ic0UtYqYJ1y6VqPw==,type:str] + lastmodified: "2024-07-13T20:01:47Z" + mac: ENC[AES256_GCM,data:bXjy4R50FqQg7kXdFO7CoylAJYlGFFsgcIw6Wp63lD/MXChPyPrXdxaoDkZb8T3FmzfgWOjiiBn98tN5xSH3e/eOST3SAjlIp6vrI6oNw+I4NLoSJ6xOQcF3OLxErzuQLffK7Gn+EfjUmJjZpyuLced9jyRVPOYKoAweFeeRTuI=,iv:E9B2/HdSL7/56KU5A0HvGiJqDUGodfdN3YDpAlO0To4=,tag:Xr1XzjmCiePtdES6JliuCw==,type:str] pgp: - created_at: "2024-07-13T18:20:50Z" enc: |- diff --git a/common/home.nix b/common/home.nix index 5fa0d638..8da4c8c0 100644 --- a/common/home.nix +++ b/common/home.nix @@ -16,13 +16,11 @@ in { sharedModules = with tree; [ modules.home - home.profiles.common - #inputs.hyprlock.homeManagerModules.default - #inputs.hypridle.homeManagerModules.default ] ++ list.optional (tree.${systemType} ? home) tree.${systemType}.home; users.kat.imports = with tree.home.profiles; [ + common ]; extraSpecialArgs = { diff --git a/modules/system/ci.nix b/modules/system/ci.nix index 04b66261..0752436f 100644 --- a/modules/system/ci.nix +++ b/modules/system/ci.nix @@ -9,7 +9,7 @@ in { enable = mkEnableOption "build via CI" // { - default = config.type == "NixOS"; + default = config.type == "NixOS" && config.system == "x86_64-linux"; }; allowFailure = mkOption { type = bool; diff --git a/modules/system/deploy.nix b/modules/system/deploy.nix index 674aa072..153dc899 100644 --- a/modules/system/deploy.nix +++ b/modules/system/deploy.nix @@ -12,7 +12,7 @@ in { inherit (lib.options) mkOption; in { deploy = mkOption { - type = nullOr inputs.arcexprs.lib.json.types.attrs; + type = nullOr (import inputs.arcexprs {}).lib.json.types.attrs; }; }; config = { diff --git a/modules/system/host.nix b/modules/system/host.nix index 80320035..7cc073d7 100644 --- a/modules/system/host.nix +++ b/modules/system/host.nix @@ -1,10 +1,10 @@ { name, config, - meta, + tree, std, - Std, lib, + pkgs, inputs, ... }: let @@ -28,7 +28,7 @@ in { }; type = mkOption { description = "Operating system type of the host"; - type = enum ["NixOS" "MacOS" "Darwin" "Linux" "Windows"]; + type = enum ["NixOS" "MacOS" "Darwin" "Linux" "Windows" "Home"]; default = "NixOS"; }; folder = mkOption { @@ -64,6 +64,7 @@ in { macos = "darwin"; darwin = "darwin"; linux = "linux"; + home = "linux"; } .${string.toLower config.type}; in "${config.arch}-${kernel}"; @@ -74,13 +75,18 @@ in { darwin = "darwin"; linux = "linux"; windows = "windows"; + home = "home"; } .${string.toLower config.type}; - modules = mkIf (config.folder != "linux") [ + modules = with tree; mkIf (config.folder != "linux") [ # per-OS modules - meta.modules.${config.folder} + modules.${config.folder} # per-OS configuration - meta.${config.folder}.base + tree.${config.folder}.common + # per-OS user definition + home.user.${config.folder} + # true base module + common ]; builder = { @@ -97,7 +103,18 @@ in { } // args); in - sys; + args: let + nixos = sys args; + in + nixos.extendModules { + modules = + nixos.config.scalpels + ++ [ + inputs.scalpel.nixosModules.scalpel + ]; + specialArgs = {prev = nixos;}; + }; + home = args: inputs.home-manager.lib.homeManagerConfiguration (args // { inherit pkgs; }); darwin = inputs.darwin.lib.darwinSystem; macos = inputs.darwin.lib.darwinSystem; } @@ -109,10 +126,9 @@ in { }) config.builder); specialArgs = { - inherit name inputs std Std meta; - inherit (inputs.self.lib) gensokyo-zone; + inherit name inputs std tree; systemType = config.folder; system = config; }; }; -} +} \ No newline at end of file diff --git a/packages/nf-build-system/build-system.sh b/packages/nf-build-system/build-system.sh new file mode 100644 index 00000000..6da36a15 --- /dev/null +++ b/packages/nf-build-system/build-system.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +set -eu + +DISCORD_WEBHOOK_LINK=${DISCORD_WEBHOOK_LINK:-""} +SYSTEM_LINK=$1 +ALIAS=$2 +SYSTEM_TYPE=$3 + +# Helper functions +send_discord_message() { + local message="$1" + local escaped_message=$(printf '%s' "$message" | jq -R -s '.') + curl -s -H "Accept: application/json" -H "Content-Type: application/json" \ + -X POST --data "{\"content\": $escaped_message}" "$DISCORD_WEBHOOK_LINK" +} + +if [[ -n ${CACHIX_SIGNING_KEY-} ]]; then + export NF_UPDATE_CACHIX_PUSH=1 +fi + +cd "$NF_CONFIG_ROOT" + +if [[ -n ${NF_UPDATE_CACHIX_PUSH-} ]]; then + export NF_ACTIONS_TEST_OUTLINK=${NF_ACTIONS_TEST_OUTLINK-result} +fi + +if [[ ${GITHUB_ACTIONS-} = true && ${RUNNER_NAME-} = "Github Actions"* ]]; then + # low disk space available on public runners... + echo "enabled GC between builds due to restricted disk space..." >&2 + export NF_ACTIONS_TEST_GC=1 +fi + +NIX_BUILD_ARGS=( + --show-trace +) +NIX_BUILD_ARGS_ASYNC=() + +init_nfargs() { + nflinksuffix="-L" + shift + + nfargs=( + "${NIX_BUILD_ARGS[@]}" + ) + + if [[ -n "${NF_ACTIONS_TEST_OUTLINK-}" || -n "${NF_UPDATE_CACHIX_PUSH-}" ]]; then + nfargs+=( + -o "${NF_ACTIONS_TEST_OUTLINK-result}$nflinksuffix" + ) + else + nfargs+=( + --no-link + ) + fi +} + +nfgc() { + if [[ -n ${NF_ACTIONS_TEST_GC-} ]]; then + if [[ -n ${NF_UPDATE_CACHIX_PUSH-} ]]; then + send_discord_message "Cachix pushing ${SYSTEM_TYPE} system build for ${ALIAS}" + cachix push kittywitch "./${NF_ACTIONS_TEST_OUTLINK-result}$nflinksuffix"*/ + rm -f "./${NF_ACTIONS_TEST_OUTLINK-result}$nflinksuffix"* + fi + nix-collect-garbage -d + fi +} + +nfinstallable="${NF_CONFIG_ROOT}#${SYSTEM_LINK}" +init_nfargs "-$nfsystem" + +nfwarn= +if [[ " ${NF_NIX_SYSTEMS_WARN[*]} " = *" $nfsystem "* ]]; then + nfwarn=1 +fi + +if [[ -n ${NF_ACTIONS_TEST_ASYNC-} && -z $nfwarn ]]; then + NIX_BUILD_ARGS_ASYNC+=("$nfinstallable") + continue +fi + +echo "building ${nfsystem}..." >&2 +echo >&2 + +nfbuildexit=0 +nix build "$nfinstallable" \ + "${nfargs[@]}" \ + "$@" || nfbuildexit=$? + +if [[ $nfbuildexit -ne 0 ]]; then + if [[ -n $nfwarn ]]; then + send_discord_message "build failure allowed for ${nfsystem}, ignoring..." + echo "build failure allowed for ${nfsystem}, ignoring..." >&2 + continue + fi + send_discord_message "build failure for ${nfsystem}, problem!" + exit $nfbuildexit +fi + +send_discord_message "${SYSTEM_TYPE} system build of ${ALIAS} succeeded!" + +nfgc + +if [[ -n ${NF_ACTIONS_TEST_ASYNC-} ]]; then + init_nfargs "" + nix build \ + "${nfargs[@]}" \ + "${NIX_BUILD_ARGS_ASYNC[@]}" \ + "$@" + + nfgc +fi \ No newline at end of file diff --git a/packages/nf-build-system/default.nix b/packages/nf-build-system/default.nix new file mode 100644 index 00000000..bdf097fc --- /dev/null +++ b/packages/nf-build-system/default.nix @@ -0,0 +1,12 @@ +{ + wrapShellScriptBin, + pkgs, +}: +wrapShellScriptBin "nf-build-system" ./build-system.sh { + depsRuntimePath = with pkgs; [ + git + cachix + jq + curl + ]; +} diff --git a/packages/nf-update/default.nix b/packages/nf-update/default.nix index d56a4f37..e3988259 100644 --- a/packages/nf-update/default.nix +++ b/packages/nf-update/default.nix @@ -6,5 +6,7 @@ wrapShellScriptBin "nf-update" ./update.sh { depsRuntimePath = with pkgs; [ git cachix + jq + curl ]; } diff --git a/packages/nf-update/update.sh b/packages/nf-update/update.sh index f72be3a2..11743623 100644 --- a/packages/nf-update/update.sh +++ b/packages/nf-update/update.sh @@ -1,12 +1,24 @@ #!/usr/bin/env bash set -eu +DISCORD_WEBHOOK_LINK=${DISCORD_WEBHOOK_LINK:-""} + +# Helper functions +send_discord_message() { + local message="$1" + local escaped_message=$(printf '%s' "$message" | jq -R -s '.') + curl -s -H "Accept: application/json" -H "Content-Type: application/json" \ + -X POST --data "{\"content\": $escaped_message}" "$DISCORD_WEBHOOK_LINK" +} + if [[ -n ${CACHIX_SIGNING_KEY-} ]]; then export NF_UPDATE_CACHIX_PUSH=1 fi cd "$NF_CONFIG_ROOT" +send_discord_message "Beginning flake update cron job" + nix flake update "$@" if [[ -n $(git status --porcelain ./flake.lock) ]]; then @@ -23,6 +35,7 @@ fi nf-actions-test -L if [[ -n ${NF_UPDATE_CACHIX_PUSH-} ]]; then + send_discord_message "Cachix pushing" cachix push kittywitch "./${NF_ACTIONS_TEST_OUTLINK}"*/ & CACHIX_PUSH=$! fi @@ -44,6 +57,7 @@ git commit --message="chore(ci): flake update" if [[ ${GITHUB_REF-} = refs/heads/${NF_UPDATE_BRANCH-main} ]]; then git push origin HEAD:${NF_UPDATE_BRANCH-main} + send_discord_message "Pushed a new commit!" fi wait ${CACHIX_PUSH-} diff --git a/systems/fullhome.nix b/systems/fullhome.nix new file mode 100644 index 00000000..1b9ddd5b --- /dev/null +++ b/systems/fullhome.nix @@ -0,0 +1,29 @@ +_: let + hostConfig = { + lib, + tree, + modulesPath, + ... + }: let + inherit (lib.modules) mkDefault; + in { + imports = + with tree.home.profiles; [ + common + ]; + home-manager.users.kat = { + imports = with tree.home.profiles; [ + devops + graphical + neovim + shell + ]; + }; + }; +in { + arch = "x86_64"; + type = "Home"; + modules = [ + hostConfig + ]; +}