From 1564b6b27e23b1b705822e2ec03a9db0fa78fdcc Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 2 Jun 2026 20:40:11 +0100 Subject: [PATCH] fix(ci): skip SARIF upload when code scanning is administratively disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a consumer of `hypatia-scan-reusable.yml` is a private repo without GitHub Advanced Security (or any repo with code scanning admin-disabled), `codeql-action/upload-sarif` fails with "Code scanning is not enabled for this repository". That's a legitimate consumer-side config choice, not a regression — the reusable should skip rather than hard-fail. Approach: add a `cs-probe` step that queries `/code-scanning/alerts` (continue-on-error so the probe itself never blocks) and gates the upload-sarif step on the probe's verdict. Preserved guarantees (per the existing design comment on this step, post-#35): - Fork PRs still skip (token read-only). - Genuine permission regression / malformed SARIF / API outage still hard-fail loud — the probe checks ONLY whether the feature is enabled, not whether the upload would otherwise succeed. Reproducing failure: hyperpolymath/.git-private-farm#69 run 26843343488 fails on "Code scanning is not enabled" AFTER the scan + SARIF conversion both succeed and the `actions: read` perm I added in #352 correctly grants the upload its needed scope. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/hypatia-scan-reusable.yml | 41 ++++++++++++++++----- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/.github/workflows/hypatia-scan-reusable.yml b/.github/workflows/hypatia-scan-reusable.yml index 710fd97b..69b1cd4b 100644 --- a/.github/workflows/hypatia-scan-reusable.yml +++ b/.github/workflows/hypatia-scan-reusable.yml @@ -281,18 +281,41 @@ jobs: CJS node "$RUNNER_TEMP/hypatia-sarif.cjs" + - name: Probe code scanning availability + # Private repos without GitHub Advanced Security (and any repo with + # code scanning administratively disabled) reject upload-sarif with + # "Code scanning is not enabled for this repository". That's a + # legitimate consumer-side config choice, not a regression — skip + # rather than hard-fail. The empty 200 from /code-scanning/alerts + # means the feature is enabled and queryable; any non-2xx means it + # is not. + id: cs-probe + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + run: | + set -uo pipefail + if gh api "repos/${GITHUB_REPOSITORY}/code-scanning/alerts" --jq 'length' >/dev/null 2>&1; then + echo "enabled=true" >> "$GITHUB_OUTPUT" + else + echo "enabled=false" >> "$GITHUB_OUTPUT" + echo "::notice::Code scanning is not enabled on ${GITHUB_REPOSITORY}; SARIF upload will be skipped. Hypatia findings still land as a build artifact." + fi + - name: Upload SARIF to GitHub code scanning - # Fork PRs get a read-only GITHUB_TOKEN, so security-events:write - # is unavailable and upload-sarif cannot publish — skip there - # rather than hard-fail (the push/schedule run on the default - # branch is the authoritative upload). Same-repo PRs and pushes - # do upload. This step is deliberately NOT continue-on-error: - # if the security-surface integration breaks we want a loud red, - # not a silently-ungated scanner (the exact failure mode #35 - # exists to end). The empty-SARIF "clear stale alerts" path is - # handled in the converter above and does not error here. + # Skipped on three legitimate paths: + # 1. Fork PRs — GITHUB_TOKEN is read-only, security-events:write + # unavailable, upload-sarif cannot publish. Push/schedule on + # the default branch is the authoritative upload. + # 2. Code scanning administratively disabled — private repo + # without Advanced Security, or owner-disabled feature. + # 3. The reusable still hard-fails on every OTHER error mode + # (genuine permission regression, malformed SARIF, API outage), + # so a silently-ungated scanner is still loud — exactly the + # failure mode #35 exists to end. if: >- always() && + steps.cs-probe.outputs.enabled == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork != true) uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1