From 96addde4c7eb605996f044d7b1e090783138b9cb Mon Sep 17 00:00:00 2001 From: noah-emp Date: Sun, 25 Oct 2026 14:25:57 -0400 Subject: [PATCH 1/2] feat(nix): build and check on x86_64-linux, aarch64-linux and aarch64-darwin --- .github/workflows/ci.yml | 2 +- ez.lock.toml | 6 +-- ez.toml | 6 +-- flake.lock | 6 +-- flake.nix | 97 ++++++++++++++++++++++------------------ 5 files changed, 64 insertions(+), 53 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9123467..ab0fe0d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,4 +8,4 @@ on: jobs: check: - uses: Emerging-Patterns/actions/.github/workflows/nix-flake-check.yml@73b2fbc64cefd6e22bd786437adb5f35190ee837 + uses: Emerging-Patterns/actions/.github/workflows/nix-flake-check.yml@5b0aa4f0eaee72662e06479ecebcfd15e9762fe7 diff --git a/ez.lock.toml b/ez.lock.toml index 21c98c5..8454d7e 100644 --- a/ez.lock.toml +++ b/ez.lock.toml @@ -51,8 +51,8 @@ LICENSE = "309f5aae946e4db157750e002fb179a74ed0fe27fce09a7be68a6977b14f205f" [tools] [tools.bolt] git = "https://github.com/Emerging-Patterns/bolt" -rev = "358c2da98df8d2d15c5ceaa3a56521212b9029ca" -tag = "v1.17.0" +rev = "7f5bb328187efa21598b4fed51cb1e154cf36330" +tag = "v1.19.0" root = "." -narHash = "sha256-J+XYAGvL7FOs4NgRwGG8itNlYTIQBM7dNq/r5nrB1Z8=" +narHash = "sha256-9d+ikveuzegJVH8nbEYSAxy8Pt0dYDyW4ISZml+MsNM=" entry = "main.bend" diff --git a/ez.toml b/ez.toml index 4a06ed5..159759c 100644 --- a/ez.toml +++ b/ez.toml @@ -25,8 +25,8 @@ entry = "dns.bend" [tools] [tools.bolt] git = "https://github.com/Emerging-Patterns/bolt" -rev = "358c2da98df8d2d15c5ceaa3a56521212b9029ca" -tag = "v1.17.0" +rev = "7f5bb328187efa21598b4fed51cb1e154cf36330" +tag = "v1.19.0" root = "." -narHash = "sha256-J+XYAGvL7FOs4NgRwGG8itNlYTIQBM7dNq/r5nrB1Z8=" +narHash = "sha256-9d+ikveuzegJVH8nbEYSAxy8Pt0dYDyW4ISZml+MsNM=" entry = "main.bend" diff --git a/flake.lock b/flake.lock index 6bc5671..8ba92af 100644 --- a/flake.lock +++ b/flake.lock @@ -31,11 +31,11 @@ ] }, "locked": { - "lastModified": 1792730458, - "narHash": "sha256-gpyP8MmnJcmOdvlWRm5SGMKomi/pimr9dKaq0DExVew=", + "lastModified": 1792951717, + "narHash": "sha256-D+oXyyhyymwc0Diu4JzDEdmIKBsWl8W6GagPk0odVts=", "owner": "Emerging-Patterns", "repo": "ez", - "rev": "166a23c54b1c5a7bf587abd3d906332bd73a856b", + "rev": "0913fd229552109f7d36ab2746b49f95cb785655", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 140e1c5..398d8df 100644 --- a/flake.nix +++ b/flake.nix @@ -16,52 +16,63 @@ outputs = { self, nixpkgs, ... }@inputs: let - system = "x86_64-linux"; - pkgs = nixpkgs.legacyPackages.${system}; - version = "0.21.0"; # x-release-please-version - ez = inputs.ez.lib.${system}; - ezBin = inputs.ez.packages.${system}.default; - bend = inputs.bend.packages.${system}.default; - bolt = ez.toolPackage { name = "bolt"; src = self; inherit bend; wrapFlags = ez.rtsFlags bend [ "--gpu" "off" ]; }; - bend-cc = ez.bend-cc; + systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ]; + forEach = nixpkgs.lib.genAttrs systems; + outputsFor = system: + let + pkgs = nixpkgs.legacyPackages.${system}; + version = "0.21.0"; # x-release-please-version + ez = inputs.ez.lib.${system}; + ezBin = inputs.ez.packages.${system}.default; + bend = inputs.bend.packages.${system}.default; + bolt = ez.toolPackage { name = "bolt"; src = self; inherit bend; wrapFlags = ez.rtsFlags bend [ "--gpu" "off" ]; }; + bend-cc = ez.bend-cc; - bench = import ./bench { - inherit pkgs bend bend-cc self ez; - lib = pkgs.lib; - }; - in { - packages.${system} = { - inherit bend bend-cc; - ez = ezBin; - inherit bolt; - } // bench.packages; + bench = import ./bench { + inherit pkgs bend bend-cc self ez; + lib = pkgs.lib; + }; + in { + packages = { + inherit bend bend-cc; + ez = ezBin; + inherit bolt; + } // bench.packages; - apps.${system} = bench.apps; + apps = bench.apps; - checks.${system} = { - proofs = ez.mkProofs { ez = ezBin; src = self; }; - lint = ez.mkLint { src = self; }; - } // bench.checks; + checks = { + proofs = ez.mkProofs { ez = ezBin; src = self; }; + lint = ez.mkLint { src = self; }; + } // bench.checks; - devShells.${system}.default = ez.mkShell { - src = self; - packages = [ - bend - bend-cc - ezBin - pkgs.openssl - pkgs.cacert - pkgs.python3 - pkgs.hey - bench.packages.ezhttp-bench-drv - bench.packages.ezhttp-rust-ref - bench.packages.ezhttp-http-check - bench.packages.ezhttp-http-bench - ]; - extraHook = '' - export BEND_LIBSSL=${pkgs.openssl.out}/lib/libssl.so.3 - export SSL_CERT_FILE=''${SSL_CERT_FILE:-${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt} - ''; - }; + devShells.default = ez.mkShell { + src = self; + packages = [ + bend + bend-cc + ezBin + pkgs.openssl + pkgs.cacert + pkgs.python3 + pkgs.hey + bench.packages.ezhttp-bench-drv + bench.packages.ezhttp-rust-ref + bench.packages.ezhttp-http-check + bench.packages.ezhttp-http-bench + ]; + extraHook = '' + export BEND_LIBSSL=${pkgs.openssl.out}/lib/libssl.so.3 + export SSL_CERT_FILE=''${SSL_CERT_FILE:-${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt} + ''; + }; + }; + perSystem = forEach outputsFor; + each = name: forEach (system: perSystem.${system}.${name}); + in { + packages = each "packages"; + checks = each "checks"; + apps = each "apps"; + devShells = each "devShells"; }; } From 1d29cbc4cc7857962ecc594430bc7d16895ce66a Mon Sep 17 00:00:00 2001 From: noah-emp Date: Sun, 25 Oct 2026 14:39:37 -0400 Subject: [PATCH 2/2] fix(bench): find a listening port without /proc --- bench/compare.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/bench/compare.nix b/bench/compare.nix index 052409f..3bc7d0a 100644 --- a/bench/compare.nix +++ b/bench/compare.nix @@ -194,11 +194,13 @@ def err_tail(path): def port_listening(port): want = f"{port:04X}" + tables = 0 for name in ("/proc/net/tcp", "/proc/net/tcp6"): try: lines = open(name, encoding="utf-8", errors="replace").read().splitlines() except OSError: continue + tables += 1 for line in lines[1:]: parts = line.split() if len(parts) < 4 or parts[3] != "0A": @@ -206,11 +208,22 @@ def port_listening(port): _ip, _, port_hex = parts[1].rpartition(":") if port_hex.upper() == want: return True + if tables: + return False + # no /proc (macOS): the port is taken once a bind to it is refused + probe = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + probe.bind(("127.0.0.1", port)) + except OSError: + return True + finally: + probe.close() return False def wait_port(port, proc, err_path, timeout=30): # A connect would be an accepted request. serve_once has only one, and - # serve's limit is the measured N, so readiness is the LISTEN row. + # serve's limit is the measured N, so readiness is the LISTEN row, or + # the bound port where there is no /proc. deadline = time.time() + timeout while time.time() < deadline: if proc.poll() is not None: