1010 - " bun.lock"
1111 - " package.json"
1212 - " packages/*/package.json"
13+ - " flake.lock"
1314 - " .github/workflows/update-nix-hashes.yml"
1415 pull_request :
1516 paths :
1617 - " bun.lock"
1718 - " package.json"
1819 - " packages/*/package.json"
20+ - " flake.lock"
1921 - " .github/workflows/update-nix-hashes.yml"
2022
2123jobs :
22- update-flake :
24+ update-node-modules-hashes :
2325 if : github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
2426 runs-on : blacksmith-4vcpu-ubuntu-2404
2527 env :
26- TITLE : flake.lock
28+ TITLE : node_modules hashes
2729
2830 steps :
2931 - name : Checkout repository
@@ -42,248 +44,54 @@ jobs:
4244 git config --global user.email "[email protected] " 4345 git config --global user.name "Github Action"
4446
45- - name : Update ${{ env.TITLE }}
46- run : |
47- set -euo pipefail
48- echo "Updating $TITLE..."
49- nix flake update
50- echo "$TITLE updated successfully"
51-
52- - name : Commit ${{ env.TITLE }} changes
47+ - name : Pull latest changes
5348 env :
5449 TARGET_BRANCH : ${{ github.head_ref || github.ref_name }}
5550 run : |
56- set -euo pipefail
57-
58- echo "Checking for changes in tracked files..."
59-
60- summarize() {
61- local status="$1"
62- {
63- echo "### Nix $TITLE"
64- echo ""
65- echo "- ref: ${GITHUB_REF_NAME}"
66- echo "- status: ${status}"
67- } >> "$GITHUB_STEP_SUMMARY"
68- if [ -n "${GITHUB_SERVER_URL:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_RUN_ID:-}" ]; then
69- echo "- run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> "$GITHUB_STEP_SUMMARY"
70- fi
71- echo "" >> "$GITHUB_STEP_SUMMARY"
72- }
73- FILES=(flake.lock flake.nix)
74- STATUS="$(git status --short -- "${FILES[@]}" || true)"
75- if [ -z "$STATUS" ]; then
76- echo "No changes detected."
77- summarize "no changes"
78- exit 0
79- fi
80-
81- echo "Changes detected:"
82- echo "$STATUS"
83- echo "Staging files..."
84- git add "${FILES[@]}"
85- echo "Committing changes..."
86- git commit -m "Update $TITLE"
87- echo "Changes committed"
88-
8951 BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
90- echo "Pulling latest from branch: $BRANCH"
9152 git pull --rebase --autostash origin "$BRANCH"
92- echo "Pushing changes to branch: $BRANCH"
93- git push origin HEAD:"$BRANCH"
94- echo "Changes pushed successfully"
95-
96- summarize "committed $(git rev-parse --short HEAD)"
97-
98- compute-node-modules-hash :
99- needs : update-flake
100- if : github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
101- strategy :
102- fail-fast : false
103- matrix :
104- include :
105- - system : x86_64-linux
106- host : blacksmith-4vcpu-ubuntu-2404
107- - system : aarch64-linux
108- host : blacksmith-4vcpu-ubuntu-2404-arm
109- - system : x86_64-darwin
110- host : macos-15-intel
111- - system : aarch64-darwin
112- host : macos-latest
113- runs-on : ${{ matrix.host }}
114- env :
115- SYSTEM : ${{ matrix.system }}
116-
117- steps :
118- - name : Checkout repository
119- uses : actions/checkout@v6
120- with :
121- token : ${{ secrets.GITHUB_TOKEN }}
122- fetch-depth : 0
123- ref : ${{ github.head_ref || github.ref_name }}
124- repository : ${{ github.event.pull_request.head.repo.full_name || github.repository }}
12553
126- - name : Setup Nix
127- uses : nixbuild/nix-quick-install-action@v34
128-
129- - name : Compute node_modules hash
54+ - name : Compute all node_modules hashes
13055 run : |
13156 set -euo pipefail
13257
133- DUMMY="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
13458 HASH_FILE="nix/hashes.json"
135- OUTPUT_FILE="hash-${SYSTEM}.txt"
136-
137- export NIX_KEEP_OUTPUTS=1
138- export NIX_KEEP_DERIVATIONS=1
139-
140- BUILD_LOG=$(mktemp)
141- TMP_JSON=$(mktemp)
142- trap 'rm -f "$BUILD_LOG" "$TMP_JSON"' EXIT
59+ SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin"
14360
14461 if [ ! -f "$HASH_FILE" ]; then
14562 mkdir -p "$(dirname "$HASH_FILE")"
14663 echo '{"nodeModules":{}}' > "$HASH_FILE"
14764 fi
14865
149- # Set dummy hash to force nix to rebuild and reveal correct hash
150- jq --arg system "$SYSTEM" --arg value "$DUMMY" \
151- '.nodeModules = (.nodeModules // {}) | .nodeModules[$system] = $value' "$HASH_FILE" > "$TMP_JSON"
152- mv "$TMP_JSON" "$HASH_FILE"
153-
154- MODULES_ATTR=".#packages.${SYSTEM}.default.node_modules"
155- DRV_PATH="$(nix eval --raw "${MODULES_ATTR}.drvPath")"
156-
157- echo "Building node_modules for ${SYSTEM} to discover correct hash..."
158- echo "Attempting to realize derivation: ${DRV_PATH}"
159- REALISE_OUT=$(nix-store --realise "$DRV_PATH" --keep-failed 2>&1 | tee "$BUILD_LOG" || true)
66+ for SYSTEM in $SYSTEMS; do
67+ echo "Computing hash for ${SYSTEM}..."
68+ BUILD_LOG=$(mktemp)
69+ trap 'rm -f "$BUILD_LOG"' EXIT
16070
161- BUILD_PATH=$(echo "$REALISE_OUT" | grep "^/nix/store/" | head -n1 || true)
162- CORRECT_HASH=" "
71+ # The updater derivations use fakeHash, so they will fail and reveal the correct hash
72+ UPDATER_ATTR=".#packages.x86_64-linux.${SYSTEM}_node_modules "
16373
164- if [ -n "$BUILD_PATH" ] && [ -d "$BUILD_PATH" ]; then
165- echo "Realized node_modules output: $BUILD_PATH"
166- CORRECT_HASH=$(nix hash path --sri "$BUILD_PATH" 2>/dev/null || true)
167- fi
74+ nix build "$UPDATER_ATTR" --no-link 2>&1 | tee "$BUILD_LOG" || true
16875
169- # Try to extract hash from build log
170- if [ -z "$CORRECT_HASH" ]; then
17176 CORRECT_HASH="$(grep -E 'got:\s+sha256-[A-Za-z0-9+/=]+' "$BUILD_LOG" | awk '{print $2}' | head -n1 || true)"
172- fi
173-
174- if [ -z "$CORRECT_HASH" ]; then
175- CORRECT_HASH="$(grep -A2 'hash mismatch' "$BUILD_LOG" | grep 'got:' | awk '{print $2}' | sed 's/sha256:/sha256-/' || true)"
176- fi
17777
178- # Try to hash from kept failed build directory
179- if [ -z "$CORRECT_HASH" ]; then
180- KEPT_DIR=$(grep -oE "build directory.*'[^']+'" "$BUILD_LOG" | grep -oE "'/[^']+'" | tr -d "'" | head -n1 || true)
181- if [ -z "$KEPT_DIR" ]; then
182- KEPT_DIR=$(grep -oE '/nix/var/nix/builds/[^ ]+' "$BUILD_LOG" | head -n1 || true)
78+ if [ -z "$CORRECT_HASH" ]; then
79+ CORRECT_HASH="$(grep -A2 'hash mismatch' "$BUILD_LOG" | grep 'got:' | awk '{print $2}' | sed 's/sha256:/sha256-/' || true)"
18380 fi
18481
185- if [ -n "$KEPT_DIR" ] && [ -d "$KEPT_DIR" ]; then
186- HASH_PATH="$KEPT_DIR"
187- [ -d "$KEPT_DIR/build" ] && HASH_PATH="$KEPT_DIR/build"
188-
189- if [ -d "$HASH_PATH/node_modules" ]; then
190- CORRECT_HASH=$(nix hash path --sri "$HASH_PATH" 2>/dev/null || true)
191- fi
82+ if [ -z "$CORRECT_HASH" ]; then
83+ echo "Failed to determine correct node_modules hash for ${SYSTEM}."
84+ cat "$BUILD_LOG"
85+ exit 1
19286 fi
193- fi
194-
195- if [ -z "$CORRECT_HASH" ]; then
196- echo "Failed to determine correct node_modules hash for ${SYSTEM}."
197- cat "$BUILD_LOG"
198- exit 1
199- fi
20087
201- echo "$CORRECT_HASH" > "$OUTPUT_FILE"
202- echo "Hash for ${SYSTEM}: $CORRECT_HASH"
203-
204- - name : Upload hash artifact
205- uses : actions/upload-artifact@v6
206- with :
207- name : hash-${{ matrix.system }}
208- path : hash-${{ matrix.system }}.txt
209- retention-days : 1
210-
211- commit-node-modules-hashes :
212- needs : compute-node-modules-hash
213- if : github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
214- runs-on : blacksmith-4vcpu-ubuntu-2404
215- env :
216- TITLE : node_modules hashes
217-
218- steps :
219- - name : Checkout repository
220- uses : actions/checkout@v6
221- with :
222- token : ${{ secrets.GITHUB_TOKEN }}
223- fetch-depth : 0
224- ref : ${{ github.head_ref || github.ref_name }}
225- repository : ${{ github.event.pull_request.head.repo.full_name || github.repository }}
226-
227- - name : Configure git
228- run : |
229- git config --global user.email "[email protected] " 230- git config --global user.name "Github Action"
231-
232- - name : Pull latest changes
233- env :
234- TARGET_BRANCH : ${{ github.head_ref || github.ref_name }}
235- run : |
236- BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
237- git pull --rebase --autostash origin "$BRANCH"
238-
239- - name : Download all hash artifacts
240- uses : actions/download-artifact@v7
241- with :
242- pattern : hash-*
243- merge-multiple : true
244-
245- - name : Merge hashes into hashes.json
246- run : |
247- set -euo pipefail
248-
249- HASH_FILE="nix/hashes.json"
250-
251- if [ ! -f "$HASH_FILE" ]; then
252- mkdir -p "$(dirname "$HASH_FILE")"
253- echo '{"nodeModules":{}}' > "$HASH_FILE"
254- fi
255-
256- echo "Merging hashes into ${HASH_FILE}..."
257-
258- shopt -s nullglob
259- files=(hash-*.txt)
260- if [ ${#files[@]} -eq 0 ]; then
261- echo "No hash files found, nothing to update"
262- exit 0
263- fi
264-
265- EXPECTED_SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin"
266- for sys in $EXPECTED_SYSTEMS; do
267- if [ ! -f "hash-${sys}.txt" ]; then
268- echo "WARNING: Missing hash file for $sys"
269- fi
270- done
271-
272- for f in "${files[@]}"; do
273- system="${f#hash-}"
274- system="${system%.txt}"
275- hash=$(cat "$f")
276- if [ -z "$hash" ]; then
277- echo "WARNING: Empty hash for $system, skipping"
278- continue
279- fi
280- echo " $system: $hash"
281- jq --arg sys "$system" --arg h "$hash" \
282- '.nodeModules = (.nodeModules // {}) | .nodeModules[$sys] = $h' "$HASH_FILE" > "${HASH_FILE}.tmp"
88+ echo " ${SYSTEM}: ${CORRECT_HASH}"
89+ jq --arg sys "$SYSTEM" --arg h "$CORRECT_HASH" \
90+ '.nodeModules[$sys] = $h' "$HASH_FILE" > "${HASH_FILE}.tmp"
28391 mv "${HASH_FILE}.tmp" "$HASH_FILE"
28492 done
28593
286- echo "All hashes merged :"
94+ echo "All hashes computed :"
28795 cat "$HASH_FILE"
28896
28997 - name : Commit ${{ env.TITLE }} changes
0 commit comments