From c418a21b4c2d8efc1a7342d9e099839f7ec8f58f Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Sat, 16 May 2026 20:42:54 +0100 Subject: [PATCH] fix(ci): adopt canonical hypatia-scan.yml (env.HOME/scanner-layout + Comment-step gate) --- .github/workflows/hypatia-scan.yml | 40 +++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index a5b99ca..860a2b7 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -10,12 +10,26 @@ on: schedule: - cron: '0 0 * * 0' # Weekly on Sunday workflow_dispatch: +# Estate guardrail: cancel superseded runs so re-pushes don't pile up +# queued runs across the estate. Safe here because this workflow only +# performs read-only checks/lint/test/scan with no publish or mutation. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true permissions: contents: read # security-events: read lets the built-in GITHUB_TOKEN query this - # repo\'s own Dependabot alerts via the Hypatia DependabotAlerts rule. + # repo's own Dependabot alerts via the Hypatia DependabotAlerts rule + # (DA001-DA004). Without this, `scan_from_path` gets HTTP 403 and + # the rule silently returns no findings. + # See 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md. security-events: read + # pull-requests: write lets the advisory "Comment on PR with findings" + # step post its summary. Without it the built-in GITHUB_TOKEN gets + # "Resource not accessible by integration" and (absent continue-on-error) + # hard-fails the scan — exactly what the gate-decoupling design forbids. + pull-requests: write jobs: scan: @@ -24,7 +38,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Full history for better pattern analysis @@ -41,10 +55,10 @@ jobs: fi - name: Build Hypatia scanner (if needed) - working-directory: /home/runner/hypatia run: | - if [ ! -f hypatia ] && [ ! -f hypatia-v2 ]; then - echo "Building hypatia-v2 scanner..." + cd "$HOME/hypatia" + if [ ! -f hypatia ]; then + echo "Building hypatia scanner..." mix deps.get mix escript.build fi @@ -52,13 +66,16 @@ jobs: - name: Run Hypatia scan id: scan env: - # Suppress the Dependabot "GITHUB_TOKEN not set" warning. + # Pass the built-in Actions token through to Hypatia so the + # DependabotAlerts rule can query this repo's own alerts. + # For cross-repo scanning (fleet-coordinator scan-supervised), + # a PAT with `security_events` scope is required instead. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Scanning repository: ${{ github.repository }}" - # Run scanner - HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json + # Run scanner (exits non-zero when findings exist — suppress to continue) + HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json || true # Count findings FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0) @@ -199,7 +216,12 @@ jobs: - name: Comment on PR with findings if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0 - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + # Advisory only — posting findings as a PR comment must never gate + # the scan (hypatia#213 gate decoupling). Belt-and-braces alongside + # the pull-requests: write permission above: a token/API hiccup or + # a fork PR (read-only token) skips the comment, not the check. + continue-on-error: true + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7 with: script: | const fs = require('fs');