Skip to content

Commit b33a572

Browse files
ci(scorecard-enforcer): split score-threshold from publish job (#24)
Replace local copy with the post-#304 standards template. The pre-fix shape has the OSSF publish contract violation: webapp: scorecard job must only have steps with uses Post-fix shape: - `scorecard` job: uses-only (now includes upload-artifact for SARIF hand-off) - `check-score` job: `needs: scorecard`, downloads artifact, runs threshold gate Caught 49 estate repos on the 2026-05-30 audit. Detector: hypatia rule WF014. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d90c572 commit b33a572

1 file changed

Lines changed: 31 additions & 27 deletions

File tree

.github/workflows/scorecard-enforcer.yml

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ permissions:
2121
contents: read
2222

2323
jobs:
24+
# The OSSF Scorecard publish endpoint enforces a hard contract: the job that
25+
# runs `ossf/scorecard-action` with `publish_results: true` must contain
26+
# ONLY steps with `uses:` (no `run:` steps in the same job). If a `run:`
27+
# step is present, the publish step fails with:
28+
# "webapp: scorecard job must only have steps with uses"
29+
# (49 estate repos hit this; see ROADMAP audit 2026-05-30.)
30+
#
31+
# Fix: split the threshold check into a downstream job that depends on
32+
# `scorecard` and consumes the SARIF artifact. The `scorecard` job stays
33+
# uses-only; `check-score` is the gating job that emits the error.
2434
scorecard:
2535
runs-on: ubuntu-latest
2636
permissions:
@@ -36,47 +46,41 @@ jobs:
3646
with:
3747
results_file: results.sarif
3848
results_format: sarif
39-
# The Scorecard publish endpoint requires the job to contain only
40-
# `uses` steps. This workflow also uploads SARIF and checks the score,
41-
# so keep publication disabled and rely on the SARIF upload below.
42-
publish_results: false
49+
publish_results: true
4350

4451
- name: Upload SARIF
4552
uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v4
4653
with:
4754
sarif_file: results.sarif
4855

49-
- name: Check minimum score
50-
run: |
51-
set -euo pipefail
52-
53-
# Scorecard's SARIF output is useful for code scanning, but some
54-
# versions do not expose an aggregate score in SARIF. Treat missing
55-
# score metadata as "not enforceable" instead of a false zero.
56-
SCORE="$(jq -r '
57-
.runs[0].invocations[0].properties.score //
58-
.runs[0].tool.driver.properties.score //
59-
empty
60-
' results.sarif 2>/dev/null || true)"
56+
- name: Persist SARIF for downstream score-gate job
57+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
58+
with:
59+
name: scorecard-results
60+
path: results.sarif
61+
retention-days: 1
6162

62-
if [ -z "$SCORE" ] || [ "$SCORE" = "null" ]; then
63-
echo "::warning::OpenSSF Scorecard SARIF did not expose an aggregate score; SARIF upload succeeded, skipping numeric threshold."
64-
exit 0
65-
fi
63+
check-score:
64+
needs: scorecard
65+
runs-on: ubuntu-latest
66+
permissions:
67+
contents: read
68+
steps:
69+
- name: Download SARIF from scorecard job
70+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5.0.0
71+
with:
72+
name: scorecard-results
6673

67-
case "$SCORE" in
68-
''|*[!0-9.]*)
69-
echo "::warning::OpenSSF Scorecard score '$SCORE' is not numeric; skipping numeric threshold."
70-
exit 0
71-
;;
72-
esac
74+
- name: Check minimum score
75+
run: |
76+
SCORE=$(jq -r '.runs[0].tool.driver.properties.score // 0' results.sarif 2>/dev/null || echo "0")
7377
7478
echo "OpenSSF Scorecard Score: $SCORE"
7579
7680
# Minimum acceptable score (0-10 scale)
7781
MIN_SCORE=5
7882
79-
if awk -v score="$SCORE" -v min="$MIN_SCORE" 'BEGIN { exit !(score < min) }'; then
83+
if [ "$(echo "$SCORE < $MIN_SCORE" | bc -l)" = "1" ]; then
8084
echo "::error::Scorecard score $SCORE is below minimum $MIN_SCORE"
8185
exit 1
8286
fi

0 commit comments

Comments
 (0)