{ outputs = { flake-parts, systems, ... } @ inputs: flake-parts.lib.mkFlake {inherit inputs;} { imports = [ inputs.devenv.flakeModule inputs.treefmt-nix.flakeModule ./lib/flakeModule.nix ]; systems = import systems; flake = {}; perSystem = { pkgs, inputs', config, system, ... }: rec { treefmt = { projectRootFile = "flake.nix"; programs = { alejandra.enable = true; mdformat.enable = true; yamlfmt.enable = true; }; }; devenv.shells.default = { containers = pkgs.lib.mkForce {}; packages = with pkgs; [dive skopeo]; pre-commit = { hooks = { treefmt = { enable = true; packageOverrides.treefmt = config.treefmt.build.wrapper; }; }; }; }; # should set the "default" pipeline ci = { stages = ["test"]; jobs = { "test" = { stage = "test"; nix = { deps = [pkgs.hello pkgs.curl]; enable-runner-cache = true; }; variables = { TEST = "test"; TEST_WITH_DERIVATION = "${pkgs.hello}/test"; }; script = [ "hello" "curl google.de" "echo $TEST $TEST_WITH_DERIVATION" ]; }; "test-default" = { stage = "test"; nix.deps = [pkgs.hello]; script = ["hello"]; }; "test-non-nix" = { nix.enable = false; stage = "test"; image = "alpine:latest"; script = [ "echo \"This job will not be modified to use nix\"" ]; }; }; }; pipelines."non-default" = { stages = ["test"]; jobs = { "test" = { stage = "test"; script = [ "echo Hello from another pipeline" ]; }; }; }; packages = let setupScript = pkgs.writeShellScriptBin "setup_nix_ci" '' echo -e "\\e[0Ksection_start:`date +%s`:nix_setup\\r\\e[0KSetting up Nix CI" nix path-info --all > /tmp/nix-store-before if [ -z "$_NIX_CI_DISABLE_CACHE" ]; then echo -e "\\e[0Ksection_start:`date +%s`:cache_setup[collapsed=true]\\r\\e[0KConfiguring cache ($_NIX_CI_CACHE_STRATEGY)" case "$_NIX_CI_CACHE_STRATEGY" in "runner") export RUNNER_CACHE=''${RUNNER_CACHE:-"file://$(pwd)/.nix-cache"} echo "Runner Cache: $RUNNER_CACHE" export NIX_CONFIG="$NIX_CONFIG extra-trusted-substituters = $RUNNER_CACHE?priority=10&trusted=true extra-substituters = $RUNNER_CACHE?priority=10&trusted=true " ;; "attic") echo "Attic Cache: $ATTIC_CACHE" attic login --set-default ci "$ATTIC_SERVER" "$ATTIC_TOKEN" || true attic use "$ATTIC_CACHE" || true ;; "cachix") echo "Cachix Cache: $CACHIX_CACHE" cachix use "$CACHIX_CACHE" || true ;; "none") echo "Cache strategy is none, doing nothing..." ;; *) echo "WARNING: Invalid cache strategy set: '$_NIX_CI_CACHE_STRATEGY'" ;; esac echo -e "\\e[0Ksection_end:`date +%s`:cache_setup\\r\\e[0K" else echo "Caching disabled (NIX_CI_DISABLE_CACHE), skipping cache configuration..." fi # load the job's deps only if the name was passed if [[ ! -z $1 ]]; then echo -e "\\e[0Ksection_start:`date +%s`:nix_deps[collapsed=true]\\r\\e[0KFetching Nix dependencies for job" nix build .#$1 source $(readlink -f result) echo -e "\\e[0Ksection_end:`date +%s`:nix_deps\\r\\e[0K" fi echo -e "\\e[0Ksection_end:`date +%s`:nix_setup\\r\\e[0K" ''; finalizeScript = pkgs.writeShellScriptBin "finalize_nix_ci" '' echo -e "\\e[0Ksection_start:`date +%s`:finalize_nix_ci\\r\\e[0KFinalizing Nix CI..." nix path-info --all > /tmp/nix-store-after echo "Finding new paths..." NEW_PATHS=$(${pkgs.diffutils}/bin/diff --new-line-format="%L" \ --old-line-format="" --unchanged-line-format="" \ /tmp/nix-store-before /tmp/nix-store-after) COUNT=$(${pkgs.busybox}/bin/wc -l <<<"$NEW_PATHS") if [ -z "$_NIX_CI_DISABLE_CACHE" ]; then echo -e "\\e[0Ksection_start:`date +%s`:cache_push[collapsed=true]\\r\\e[0KPushing $COUNT new store paths to cache ($_NIX_CI_CACHE_STRATEGY)" echo $NEW_PATHS | { case "$_NIX_CI_CACHE_STRATEGY" in "runner") export RUNNER_CACHE=''${RUNNER_CACHE:-"file://$(pwd)/.nix-cache"} # add ^* to all store paths ending in .drv (prevent warning log spam) ${pkgs.gnused}/bin/sed '/\.drv$/s/$/^*/' | nix copy --quiet --to "$RUNNER_CACHE" --stdin || true ;; "attic") attic push --stdin ci:$ATTIC_CACHE || true ;; "cachix") cachix push $CACHIX_CACHE || true ;; "none") echo "Cache strategy is none, doing nothing..." ;; *) echo "WARNING: Invalid cache strategy set: '$_NIX_CI_CACHE_STRATEGY'" ;; esac } echo -e "\\e[0Ksection_end:`date +%s`:cache_push\\r\\e[0K" else echo "Caching disabled, not uploading $COUNT new store entries..." fi echo -e "\\e[0Ksection_end:`date +%s`:finalize_nix_ci\\r\\e[0K" ''; in { setup-script = setupScript; finalize-script = finalizeScript; image = pkgs.dockerTools.buildImage { name = "nix-ci"; fromImage = let hashes = { "aarch64-linux" = "sha256-mfTNlGOpThanLlLQ2lL1RTcHqZJWdqUafYDZMeZPWEk="; "x86_64-linux" = "sha256-DMlSaP+ZVqxd9NxdFydGyfkuJdmOW5jt5iM/7cDyTEM="; }; # skopeo inspect --raw docker://nixpkgs/nix-flakes digests = { "aarch64-linux" = "sha256:5113a4d10dda16c30bf2e517f29a56890233d2660115003155aab1f7d279d8db"; "x86_64-linux" = "sha256:be07ecf4b5c19be83f63b6f5c7f21bcaf19cf722d339c99cfe2b2ad09f81a7fa"; }; sha256 = hashes.${system} or (throw "Unsupported system"); imageDigest = digests.${system} or (throw "Unsupported system"); in pkgs.dockerTools.pullImage { imageName = "nixpkgs/nix-flakes"; inherit sha256 imageDigest; finalImageName = "nixpkgs/nix-flakes"; finalImageTag = "latest"; }; copyToRoot = pkgs.buildEnv { name = "image-root"; paths = [ pkgs.gitMinimal pkgs.gnugrep pkgs.cachix pkgs.attic-client setupScript finalizeScript ]; pathsToLink = ["/bin"]; }; }; }; checks = packages; }; }; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; # flake & devenv related flake-parts.url = "github:hercules-ci/flake-parts"; systems.url = "github:nix-systems/default-linux"; devenv.url = "github:cachix/devenv"; treefmt-nix.url = "github:numtide/treefmt-nix"; }; nixConfig = { extra-substituters = [ "https://cache.nixos.org/" "https://nix-community.cachix.org" "https://devenv.cachix.org" ]; extra-trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" ]; }; }