diff --git a/README.md b/README.md index 5ca058f9..ff8c910d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ mrs === [![CI](https://github.com/mbj/mrs/actions/workflows/ci.yml/badge.svg)](https://github.com/mbj/mrs/actions/workflows/ci.yml) +[![NixCI Badge](https://nix-ci.com/badge/gh:mbj:mrs)](https://nix-ci.com/gh:mbj:mrs) A collection of Rust tools for cloud infrastructure, PostgreSQL, Git, and GitHub. diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..84260c03 --- /dev/null +++ b/flake.lock @@ -0,0 +1,98 @@ +{ + "nodes": { + "crane": { + "locked": { + "lastModified": 1771121070, + "narHash": "sha256-aIlv7FRXF9q70DNJPI237dEDAznSKaXmL5lfK/Id/bI=", + "owner": "ipetkov", + "repo": "crane", + "rev": "a2812c19f1ed2e5ed5ce2ef7109798b575c180e1", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1771208521, + "narHash": "sha256-X01Q3DgSpjeBpapoGA4rzKOn25qdKxbPnxHeMLNoHTU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fa56d7d6de78f5a7f997b0ea2bc6efd5868ad9e8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771384185, + "narHash": "sha256-KvmjUeA7uODwzbcQoN/B8DCZIbhT/Q/uErF1BBMcYnw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "23dd7fa91602a68bd04847ac41bc10af1e6e2fd2", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..0a23709a --- /dev/null +++ b/flake.nix @@ -0,0 +1,181 @@ +{ + description = "NixCI demo for the ociman crate"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; + + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + crane.url = "github:ipetkov/crane"; + + flake-utils.url = "github:numtide/flake-utils"; + + }; + + outputs = { nixpkgs, rust-overlay, crane, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ rust-overlay.overlays.default ]; + }; + + craneLib = (crane.mkLib pkgs).overrideToolchain + (pkgs.rust-bin.stable."1.93.0".default.override { + extensions = [ "clippy" "rustfmt" ]; + }); + + src = ./.; + + commonArgs = { + inherit src; + strictDeps = true; + }; + + cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { + pname = "workspace"; + version = "0.0.0"; + }); + + buildPackage = args: craneLib.buildPackage (commonArgs // { + inherit cargoArtifacts; + } // args); + + ociman = buildPackage { + pname = "ociman"; + version = "0.3.1"; + cargoExtraArgs = "-p ociman"; + cargoTestExtraArgs = "--lib -- --skip backend::tests"; + }; + + stratosphere = buildPackage { + pname = "stratosphere"; + version = "0.0.5"; + cargoExtraArgs = "-p stratosphere"; + }; + + stratosphere-core = buildPackage { + pname = "stratosphere-core"; + version = "0.0.5"; + cargoExtraArgs = "-p stratosphere-core"; + }; + + stratosphere-generator = buildPackage { + pname = "stratosphere-generator"; + version = "0.0.5"; + cargoExtraArgs = "-p stratosphere-generator"; + }; + + # Turn a derivation into a fixed-output derivation so the Nix + # sandbox grants network access. The output is a deterministic + # magic string whose hash we pre-compute; the real signal is + # whether the build succeeds or fails. + makePureImpure = drv: + let + magicString = builtins.unsafeDiscardStringContext + (builtins.substring 0 12 (baseNameOf drv.drvPath)); + outputHash = builtins.hashString "sha256" magicString; + in + drv.overrideAttrs (old: { + outputHashAlgo = "sha256"; + outputHashMode = "flat"; + inherit outputHash; + buildCommand = '' + ${old.buildCommand or ""} + rm -rf $out + echo -n "${magicString}" > $out + ''; + }); + in + { + packages = { + inherit ociman stratosphere stratosphere-core stratosphere-generator; + default = ociman; + }; + + checks = { + inherit ociman stratosphere stratosphere-core stratosphere-generator; + + clippy = craneLib.cargoClippy (commonArgs // { + inherit cargoArtifacts; + pname = "workspace"; + version = "0.0.0"; + cargoClippyExtraArgs = "--all-targets -- -D warnings"; + }); + + fmt = craneLib.cargoFmt { + inherit src; + pname = "workspace"; + version = "0.0.0"; + }; + + ociman-integration-test = + let + ocimanTestArchive = craneLib.mkCargoDerivation (commonArgs // { + inherit cargoArtifacts; + pname = "ociman"; + version = "0.3.1"; + nativeBuildInputs = [ pkgs.cargo-nextest ]; + buildPhaseCargoCommand = '' + cargo nextest archive \ + --all-features \ + --release \ + --package ociman \ + --archive-file archive.tar.zst + ''; + installPhaseCommand = '' + mkdir -p $out + cp archive.tar.zst $out/ + ''; + }); + + integrationTest = pkgs.testers.runNixOSTest { + name = "ociman-integration-test"; + nodes.machine = { pkgs, lib, ... }: { + virtualisation.podman.enable = true; + virtualisation.memorySize = 4096; + virtualisation.cores = 2; + virtualisation.diskSize = 8192; + networking.useDHCP = lib.mkForce true; + environment.systemPackages = [ pkgs.cargo-nextest ]; + }; + testScript = '' + machine.wait_for_unit("default.target") + machine.wait_for_unit("dhcpcd.service") + machine.succeed( + "cp -r ${src}/. /tmp/source" + " && chmod -R u+w /tmp/source" + " && OCIMAN_BACKEND=podman" + " cargo-nextest nextest run" + " --archive-file ${ocimanTestArchive}/archive.tar.zst" + " --workspace-remap /tmp/source" + " --test-threads=1" + ) + ''; + }; + in + makePureImpure (pkgs.stdenv.mkDerivation { + name = "ociman-integration-test"; + requiredSystemFeatures = [ "nixos-test" "kvm" ]; + buildCommand = '' + mkdir -p $out + export LOGFILE=/dev/null + ${integrationTest.driver}/bin/nixos-test-driver -o $out + ''; + }); + }; + + devShells.default = craneLib.devShell { + checks = { + inherit ociman; + }; + packages = [ + pkgs.cargo-nextest + ]; + }; + } + ); +}