From caccfad7b6e797d4ed9f2d4bf579f28387099054 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Sat, 8 Aug 2026 13:17:15 -0500 Subject: [PATCH 1/5] chore: stage macOS Nix daemon readiness hardening --- .../apply-macos-nix-daemon-readiness.yml | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/apply-macos-nix-daemon-readiness.yml diff --git a/.github/workflows/apply-macos-nix-daemon-readiness.yml b/.github/workflows/apply-macos-nix-daemon-readiness.yml new file mode 100644 index 00000000..feb04ef5 --- /dev/null +++ b/.github/workflows/apply-macos-nix-daemon-readiness.yml @@ -0,0 +1,93 @@ +name: apply macOS Nix daemon readiness hardening + +on: + push: + branches: + - fix/macos-nix-daemon-readiness + +permissions: + contents: write + +concurrency: + group: macos-nix-daemon-readiness-materializer + cancel-in-progress: true + +jobs: + apply: + if: github.actor != 'github-actions[bot]' + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - name: Check out repair branch + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: fix/macos-nix-daemon-readiness + fetch-depth: 0 + persist-credentials: true + show-progress: false + + - name: Add bounded Nix daemon readiness probe + shell: bash + run: | + set -euo pipefail + python3 - <<'PY' + from pathlib import Path + + path = Path('.github/workflows/nix-interop.yml') + text = path.read_text(encoding='utf-8') + anchor = ''' - name: Load the locked Nixpkgs input + ''' + readiness = ''' - name: Wait for the Nix store to become ready + shell: bash + run: | + set -euo pipefail + if [[ "$RUNNER_OS" != "macOS" ]]; then + nix store ping + exit 0 + fi + + for attempt in $(seq 1 20); do + if NIX_REMOTE=daemon nix store ping >/dev/null 2>&1; then + printf 'NIX_REMOTE=daemon\\n' >> "$GITHUB_ENV" + exit 0 + fi + echo "Nix daemon is not ready yet (attempt ${attempt}/20)" >&2 + sudo launchctl kickstart -k system/org.nixos.nix-daemon >/dev/null 2>&1 || true + sleep 2 + done + + sudo launchctl print system/org.nixos.nix-daemon || true + ls -la /nix/var/nix/daemon-socket || true + echo "Nix daemon did not become ready" >&2 + exit 1 + + - name: Load the locked Nixpkgs input + ''' + if 'name: Wait for the Nix store to become ready' not in text: + if text.count(anchor) != 1: + raise SystemExit(f'expected one locked-input step anchor, found {text.count(anchor)}') + text = text.replace(anchor, readiness, 1) + path.write_text(text, encoding='utf-8') + PY + + python3 - <<'PY' + from pathlib import Path + text = Path('.github/workflows/nix-interop.yml').read_text(encoding='utf-8') + assert text.count('name: Wait for the Nix store to become ready') == 1 + assert 'NIX_REMOTE=daemon nix store ping' in text + assert 'launchctl kickstart -k system/org.nixos.nix-daemon' in text + PY + git diff --check + + - name: Commit the permanent workflow repair + shell: bash + run: | + set -euo pipefail + rm .github/workflows/apply-macos-nix-daemon-readiness.yml + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + git add .github/workflows/nix-interop.yml \ + .github/workflows/apply-macos-nix-daemon-readiness.yml + git diff --cached --check + git commit -m 'fix: wait for the macOS Nix daemon before evaluation' + git push origin HEAD:fix/macos-nix-daemon-readiness From 87e9f123e960a7e2a2453de44c14cb49e306d313 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Sat, 8 Aug 2026 13:21:09 -0500 Subject: [PATCH 2/5] ci: materialize Nix daemon readiness on Windows --- .../apply-macos-nix-daemon-readiness.yml | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/.github/workflows/apply-macos-nix-daemon-readiness.yml b/.github/workflows/apply-macos-nix-daemon-readiness.yml index feb04ef5..62a4b88d 100644 --- a/.github/workflows/apply-macos-nix-daemon-readiness.yml +++ b/.github/workflows/apply-macos-nix-daemon-readiness.yml @@ -12,10 +12,14 @@ concurrency: group: macos-nix-daemon-readiness-materializer cancel-in-progress: true +defaults: + run: + shell: bash + jobs: apply: if: github.actor != 'github-actions[bot]' - runs-on: ubuntu-24.04 + runs-on: windows-2025 timeout-minutes: 10 steps: - name: Check out repair branch @@ -27,42 +31,42 @@ jobs: show-progress: false - name: Add bounded Nix daemon readiness probe - shell: bash run: | set -euo pipefail - python3 - <<'PY' + python - <<'PY' from pathlib import Path path = Path('.github/workflows/nix-interop.yml') text = path.read_text(encoding='utf-8') - anchor = ''' - name: Load the locked Nixpkgs input - ''' - readiness = ''' - name: Wait for the Nix store to become ready - shell: bash - run: | - set -euo pipefail - if [[ "$RUNNER_OS" != "macOS" ]]; then - nix store ping - exit 0 - fi - - for attempt in $(seq 1 20); do - if NIX_REMOTE=daemon nix store ping >/dev/null 2>&1; then - printf 'NIX_REMOTE=daemon\\n' >> "$GITHUB_ENV" - exit 0 - fi - echo "Nix daemon is not ready yet (attempt ${attempt}/20)" >&2 - sudo launchctl kickstart -k system/org.nixos.nix-daemon >/dev/null 2>&1 || true - sleep 2 - done - - sudo launchctl print system/org.nixos.nix-daemon || true - ls -la /nix/var/nix/daemon-socket || true - echo "Nix daemon did not become ready" >&2 - exit 1 - - - name: Load the locked Nixpkgs input - ''' + anchor = ' - name: Load the locked Nixpkgs input\n' + readiness = '\n'.join([ + ' - name: Wait for the Nix store to become ready', + ' shell: bash', + ' run: |', + ' set -euo pipefail', + ' if [[ "$RUNNER_OS" != "macOS" ]]; then', + ' nix store ping', + ' exit 0', + ' fi', + '', + ' for attempt in $(seq 1 20); do', + ' if NIX_REMOTE=daemon nix store ping >/dev/null 2>&1; then', + " printf 'NIX_REMOTE=daemon\\n' >> \"$GITHUB_ENV\"", + ' exit 0', + ' fi', + ' echo "Nix daemon is not ready yet (attempt ${attempt}/20)" >&2', + ' sudo launchctl kickstart -k system/org.nixos.nix-daemon >/dev/null 2>&1 || true', + ' sleep 2', + ' done', + '', + ' sudo launchctl print system/org.nixos.nix-daemon || true', + ' ls -la /nix/var/nix/daemon-socket || true', + ' echo "Nix daemon did not become ready" >&2', + ' exit 1', + '', + ' - name: Load the locked Nixpkgs input', + '', + ]) if 'name: Wait for the Nix store to become ready' not in text: if text.count(anchor) != 1: raise SystemExit(f'expected one locked-input step anchor, found {text.count(anchor)}') @@ -70,17 +74,17 @@ jobs: path.write_text(text, encoding='utf-8') PY - python3 - <<'PY' + python - <<'PY' from pathlib import Path text = Path('.github/workflows/nix-interop.yml').read_text(encoding='utf-8') assert text.count('name: Wait for the Nix store to become ready') == 1 assert 'NIX_REMOTE=daemon nix store ping' in text assert 'launchctl kickstart -k system/org.nixos.nix-daemon' in text + assert text.count('name: Load the locked Nixpkgs input') == 1 PY git diff --check - name: Commit the permanent workflow repair - shell: bash run: | set -euo pipefail rm .github/workflows/apply-macos-nix-daemon-readiness.yml From d11142ad51eb21709e2451457a299763e9da5207 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Sat, 8 Aug 2026 13:23:17 -0500 Subject: [PATCH 3/5] ci: materialize Nix daemon readiness on macOS --- .github/workflows/apply-macos-nix-daemon-readiness.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/apply-macos-nix-daemon-readiness.yml b/.github/workflows/apply-macos-nix-daemon-readiness.yml index 62a4b88d..d433e783 100644 --- a/.github/workflows/apply-macos-nix-daemon-readiness.yml +++ b/.github/workflows/apply-macos-nix-daemon-readiness.yml @@ -19,7 +19,7 @@ defaults: jobs: apply: if: github.actor != 'github-actions[bot]' - runs-on: windows-2025 + runs-on: macos-15 timeout-minutes: 10 steps: - name: Check out repair branch @@ -33,7 +33,7 @@ jobs: - name: Add bounded Nix daemon readiness probe run: | set -euo pipefail - python - <<'PY' + python3 - <<'PY' from pathlib import Path path = Path('.github/workflows/nix-interop.yml') @@ -74,7 +74,7 @@ jobs: path.write_text(text, encoding='utf-8') PY - python - <<'PY' + python3 - <<'PY' from pathlib import Path text = Path('.github/workflows/nix-interop.yml').read_text(encoding='utf-8') assert text.count('name: Wait for the Nix store to become ready') == 1 From bf8466d9519a910377154be4397f2eeb47f6f737 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Sat, 8 Aug 2026 13:25:23 -0500 Subject: [PATCH 4/5] fix: wait for the macOS Nix daemon before evaluation --- .github/workflows/nix-interop.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nix-interop.yml b/.github/workflows/nix-interop.yml index 750aec90..850cdeae 100644 --- a/.github/workflows/nix-interop.yml +++ b/.github/workflows/nix-interop.yml @@ -51,6 +51,30 @@ jobs: experimental-features = nix-command flakes accept-flake-config = false + - name: Wait for the Nix store to become ready + shell: bash + run: | + set -euo pipefail + if [[ "$RUNNER_OS" != "macOS" ]]; then + nix store ping + exit 0 + fi + + for attempt in $(seq 1 20); do + if NIX_REMOTE=daemon nix store ping >/dev/null 2>&1; then + printf 'NIX_REMOTE=daemon\n' >> "$GITHUB_ENV" + exit 0 + fi + echo "Nix daemon is not ready yet (attempt ${attempt}/20)" >&2 + sudo launchctl kickstart -k system/org.nixos.nix-daemon >/dev/null 2>&1 || true + sleep 2 + done + + sudo launchctl print system/org.nixos.nix-daemon || true + ls -la /nix/var/nix/daemon-socket || true + echo "Nix daemon did not become ready" >&2 + exit 1 + - name: Load the locked Nixpkgs input shell: bash run: | @@ -308,7 +332,7 @@ jobs: flags=re.MULTILINE, ) if count != 1: - raise SystemExit("expected one locked artifact sha256 to tamper") + raise SystemExit("expected one locked artifact sha256 to tamper") path.write_text(text, encoding="utf-8") PY From 55fd623730272f249f54fd614c1a3a79269dff2b Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Sat, 8 Aug 2026 13:25:33 -0500 Subject: [PATCH 5/5] chore: remove completed Nix readiness materializer --- .../apply-macos-nix-daemon-readiness.yml | 97 ------------------- 1 file changed, 97 deletions(-) delete mode 100644 .github/workflows/apply-macos-nix-daemon-readiness.yml diff --git a/.github/workflows/apply-macos-nix-daemon-readiness.yml b/.github/workflows/apply-macos-nix-daemon-readiness.yml deleted file mode 100644 index d433e783..00000000 --- a/.github/workflows/apply-macos-nix-daemon-readiness.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: apply macOS Nix daemon readiness hardening - -on: - push: - branches: - - fix/macos-nix-daemon-readiness - -permissions: - contents: write - -concurrency: - group: macos-nix-daemon-readiness-materializer - cancel-in-progress: true - -defaults: - run: - shell: bash - -jobs: - apply: - if: github.actor != 'github-actions[bot]' - runs-on: macos-15 - timeout-minutes: 10 - steps: - - name: Check out repair branch - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: fix/macos-nix-daemon-readiness - fetch-depth: 0 - persist-credentials: true - show-progress: false - - - name: Add bounded Nix daemon readiness probe - run: | - set -euo pipefail - python3 - <<'PY' - from pathlib import Path - - path = Path('.github/workflows/nix-interop.yml') - text = path.read_text(encoding='utf-8') - anchor = ' - name: Load the locked Nixpkgs input\n' - readiness = '\n'.join([ - ' - name: Wait for the Nix store to become ready', - ' shell: bash', - ' run: |', - ' set -euo pipefail', - ' if [[ "$RUNNER_OS" != "macOS" ]]; then', - ' nix store ping', - ' exit 0', - ' fi', - '', - ' for attempt in $(seq 1 20); do', - ' if NIX_REMOTE=daemon nix store ping >/dev/null 2>&1; then', - " printf 'NIX_REMOTE=daemon\\n' >> \"$GITHUB_ENV\"", - ' exit 0', - ' fi', - ' echo "Nix daemon is not ready yet (attempt ${attempt}/20)" >&2', - ' sudo launchctl kickstart -k system/org.nixos.nix-daemon >/dev/null 2>&1 || true', - ' sleep 2', - ' done', - '', - ' sudo launchctl print system/org.nixos.nix-daemon || true', - ' ls -la /nix/var/nix/daemon-socket || true', - ' echo "Nix daemon did not become ready" >&2', - ' exit 1', - '', - ' - name: Load the locked Nixpkgs input', - '', - ]) - if 'name: Wait for the Nix store to become ready' not in text: - if text.count(anchor) != 1: - raise SystemExit(f'expected one locked-input step anchor, found {text.count(anchor)}') - text = text.replace(anchor, readiness, 1) - path.write_text(text, encoding='utf-8') - PY - - python3 - <<'PY' - from pathlib import Path - text = Path('.github/workflows/nix-interop.yml').read_text(encoding='utf-8') - assert text.count('name: Wait for the Nix store to become ready') == 1 - assert 'NIX_REMOTE=daemon nix store ping' in text - assert 'launchctl kickstart -k system/org.nixos.nix-daemon' in text - assert text.count('name: Load the locked Nixpkgs input') == 1 - PY - git diff --check - - - name: Commit the permanent workflow repair - run: | - set -euo pipefail - rm .github/workflows/apply-macos-nix-daemon-readiness.yml - git config user.name 'github-actions[bot]' - git config user.email '41898282+github-actions[bot]@users.noreply.github.com' - git add .github/workflows/nix-interop.yml \ - .github/workflows/apply-macos-nix-daemon-readiness.yml - git diff --cached --check - git commit -m 'fix: wait for the macOS Nix daemon before evaluation' - git push origin HEAD:fix/macos-nix-daemon-readiness