Skip to content

ci: CI hardening + Scorecard (#14)#61

Merged
DocGerd merged 1 commit into
mainfrom
feat/14-ci-hardening
Jul 17, 2026
Merged

ci: CI hardening + Scorecard (#14)#61
DocGerd merged 1 commit into
mainfrom
feat/14-ci-hardening

Conversation

@DocGerd

@DocGerd DocGerd commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Closes #14

Hardening moves on ci.yml / deploy.yml

  • Least-privilege permissions: top-level permissions: contents: read on both workflows; deploy.yml only elevates (pages: write, id-token: write) on the deploy job, not the build job.
  • Concurrency: ci.yml cancels superseded runs on PRs only (cancel-in-progress: ${{ github.event_name == 'pull_request' }}) — pushes to main always run to completion. deploy.yml keeps its existing pages concurrency group.
  • SHA pins: every uses: across all workflows now pins a 40-hex commit SHA with a version comment, matching the pattern already used in codeql.yml (untouched by this PR). Verified with a full-directory sweep — see below.
  • Job ids unchanged: app and e2e in ci.yml keep their exact names — these are the protect-main ruleset's required-check names.

New workflows

  • verify-mask.yml (job id verify, workflow name "Mask integrity"): flood-fill-checks the committed mask (app/public/data/mask.bin) with the same probes as pipeline/verify_mask.py. Path-filtered to pipeline/**, app/public/data/**, and the workflow file itself, on both pull_request and push: main — deliberately not a required check, so a skipped run (unrelated paths) can never block a PR. Slim on purpose: verify_mask.py only imports numpy + scipy.ndimage, no rebuild/geo stack. Rehearsed locally in an isolated venv (numpy 2.5.1, scipy 1.18.0) against the real committed mask — exit 0, 28/33 harbors OK, 5 known-disconnected (tracked, Mask: 5 harbors remain disconnected — Schlei fairway, Dyvig channel, Gråsten bridge (sub-cell features) #9).
  • scorecard.yml (job id analysis, workflow name "Scorecard"): OpenSSF Scorecard, runs on push to main, weekly (Monday 03:30 UTC), and on branch-protection-rule changes. Uploads SARIF to code scanning. Not a required check.

README

Added CI / CodeQL / Scorecard badges as the first line block, above the banner image.

Deferred

  • OpenSSF Best Practices badge (from Public readiness: CI hardening + OpenSSF Scorecard alignment #14's last bullet): deferred — needs a bestpractices.dev questionnaire filled out by the project, out of scope for this CI-hardening PR.
  • The Scorecard badge will stay gray until the first main run publishes results after merge — expected, not a bug in this PR.

Verification

  • grep -rn 'uses:' .github/workflows/ | grep -v '@[0-9a-f]\{40\}' → empty (full pin sweep clean).
  • All 5 workflow YAML files parse with yaml.safe_load.
  • verify_mask.py rehearsed against the real committed mask in a slim venv (numpy+scipy only) — exit 0.
  • codeql.yml untouched (0 lines changed).

Acceptance evidence (to confirm on this PR)

  • app + e2e green under the new pinned actions.
  • Mask integrity runs on this PR (the workflow file itself matches its own paths filter) and passes.
  • After merge: Deploy and Scorecard succeed on main, then work through any Scorecard findings via gh api repos/DocGerd/sail_command/code-scanning/alerts.

@DocGerd
DocGerd merged commit 57273ea into main Jul 17, 2026
6 checks passed
@DocGerd DocGerd mentioned this pull request Jul 17, 2026
7 tasks
@DocGerd
DocGerd deleted the feat/14-ci-hardening branch July 17, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Public readiness: CI hardening + OpenSSF Scorecard alignment

1 participant