nix.yml
1 name: Nix 2 3 on: 4 push: 5 branches: [main] 6 pull_request: 7 8 permissions: 9 contents: read 10 pull-requests: write 11 12 concurrency: 13 group: nix-${{ github.ref }} 14 cancel-in-progress: true 15 16 jobs: 17 nix: 18 strategy: 19 matrix: 20 os: [ubuntu-latest, macos-latest] 21 runs-on: ${{ matrix.os }} 22 timeout-minutes: 30 23 steps: 24 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 25 - uses: ./.github/actions/nix-setup 26 with: 27 cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} 28 29 - name: Resolve head SHA 30 if: github.event_name == 'pull_request' 31 id: sha 32 shell: bash 33 run: | 34 FULL="${{ github.event.pull_request.head.sha || github.sha }}" 35 echo "full=$FULL" >> "$GITHUB_OUTPUT" 36 echo "short=${FULL:0:7}" >> "$GITHUB_OUTPUT" 37 38 - name: Check flake 39 id: flake 40 if: runner.os == 'Linux' 41 continue-on-error: true 42 run: nix flake check --print-build-logs 43 44 - name: Build package 45 id: build 46 if: runner.os == 'Linux' 47 continue-on-error: true 48 run: nix build --print-build-logs 49 50 # When the real Nix build fails, run a targeted diagnostic to see if 51 # the failure is specifically a stale npm lockfile hash in one of the 52 # known npm subpackages (tui / web). This avoids surfacing a generic 53 # "build failed" message when the fix is a single known command. 54 - name: Diagnose npm lockfile hashes 55 id: hash_check 56 if: (steps.flake.outcome == 'failure' || steps.build.outcome == 'failure') && runner.os == 'Linux' 57 continue-on-error: true 58 env: 59 LINK_SHA: ${{ steps.sha.outputs.full }} 60 run: nix run .#fix-lockfiles -- --check 61 62 # If fix-lockfiles itself crashes (infrastructure blip, cache throttle, 63 # etc.) it won't set stale=true/false. Treat that as a distinct failure 64 # mode rather than silently ignoring it. 65 - name: Fail if hash check crashed without reporting 66 if: steps.hash_check.outcome == 'failure' && steps.hash_check.outputs.stale != 'true' && steps.hash_check.outputs.stale != 'false' 67 run: | 68 echo "::error::fix-lockfiles exited without reporting stale status — likely an infrastructure or script failure" 69 exit 1 70 71 - name: Post sticky PR comment (stale hashes) 72 if: steps.hash_check.outputs.stale == 'true' && github.event_name == 'pull_request' 73 uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1 74 with: 75 header: nix-lockfile-check 76 message: | 77 ### ⚠️ npm lockfile hash out of date 78 79 Checked against commit [`${{ steps.sha.outputs.short }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ steps.sha.outputs.full }}) (PR head at check time). 80 81 The `hash = "sha256-..."` line in these nix files no longer matches the committed `package-lock.json`: 82 83 ${{ steps.hash_check.outputs.report }} 84 85 #### Apply the fix 86 87 - [ ] **Apply lockfile fix** — tick to push a commit with the correct hashes to this PR branch 88 - Or [run the Nix Lockfile Fix workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/nix-lockfile-fix.yml) manually (pass PR `#${{ github.event.pull_request.number }}`) 89 - Or locally: `nix run .#fix-lockfiles` and commit the diff 90 91 # Clear the sticky comment when either the build passed outright (no 92 # hash check needed) or the hash check explicitly returned stale=false 93 # (build failed for a non-hash reason). 94 - name: Clear sticky PR comment (resolved) 95 if: | 96 github.event_name == 'pull_request' && 97 runner.os == 'Linux' && 98 (steps.hash_check.outputs.stale == 'false' || 99 (steps.flake.outcome == 'success' && steps.build.outcome == 'success')) 100 uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1 101 with: 102 header: nix-lockfile-check 103 delete: true 104 105 - name: Final fail if build or flake failed 106 if: steps.flake.outcome == 'failure' || steps.build.outcome == 'failure' 107 run: | 108 if [ "${{ steps.hash_check.outputs.stale }}" == "true" ]; then 109 echo "::error::Nix build failed due to stale npm lockfile hash. Run: nix run .#fix-lockfiles" 110 else 111 echo "::error::Nix build/flake check failed. See logs above." 112 fi 113 exit 1 114 115 - name: Evaluate flake (macOS) 116 if: runner.os == 'macOS' 117 run: nix flake show --json > /dev/null