Kaynağa Gözat

fix(nix): restore native runners for darwin hash computation (#11495)

Jérôme Benoit 2 hafta önce
ebeveyn
işleme
121d6a72c0
3 değiştirilmiş dosya ile 101 ekleme ve 104 silme
  1. 92 79
      .github/workflows/nix-hashes.yml
  2. 5 18
      flake.nix
  3. 4 7
      nix/node_modules.nix

+ 92 - 79
.github/workflows/nix-hashes.yml

@@ -21,11 +21,68 @@ on:
       - ".github/workflows/nix-hashes.yml"
 
 jobs:
-  nix-hashes:
-    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
+  # Native runners required: bun install cross-compilation flags (--os/--cpu)
+  # do not produce byte-identical node_modules as native installs.
+  compute-hash:
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - system: x86_64-linux
+            runner: blacksmith-4vcpu-ubuntu-2404
+          - system: aarch64-linux
+            runner: blacksmith-4vcpu-ubuntu-2404-arm
+          - system: x86_64-darwin
+            runner: macos-15-intel
+          - system: aarch64-darwin
+            runner: macos-latest
+    runs-on: ${{ matrix.runner }}
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v6
+
+      - name: Setup Nix
+        uses: nixbuild/nix-quick-install-action@v34
+
+      - name: Compute node_modules hash
+        id: hash
+        env:
+          SYSTEM: ${{ matrix.system }}
+        run: |
+          set -euo pipefail
+
+          BUILD_LOG=$(mktemp)
+          trap 'rm -f "$BUILD_LOG"' EXIT
+
+          # Build with fakeHash to trigger hash mismatch and reveal correct hash
+          nix build ".#packages.${SYSTEM}.node_modules_updater" --no-link 2>&1 | tee "$BUILD_LOG" || true
+
+          HASH="$(grep -E 'got:\s+sha256-' "$BUILD_LOG" | sed -E 's/.*got:\s+(sha256-[A-Za-z0-9+/=]+).*/\1/' | head -n1 || true)"
+          if [ -z "$HASH" ]; then
+            HASH="$(grep -A2 'hash mismatch' "$BUILD_LOG" | grep 'got:' | sed -E 's/.*got:\s+(sha256-[A-Za-z0-9+/=]+).*/\1/' | head -n1 || true)"
+          fi
+
+          if [ -z "$HASH" ]; then
+            echo "::error::Failed to compute hash for ${SYSTEM}"
+            cat "$BUILD_LOG"
+            exit 1
+          fi
+
+          echo "$HASH" > hash.txt
+          echo "Computed hash for ${SYSTEM}: $HASH"
+
+      - name: Upload hash
+        uses: actions/upload-artifact@v4
+        with:
+          name: hash-${{ matrix.system }}
+          path: hash.txt
+          retention-days: 1
+
+  update-hashes:
+    needs: compute-hash
+    if: github.event_name != 'pull_request'
     runs-on: blacksmith-4vcpu-ubuntu-2404
-    env:
-      TITLE: node_modules hashes
 
     steps:
       - name: Checkout repository
@@ -33,108 +90,64 @@ jobs:
         with:
           token: ${{ secrets.GITHUB_TOKEN }}
           fetch-depth: 0
-          ref: ${{ github.head_ref || github.ref_name }}
-          repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
+          ref: ${{ github.ref_name }}
 
       - name: Setup git committer
-        id: committer
         uses: ./.github/actions/setup-git-committer
         with:
           opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
           opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
 
-      - name: Setup Nix
-        uses: nixbuild/nix-quick-install-action@v34
-
       - name: Pull latest changes
-        env:
-          TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
         run: |
-          BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
-          git pull --rebase --autostash origin "$BRANCH"
+          git pull --rebase --autostash origin "$GITHUB_REF_NAME"
 
-      - name: Compute all node_modules hashes
+      - name: Download hash artifacts
+        uses: actions/download-artifact@v4
+        with:
+          path: hashes
+          pattern: hash-*
+
+      - name: Update hashes.json
         run: |
           set -euo pipefail
 
           HASH_FILE="nix/hashes.json"
-          SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin"
-
-          if [ ! -f "$HASH_FILE" ]; then
-            mkdir -p "$(dirname "$HASH_FILE")"
-            echo '{"nodeModules":{}}' > "$HASH_FILE"
-          fi
-
-          for SYSTEM in $SYSTEMS; do
-            echo "Computing hash for ${SYSTEM}..."
-            BUILD_LOG=$(mktemp)
-            trap 'rm -f "$BUILD_LOG"' EXIT
 
-            # The updater derivations use fakeHash, so they will fail and reveal the correct hash
-            UPDATER_ATTR=".#packages.x86_64-linux.${SYSTEM}_node_modules"
-
-            nix build "$UPDATER_ATTR" --no-link 2>&1 | tee "$BUILD_LOG" || true
-
-            CORRECT_HASH="$(grep -E 'got:\s+sha256-[A-Za-z0-9+/=]+' "$BUILD_LOG" | awk '{print $2}' | head -n1 || true)"
-
-            if [ -z "$CORRECT_HASH" ]; then
-              CORRECT_HASH="$(grep -A2 'hash mismatch' "$BUILD_LOG" | grep 'got:' | awk '{print $2}' | sed 's/sha256:/sha256-/' || true)"
-            fi
-
-            if [ -z "$CORRECT_HASH" ]; then
-              echo "Failed to determine correct node_modules hash for ${SYSTEM}."
-              cat "$BUILD_LOG"
-              exit 1
+          [ -f "$HASH_FILE" ] || echo '{"nodeModules":{}}' > "$HASH_FILE"
+
+          for SYSTEM in x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin; do
+            FILE="hashes/hash-${SYSTEM}/hash.txt"
+            if [ -f "$FILE" ]; then
+              HASH="$(tr -d '[:space:]' < "$FILE")"
+              echo "${SYSTEM}: ${HASH}"
+              jq --arg sys "$SYSTEM" --arg h "$HASH" '.nodeModules[$sys] = $h' "$HASH_FILE" > tmp.json
+              mv tmp.json "$HASH_FILE"
+            else
+              echo "::warning::Missing hash for ${SYSTEM}"
             fi
-
-            echo "  ${SYSTEM}: ${CORRECT_HASH}"
-            jq --arg sys "$SYSTEM" --arg h "$CORRECT_HASH" \
-              '.nodeModules[$sys] = $h' "$HASH_FILE" > "${HASH_FILE}.tmp"
-            mv "${HASH_FILE}.tmp" "$HASH_FILE"
           done
 
-          echo "All hashes computed:"
           cat "$HASH_FILE"
 
-      - name: Commit ${{ env.TITLE }} changes
-        env:
-          TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
+      - name: Commit changes
         run: |
           set -euo pipefail
 
           HASH_FILE="nix/hashes.json"
-          echo "Checking for changes..."
-
-          summarize() {
-            local status="$1"
-            {
-              echo "### Nix $TITLE"
-              echo ""
-              echo "- ref: ${GITHUB_REF_NAME}"
-              echo "- status: ${status}"
-            } >> "$GITHUB_STEP_SUMMARY"
-            if [ -n "${GITHUB_SERVER_URL:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_RUN_ID:-}" ]; then
-              echo "- run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> "$GITHUB_STEP_SUMMARY"
-            fi
-            echo "" >> "$GITHUB_STEP_SUMMARY"
-          }
-
-          FILES=("$HASH_FILE")
-          STATUS="$(git status --short -- "${FILES[@]}" || true)"
-          if [ -z "$STATUS" ]; then
-            echo "No changes detected."
-            summarize "no changes"
+
+          if [ -z "$(git status --short -- "$HASH_FILE")" ]; then
+            echo "No changes to commit"
+            echo "### Nix hashes" >> "$GITHUB_STEP_SUMMARY"
+            echo "Status: no changes" >> "$GITHUB_STEP_SUMMARY"
             exit 0
           fi
 
-          echo "Changes detected:"
-          echo "$STATUS"
-          git add "${FILES[@]}"
+          git add "$HASH_FILE"
           git commit -m "chore: update nix node_modules hashes"
 
-          BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
-          git pull --rebase --autostash origin "$BRANCH"
-          git push origin HEAD:"$BRANCH"
-          echo "Changes pushed successfully"
+          git pull --rebase --autostash origin "$GITHUB_REF_NAME"
+          git push origin HEAD:"$GITHUB_REF_NAME"
 
-          summarize "committed $(git rev-parse --short HEAD)"
+          echo "### Nix hashes" >> "$GITHUB_STEP_SUMMARY"
+          echo "Status: committed $(git rev-parse --short HEAD)" >> "$GITHUB_STEP_SUMMARY"

+ 5 - 18
flake.nix

@@ -42,28 +42,15 @@
           desktop = pkgs.callPackage ./nix/desktop.nix {
             inherit opencode;
           };
-          # nixpkgs cpu naming to bun cpu naming
-          cpuMap = { x86_64 = "x64"; aarch64 = "arm64"; };
-          # matrix of node_modules builds - these will always fail due to fakeHash usage
-          # but allow computation of the correct hash from any build machine for any cpu/os
-          # see the update-nix-hashes workflow for usage
-          moduleUpdaters = pkgs.lib.listToAttrs (
-            pkgs.lib.concatMap (cpu:
-              map (os: {
-                name = "${cpu}-${os}_node_modules";
-                value = node_modules.override {
-                  bunCpu = cpuMap.${cpu};
-                  bunOs = os;
-                  hash = pkgs.lib.fakeHash;
-                };
-              }) [ "linux" "darwin" ]
-            ) [ "x86_64" "aarch64" ]
-          );
         in
         {
           default = opencode;
           inherit opencode desktop;
-        } // moduleUpdaters
+          # Updater derivation with fakeHash - build fails and reveals correct hash
+          node_modules_updater = node_modules.override {
+            hash = pkgs.lib.fakeHash;
+          };
+        }
       );
     };
 }

+ 4 - 7
nix/node_modules.nix

@@ -2,8 +2,6 @@
   lib,
   stdenvNoCC,
   bun,
-  bunCpu ? if stdenvNoCC.hostPlatform.isAarch64 then "arm64" else "x64",
-  bunOs ? if stdenvNoCC.hostPlatform.isLinux then "linux" else "darwin",
   rev ? "dirty",
   hash ?
     (lib.pipe ./hashes.json [
@@ -16,6 +14,9 @@ let
     builtins.readFile
     builtins.fromJSON
   ];
+  platform = stdenvNoCC.hostPlatform;
+  bunCpu = if platform.isAarch64 then "arm64" else "x64";
+  bunOs = if platform.isLinux then "linux" else "darwin";
 in
 stdenvNoCC.mkDerivation {
   pname = "opencode-node_modules";
@@ -39,9 +40,7 @@ stdenvNoCC.mkDerivation {
     "SOCKS_SERVER"
   ];
 
-  nativeBuildInputs = [
-    bun
-  ];
+  nativeBuildInputs = [ bun ];
 
   dontConfigure = true;
 
@@ -63,10 +62,8 @@ stdenvNoCC.mkDerivation {
 
   installPhase = ''
     runHook preInstall
-
     mkdir -p $out
     find . -type d -name node_modules -exec cp -R --parents {} $out \;
-
     runHook postInstall
   '';