From 577eeceac4b5d7b008e0172985c9ee504fecc824 Mon Sep 17 00:00:00 2001 From: Marc Mandel Date: Fri, 3 Jul 2026 18:01:31 -0400 Subject: [PATCH 1/4] ci: run workflows on the self-hosted local macOS runner Registered this machine as a repo-scoped self-hosted GitHub Actions runner (labels: self-hosted, macOS, ARM64, marcut-local) rather than using GitHub-hosted macos-14 runners, per user preference. Points all three workflows (ci.yml, macos-build-verify.yml, macos-full-e2e.yml) at [self-hosted, marcut-local]. Note: self-hosted runners execute arbitrary code from workflow-triggering events on this machine. This repo's branch protection (PR + 1 approval + code-owner review required, no bypass actors) limits triggering to trusted collaborators, but this is worth keeping in mind if the repo's contributor model ever changes. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/ci.yml | 2 +- .github/workflows/macos-build-verify.yml | 2 +- .github/workflows/macos-full-e2e.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75d28c7..97ba7f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: jobs: smoke: - runs-on: macos-14 + runs-on: [self-hosted, marcut-local] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/macos-build-verify.yml b/.github/workflows/macos-build-verify.yml index 972c5be..8e0cce4 100644 --- a/.github/workflows/macos-build-verify.yml +++ b/.github/workflows/macos-build-verify.yml @@ -8,7 +8,7 @@ on: jobs: build-verify: - runs-on: macos-14 + runs-on: [self-hosted, marcut-local] timeout-minutes: 15 steps: - name: Checkout diff --git a/.github/workflows/macos-full-e2e.yml b/.github/workflows/macos-full-e2e.yml index 453e9cb..725423e 100644 --- a/.github/workflows/macos-full-e2e.yml +++ b/.github/workflows/macos-full-e2e.yml @@ -8,7 +8,7 @@ on: jobs: full-e2e: - runs-on: macos-14 + runs-on: [self-hosted, marcut-local] timeout-minutes: 30 env: MACOS_CERT_P12_BASE64: ${{ secrets.MACOS_CERT_P12_BASE64 }} From cd1ab7d831ec17292a538222403cb23e26023f54 Mon Sep 17 00:00:00 2001 From: Marc Mandel Date: Fri, 3 Jul 2026 18:05:51 -0400 Subject: [PATCH 2/4] fix: use the runner's own python3.11 instead of actions/setup-python actions/setup-python@v5's macOS install path hardcodes /Users/runner for its hostedtoolcache, which only exists on GitHub-hosted runners (which literally run as a user named "runner"). On this self-hosted runner (running as a different user), that step failed immediately with "mkdir: /Users/runner: Permission denied", regardless of RUNNER_TOOL_CACHE. Self-hosted runners are expected to bring their own toolchain rather than relying on ephemeral-runner setup actions. python3.11 is already installed on this machine (Homebrew) -- both workflows now use it directly instead of going through actions/setup-python. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/ci.yml | 18 ++++++++---------- .github/workflows/macos-build-verify.yml | 18 ++++++++---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 97ba7f3..273d895 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,22 +13,20 @@ jobs: uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" + run: python3.11 --version - name: Install Python dependencies run: | - python -m pip install -U pip - pip install -e . - pip install pytest - python scripts/check_dependency_vulnerabilities.py requirements-pinned.txt - python scripts/generate_python_sbom.py --check - python scripts/check_markdown_links.py + python3.11 -m pip install -U pip + python3.11 -m pip install -e . + python3.11 -m pip install pytest + python3.11 scripts/check_dependency_vulnerabilities.py requirements-pinned.txt + python3.11 scripts/generate_python_sbom.py --check + python3.11 scripts/check_markdown_links.py - name: Python smoke tests (rules-only) run: | - pytest -q tests/test_rules.py tests/test_rule_filter.py + python3.11 -m pytest -q tests/test_rules.py tests/test_rule_filter.py - name: Swift build (compile-only) run: | diff --git a/.github/workflows/macos-build-verify.yml b/.github/workflows/macos-build-verify.yml index 8e0cce4..19bd2b6 100644 --- a/.github/workflows/macos-build-verify.yml +++ b/.github/workflows/macos-build-verify.yml @@ -15,19 +15,17 @@ jobs: uses: actions/checkout@v4 - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: '3.11' + run: python3.11 --version - name: Install Python deps + tests run: | - python -m pip install -U pip - pip install -e . - pip install pytest - python scripts/check_dependency_vulnerabilities.py requirements-pinned.txt - python scripts/generate_python_sbom.py --check - python scripts/check_markdown_links.py - pytest -q + python3.11 -m pip install -U pip + python3.11 -m pip install -e . + python3.11 -m pip install pytest + python3.11 scripts/check_dependency_vulnerabilities.py requirements-pinned.txt + python3.11 scripts/generate_python_sbom.py --check + python3.11 scripts/check_markdown_links.py + python3.11 -m pytest -q - name: Prepare stub Ollama for packaging run: | From e786f083ff69eca74800dd3b65f95f1447676f87 Mon Sep 17 00:00:00 2001 From: Marc Mandel Date: Fri, 3 Jul 2026 18:13:54 -0400 Subject: [PATCH 3/4] diag: add temporary network diagnostics step to isolate runner hang --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 273d895..015fa7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,13 @@ jobs: - name: Set up Python run: python3.11 --version + - name: Network diagnostics + run: | + echo "scutil dns:"; scutil --dns | head -20 + echo "resolv.conf:"; cat /etc/resolv.conf + echo "curl pypi (5s timeout):"; curl -sS -m 5 -o /dev/null -w "http_code=%{http_code} time=%{time_total}\n" https://pypi.org || echo "curl FAILED rc=$?" + echo "dns lookup:"; (dscacheutil -q host -a name pypi.org &) ; sleep 3; echo done + - name: Install Python dependencies run: | python3.11 -m pip install -U pip From 349b3dcb3426690d778538a71bf4f7de4780dfd5 Mon Sep 17 00:00:00 2001 From: Marc Mandel Date: Fri, 3 Jul 2026 18:17:01 -0400 Subject: [PATCH 4/4] diag: capture verbose pip output with self-timeout to isolate hang point --- .github/workflows/ci.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 015fa7e..bbe3049 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,24 @@ jobs: - name: Network diagnostics run: | - echo "scutil dns:"; scutil --dns | head -20 - echo "resolv.conf:"; cat /etc/resolv.conf - echo "curl pypi (5s timeout):"; curl -sS -m 5 -o /dev/null -w "http_code=%{http_code} time=%{time_total}\n" https://pypi.org || echo "curl FAILED rc=$?" - echo "dns lookup:"; (dscacheutil -q host -a name pypi.org &) ; sleep 3; echo done + echo "curl pypi.org:"; curl -sS -m 5 -o /dev/null -w "http_code=%{http_code} time=%{time_total}\n" https://pypi.org || echo "curl FAILED rc=$?" + echo "curl files.pythonhosted.org:"; curl -sS -m 5 -o /dev/null -w "http_code=%{http_code} time=%{time_total}\n" https://files.pythonhosted.org || echo "curl FAILED rc=$?" + echo "curl pypi simple index for pip:"; curl -sS -m 5 -o /dev/null -w "http_code=%{http_code} time=%{time_total}\n" https://pypi.org/simple/pip/ || echo "curl FAILED rc=$?" + echo "--- pip install -v -U pip with 15s self-timeout ---" + python3.11 -m pip install -v -U pip > /tmp/pip_verbose.log 2>&1 & + PIPPID=$! + for i in $(seq 1 15); do + if ! kill -0 $PIPPID 2>/dev/null; then break; fi + sleep 1 + done + if kill -0 $PIPPID 2>/dev/null; then + echo "PIP STILL RUNNING AFTER 15s -- killing and dumping log" + kill -9 $PIPPID + else + echo "pip completed within 15s" + fi + echo "--- last 40 lines of verbose pip log ---" + tail -40 /tmp/pip_verbose.log - name: Install Python dependencies run: |