From 203b2b93a547148bb2933c91595fc99bfac33ce7 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans-personal@users.noreply.github.com> Date: Sun, 31 May 2026 10:56:37 -0400 Subject: [PATCH 1/2] feat(workflows): add reusable Nix validate/build templates Relocate the shared Nix CI reusable workflows into dryvist/.github so the org has one normalized, FlakeHub-free Nix CI source. Ported byte-identical from JacobPEvans-personal/.github (git-blob SHA match) so the consumer repoint is a clean uses: owner-swap and the eventual personal-copy removal needs no drift reconciliation. Both use determinate-nix-action (installer only) + actions/cache; neither touches FlakeHub. zizmor policy already permits DeterminateSystems/* ref-pin, so no policy change is needed. Assisted-by: Claude:claude-opus-4-8 --- .github/workflows/_nix-build.yml | 73 +++++++++++++++++++ .github/workflows/_nix-validate.yml | 107 ++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 .github/workflows/_nix-build.yml create mode 100644 .github/workflows/_nix-validate.yml diff --git a/.github/workflows/_nix-build.yml b/.github/workflows/_nix-build.yml new file mode 100644 index 0000000..f3fe983 --- /dev/null +++ b/.github/workflows/_nix-build.yml @@ -0,0 +1,73 @@ +# Reusable: Nix Build (macOS) +# Builds a Nix flake on macOS with store caching. +# Default build command targets home-manager; override for darwin-rebuild. +name: _nix-build + +on: + workflow_call: + inputs: + build-command: + description: "Build command to run (default: home-manager build)" + required: false + type: string + default: "nix build .#homeConfigurations.$(whoami).activationPackage --print-build-logs" + +permissions: {} + +concurrency: + group: nix-build-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build + runs-on: macos-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6 + + # determinate-nix-action@v3 is ONLY a Nix installer (replaced nix-installer-action@v21). + # It does NOT include flake checking — flake validation is in _nix-validate.yml. + - name: Install Nix + uses: DeterminateSystems/determinate-nix-action@v3 + with: + extra-conf: | + max-jobs = auto + cores = 0 + http-connections = 50 + connect-timeout = 5 + stalled-download-timeout = 10 + narinfo-cache-positive-ttl = 86400 + fallback = true + + - name: Restore Nix Store Cache + uses: actions/cache/restore@v5 + id: nix-cache + with: + path: | + /nix/store + ~/.cache/nix + key: nix-macos-${{ runner.os }}-${{ hashFiles('flake.lock') }} + restore-keys: | + nix-macos-${{ runner.os }}- + + - name: Build + run: ${{ inputs.build-command }} + + - name: Garbage Collect Nix Store + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.nix-cache.outputs.cache-hit != 'true' + run: | + echo "Store size before GC: $(du -sh /nix/store | cut -f1)" + nix-collect-garbage --delete-older-than 1d + echo "Store size after GC: $(du -sh /nix/store | cut -f1)" + + - name: Save Nix Store Cache + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.nix-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v5 + with: + path: | + /nix/store + ~/.cache/nix + key: nix-macos-${{ runner.os }}-${{ hashFiles('flake.lock') }} diff --git a/.github/workflows/_nix-validate.yml b/.github/workflows/_nix-validate.yml new file mode 100644 index 0000000..482933a --- /dev/null +++ b/.github/workflows/_nix-validate.yml @@ -0,0 +1,107 @@ +# Reusable: Nix Validate +# Runs `nix flake check` for the current system, optionally with --all-systems +# to catch packages broken on darwin from a linux runner before they merge. +name: _nix-validate + +on: + workflow_call: + inputs: + runner_label: + description: >- + GitHub Actions runner label to run the validate job on. Defaults to + ubuntu-latest. Pass a RunsOn label (see runs-on.com job labels docs) + to opt the calling repo into self-hosted runners. + type: string + required: false + default: ubuntu-latest + all_systems: + description: >- + Pass --all-systems to nix flake check to evaluate outputs for every + declared system from the runner. Defaults true. Set false for repos + whose check derivations are platform-specific (require darwin + binaries to build), since `nix flake check --all-systems` attempts + to build cross-platform checks and fails with "platform mismatch". + type: boolean + required: false + default: true + +concurrency: + group: nix-validate-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + validate: + name: Validate + runs-on: ${{ inputs.runner_label }} + # Hard cap so a wedged `nix flake check` (network hang, runner stall) can't + # block `Merge Gate` indefinitely. Queue-stuck handling lives in the + # _ci-gate watchdog; this is the running-job side of defense in depth. + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v6 + + # Free ~30GB on the ubuntu-latest runner so `nix flake check --all-systems` + # has space to substitute darwin source paths (rustc-src, cctools, + # apple-sdk, etc.) without hitting "No space left on device". Only needed + # when all_systems is true; gated to ubuntu-* runners so self-hosted + # runner long-lived state is never modified. + - name: Free disk space + if: inputs.all_systems && startsWith(inputs.runner_label, 'ubuntu-') + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: false + docker-images: true + + # determinate-nix-action@v3 is ONLY a Nix installer (replaced nix-installer-action@v21). + # It does NOT include flake checking — that was a separate action (flake-checker-action). + # Flake evaluation is handled by `nix flake check` below, not by the installer. + - name: Install Nix + uses: DeterminateSystems/determinate-nix-action@v3 + with: + extra-conf: | + max-jobs = auto + cores = 0 + http-connections = 50 + connect-timeout = 5 + stalled-download-timeout = 10 + narinfo-cache-positive-ttl = 86400 + fallback = true + log-lines = 1000 + + - name: Restore Nix Store Cache + uses: actions/cache/restore@v5 + id: nix-cache + with: + path: | + /nix/store + ~/.cache/nix + key: nix-linux-${{ runner.os }}-${{ hashFiles('flake.lock') }} + restore-keys: | + nix-linux-${{ runner.os }}- + + - name: Check flake + # --all-systems evaluates outputs for every declared system to catch + # darwin-only broken packages from the linux runner. Disabled by setting + # `all_systems: false` for repos whose checks build platform-specific + # derivations (require darwin binaries). + env: + ALL_SYSTEMS_FLAG: ${{ inputs.all_systems && '--all-systems' || '' }} + run: nix flake check $ALL_SYSTEMS_FLAG --print-build-logs --show-trace --keep-going + + - name: Save Nix Store Cache + if: github.event_name == 'push' && steps.nix-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v5 + with: + path: | + /nix/store + ~/.cache/nix + key: nix-linux-${{ runner.os }}-${{ hashFiles('flake.lock') }} From c6f3e41da68f8b425e297ba14dfb3d079083003f Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans-personal@users.noreply.github.com> Date: Sun, 31 May 2026 11:10:42 -0400 Subject: [PATCH 2/2] feat(zizmor): trust dryvist/* reusable workflows (ref-pin) The org references its own reusable workflows via @main (self-reference convention), but the unpinned-uses policy only trusted external vendors, so a dryvist/.github reusable-workflow call failed zizmor with a SHA-pin demand. Add dryvist/* to the trusted-publisher list so consumers can call the new Nix templates as dryvist/.github/...@main. Assisted-by: Claude:claude-opus-4-8 --- zizmor.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zizmor.yml b/zizmor.yml index 80604b7..0104b58 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -10,10 +10,16 @@ # Trusted publishers below are allowed to use `ref-pin` (tag or branch # references). Everything else falls through to zizmor's implicit # `hash-pin` default. +# +# `dryvist/*` is the org itself: first-party reusable workflows (e.g. +# dryvist/.github's `_nix-validate.yml`, dryvist/ai-workflows) are +# referenced via `@main` per the self-reference convention, so they must +# be trusted here rather than SHA-pinned. rules: unpinned-uses: config: policies: actions/*: ref-pin DeterminateSystems/*: ref-pin + dryvist/*: ref-pin googleapis/*: ref-pin