From d3f61c70536caa3e721ec539719ec20d7ad552c0 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 21 Jul 2026 13:22:15 +0100 Subject: [PATCH] fix(ci): add SPDX header to pages.yml; remove retired scorecard-enforcer.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two of the governance gate's failures, both surfaced only after the repository's Actions policy was fixed (the workflows previously startup_failure'd before any job could run). Workflow security linter ERROR: .github/workflows/pages.yml missing SPDX header pages.yml is the active Ddraig SSG docs deploy added in #288; it was the only workflow of 26 without the header. Added, matching the form used by proofs.yml. Not deleted — it is live, and pages-deploy.yml is a different thing (Cloudflare Workers, not GitHub Pages). Check Workflow Staleness ERROR: scorecard-enforcer.yml is retired. Use scorecard.yml -> standards scorecard-reusable.yml instead. Removed. The replacement scorecard.yml is present. This also clears the separate `OpenSSF Scorecard Enforcer` run failure. Confirmed safe to delete: the Base ruleset (14285163) requires only `Dependabot`, `Hypatia Neurosymbolic Analysis` and `Hypatia`, so removing this workflow cannot strand a PR on a permanently-"Expected" required check. Deliberately NOT addressed here — the staleness gate's two remaining complaints both concern shared CI fate and want coordination, not a drive-by fix: - governance-reusable.yml / scorecard-reusable.yml pin d135b05bfc64 is 75 commits / 26d behind standards HEAD (refresh toward 8813ecf2a841). Re-pinning consumers changes behaviour estate-wide, and at least one reusable (secret-scanner) is known not to inherit its config to callers. - OSSF Scorecard uploading SARIF to Code Scanning while not running for every PR head commit. Verified locally by replicating the linter's own check across all 25 remaining workflows: every one carries an SPDX header and a top-level `permissions:`. pages.yml still parses as valid YAML. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/pages.yml | 5 + .github/workflows/scorecard-enforcer.yml | 124 ----------------------- 2 files changed, 5 insertions(+), 124 deletions(-) delete mode 100644 .github/workflows/scorecard-enforcer.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 649dcb1a..6168232d 100755 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# GitHub Pages docs deploy via the Ddraig SSG (#288). + name: GitHub Pages (Ddraig SSG) on: push: diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml deleted file mode 100644 index 86d81735..00000000 --- a/.github/workflows/scorecard-enforcer.yml +++ /dev/null @@ -1,124 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell -# -# Prevention workflow - runs OpenSSF Scorecard and fails on low scores. -# -# Split into TWO jobs to satisfy the OSSF Scorecard webapp's workflow -# restriction: -# "scorecard job must only have steps with `uses`" -# (https://github.com/ossf/scorecard-action#workflow-restrictions). -# -# When the publishing job contains a `run:` step, the webapp rejects -# the signed-result POST with HTTP 400 "workflow verification failed". -# That regression had this workflow `failure`-state ever since -# `publish_results: true` was added — the score *was* computed, but -# the webapp publish step failed and propagated to job-level failure. -# -# Job 1 (`scorecard`): uses-only steps. Computes the score, publishes -# signed results to the OSSF webapp, uploads SARIF to GitHub code -# scanning, and saves results.sarif as an artifact for Job 2. -# -# Job 2 (`enforce-min-score`): downloads the artifact and runs the -# minimum-score gate. May contain `run:` steps freely — it does not -# call scorecard-action. -# -# Sister fix landed in hyperpolymath/ephapax#264 (2026-06-01); this -# PR mirrors it so the two repos stay in sync. - -name: OpenSSF Scorecard Enforcer - -on: - push: - branches: [main] - schedule: - - cron: '0 6 * * 1' # Weekly on Monday - workflow_dispatch: - -# Estate guardrail: cancel superseded runs so re-pushes / rebased PR -# updates do not pile up queued runs against the shared account-wide -# Actions concurrency pool. Applied only to read-only check workflows -# (no publish/mutation), so cancelling a superseded run is always safe. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - scorecard: - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - security-events: write - id-token: write # For OIDC - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Run Scorecard - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 - with: - results_file: results.sarif - results_format: sarif - publish_results: true - - - name: Upload SARIF - uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v4 - with: - sarif_file: results.sarif - - - name: Upload results artifact for min-score gate - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 - with: - name: scorecard-results - path: results.sarif - retention-days: 7 - - enforce-min-score: - needs: scorecard - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Download results artifact - uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 - with: - name: scorecard-results - - - name: Check minimum score - run: | - # Parse score from SARIF results. - SCORE=$(jq -r '.runs[0].tool.driver.properties.score // 0' results.sarif 2>/dev/null || echo "0") - - echo "OpenSSF Scorecard Score: $SCORE" - - # Minimum acceptable score (0-10 scale). - MIN_SCORE=5 - - if [ "$(echo "$SCORE < $MIN_SCORE" | bc -l)" = "1" ]; then - echo "::error::Scorecard score $SCORE is below minimum $MIN_SCORE" - exit 1 - fi - - # Check specific high-priority items - check-critical: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Check SECURITY.md exists - run: | - if [ ! -f "SECURITY.md" ]; then - echo "::error::SECURITY.md is required" - exit 1 - fi - - - name: Check for pinned dependencies - run: | - # Check workflows for unpinned actions - unpinned=$(grep -r "uses:.*@v[0-9]" .github/workflows/*.yml 2>/dev/null | grep -v "#" | head -5 || true) - if [ -n "$unpinned" ]; then - echo "::warning::Found unpinned actions:" - echo "$unpinned" - fi