diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 00000000000..963d42a297c --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,35 @@ +name: Nix + +on: + push: + branches: [main] + pull_request: + paths: + - 'flake.nix' + - 'flake.lock' + - 'nix/**' + - 'pyproject.toml' + - 'uv.lock' + - 'hermes_cli/**' + - 'run_agent.py' + - 'acp_adapter/**' + +concurrency: + group: nix-${{ github.ref }} + cancel-in-progress: true + +jobs: + nix: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Check flake + run: nix flake check --print-build-logs + - name: Build package + run: nix build --print-build-logs diff --git a/nix/checks.nix b/nix/checks.nix index bb9b4b1a77d..993b96e7a5b 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -22,6 +22,20 @@ echo "ok" > $out/result ''; + # Verify every pyproject.toml [project.scripts] entry has a wrapped binary + entry-points-sync = pkgs.runCommand "hermes-entry-points-sync" { } '' + set -e + echo "=== Checking entry points match pyproject.toml [project.scripts] ===" + # These must match [project.scripts] in pyproject.toml + for bin in hermes hermes-agent hermes-acp; do + test -x ${hermes-agent}/bin/$bin || (echo "FAIL: $bin binary missing from Nix package"; exit 1) + echo "PASS: $bin present" + done + + mkdir -p $out + echo "ok" > $out/result + ''; + # Verify CLI subcommands are accessible cli-commands = pkgs.runCommand "hermes-cli-commands" { } '' set -e @@ -37,15 +51,22 @@ echo "ok" > $out/result ''; - # Verify HERMES_MANAGED guard works + # Verify HERMES_MANAGED guard works on all mutation commands managed-guard = pkgs.runCommand "hermes-managed-guard" { } '' set -e export HOME=$(mktemp -d) - echo "=== Checking HERMES_MANAGED guard ===" - OUTPUT=$(HERMES_MANAGED=true ${hermes-agent}/bin/hermes config set model foo 2>&1 || true) - echo "$OUTPUT" | grep -q "managed by NixOS" || (echo "FAIL: managed guard not working"; echo "$OUTPUT"; exit 1) - echo "PASS: Managed guard blocks config mutation" + check_blocked() { + local label="$1" + shift + OUTPUT=$(HERMES_MANAGED=true "$@" 2>&1 || true) + echo "$OUTPUT" | grep -q "managed by NixOS" || (echo "FAIL: $label not guarded"; echo "$OUTPUT"; exit 1) + echo "PASS: $label blocked in managed mode" + } + + echo "=== Checking HERMES_MANAGED guards ===" + check_blocked "config set" ${hermes-agent}/bin/hermes config set model foo + check_blocked "config edit" ${hermes-agent}/bin/hermes config edit echo "=== All guard checks passed ===" mkdir -p $out diff --git a/nix/packages.nix b/nix/packages.nix index c5806a67c8f..aa2b4bdccd0 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -31,6 +31,9 @@ makeWrapper ${hermesVenv}/bin/hermes-agent $out/bin/hermes-agent \ --prefix PATH : "${runtimePath}" + makeWrapper ${hermesVenv}/bin/hermes-acp $out/bin/hermes-acp \ + --prefix PATH : "${runtimePath}" + runHook postInstall '';