|
9 | 9 | - cron: '0 6 * * 1' # Weekly on Monday |
10 | 10 | workflow_dispatch: |
11 | 11 |
|
12 | | -permissions: read-all |
| 12 | +# Estate guardrail: cancel superseded runs so re-pushes / rebased PR |
| 13 | +# updates do not pile up queued runs against the shared account-wide |
| 14 | +# Actions concurrency pool. Applied only to read-only check workflows |
| 15 | +# (no publish/mutation), so cancelling a superseded run is always safe. |
| 16 | +concurrency: |
| 17 | + group: ${{ github.workflow }}-${{ github.ref }} |
| 18 | + cancel-in-progress: true |
| 19 | + |
| 20 | +permissions: |
| 21 | + contents: read |
13 | 22 |
|
14 | 23 | 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. |
15 | 34 | scorecard: |
16 | 35 | runs-on: ubuntu-latest |
17 | 36 | permissions: |
18 | 37 | security-events: write |
19 | 38 | id-token: write # For OIDC |
20 | 39 | steps: |
21 | | - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 |
| 40 | + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
22 | 41 | with: |
23 | 42 | persist-credentials: false |
24 | 43 |
|
25 | 44 | - name: Run Scorecard |
26 | | - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 |
| 45 | + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 |
27 | 46 | with: |
28 | 47 | results_file: results.sarif |
29 | 48 | results_format: sarif |
30 | 49 | publish_results: true |
31 | 50 |
|
32 | 51 | - name: Upload SARIF |
33 | | - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3 |
| 52 | + uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v4 |
34 | 53 | with: |
35 | 54 | sarif_file: results.sarif |
36 | 55 |
|
| 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 |
| 62 | + |
| 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 |
| 73 | + |
37 | 74 | - name: Check minimum score |
38 | 75 | run: | |
39 | | - # Parse score from results |
40 | 76 | SCORE=$(jq -r '.runs[0].tool.driver.properties.score // 0' results.sarif 2>/dev/null || echo "0") |
41 | 77 |
|
42 | 78 | echo "OpenSSF Scorecard Score: $SCORE" |
|
53 | 89 | check-critical: |
54 | 90 | runs-on: ubuntu-latest |
55 | 91 | steps: |
56 | | - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 |
| 92 | + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
57 | 93 |
|
58 | 94 | - name: Check SECURITY.md exists |
59 | 95 | run: | |
|
0 commit comments