ci: replace CodeQL with Semgrep (Gitea-compatible SAST)
CodeQL is GitHub-only — its analyze step uploads SARIF to GitHub's code-scanning API and assumes a GitHub Security tab; this CI runs on Gitea only, so the job could never go green (it had been red since it was added). Replace it with Semgrep OSS, a plain CLI SAST with no account/platform API, which runs fine on Gitea. - Remove the codeql job (+ its security-events permission) and the schedule trigger (it existed only for codeql; semgrep runs on push + PR). - Add a semgrep job: setup-python + `pip install semgrep` + `semgrep scan --config p/default --config p/csharp --metrics=off`. pip-on-runner (not container:) mirrors the other jobs' model; anonymous registry, telemetry off. - Report-only for now (no --error → job stays green): a local dry-run found 27 findings, mostly CI/config policy (unpinned actions, .npmrc), not app-code vulns. WP-30 tracks triaging them + flipping to --error (a blocking gate). Verified locally: `semgrep scan` runs clean (exit 0 without --error, 306 rules / 450 files). CI behaviour confirmable only on the Gitea runner — watch the run. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+16
-32
@@ -5,11 +5,8 @@ on:
|
|||||||
branches: [main]
|
branches: [main]
|
||||||
tags: ['v*']
|
tags: ['v*']
|
||||||
pull_request:
|
pull_request:
|
||||||
# CodeQL runs on main + this weekly cron only (not on PRs) — see the codeql job's `if`.
|
|
||||||
schedule:
|
|
||||||
- cron: '0 3 * * 1' # Mondays 03:00 UTC
|
|
||||||
|
|
||||||
# Least privilege by default; the CodeQL job widens its own scope locally.
|
# Least privilege by default.
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
@@ -111,38 +108,25 @@ jobs:
|
|||||||
- run: npx playwright install --with-deps chromium
|
- run: npx playwright install --with-deps chromium
|
||||||
- run: npm run e2e
|
- run: npm run e2e
|
||||||
|
|
||||||
codeql:
|
semgrep:
|
||||||
# Static analysis (SAST) for both sides; results appear under the Security tab.
|
# SAST for both sides — replaces CodeQL, which is GitHub-only (its analyze step uploads
|
||||||
# Off the PR path (slow 2-language matrix) — runs on push-to-main + the weekly
|
# SARIF to GitHub's code-scanning API) and can't run on this Gitea instance. Semgrep OSS
|
||||||
# cron only, so PR feedback isn't bottlenecked on it.
|
# is a plain CLI: no account, no external platform API. Findings print in the job log.
|
||||||
if: github.event_name != 'pull_request'
|
# ponytail: report-only for now (no `--error`, so the job stays green while the initial
|
||||||
|
# findings are triaged); flip to `--error` to make it a blocking gate. See WP-30.
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 15
|
||||||
permissions:
|
|
||||||
security-events: write
|
|
||||||
contents: read
|
|
||||||
actions: read
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [javascript-typescript, csharp]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- if: matrix.language == 'csharp'
|
- uses: actions/setup-python@v5
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: 10.0.x
|
python-version: '3.12'
|
||||||
- if: matrix.language == 'csharp'
|
cache: pip
|
||||||
uses: actions/cache@v4
|
- run: pip install semgrep
|
||||||
with:
|
# p/default = curated cross-language security (covers JS/TS); p/csharp = the backend.
|
||||||
path: ~/.nuget/packages
|
# Anonymous registry fetch; --metrics=off disables telemetry (not `auto`, which uploads
|
||||||
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }}
|
# project metadata).
|
||||||
restore-keys: nuget-${{ runner.os }}-
|
- run: semgrep scan --config p/default --config p/csharp --metrics=off
|
||||||
- uses: github/codeql-action/init@v3
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
- uses: github/codeql-action/autobuild@v3
|
|
||||||
- uses: github/codeql-action/analyze@v3
|
|
||||||
|
|
||||||
api-client-drift:
|
api-client-drift:
|
||||||
# The committed typed client must match the backend OpenAPI doc.
|
# The committed typed client must match the backend OpenAPI doc.
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ runner image, set on the act_runner host).
|
|||||||
5. **Lean deployable backend image** (optional, not for the dev demo): multi-stage prod build on
|
5. **Lean deployable backend image** (optional, not for the dev demo): multi-stage prod build on
|
||||||
`mcr.microsoft.com/dotnet/aspnet:10.0` (~220 MB) in a separate `docker-compose.prod.yml`. The
|
`mcr.microsoft.com/dotnet/aspnet:10.0` (~220 MB) in a separate `docker-compose.prod.yml`. The
|
||||||
dev `docker-compose.yml` keeps the SDK image because `dotnet run` hot-reload needs it.
|
dev `docker-compose.yml` keeps the SDK image because `dotnet run` hot-reload needs it.
|
||||||
|
6. **Semgrep: triage findings + make it blocking.** Semgrep replaced CodeQL (GitHub-only, couldn't
|
||||||
|
run on Gitea) and currently runs **report-only** — a local dry-run found 27 findings, mostly
|
||||||
|
CI/config policy (unpinned GitHub Actions in `ci.yml`, `.npmrc` min-release-age) rather than
|
||||||
|
app-code vulns. Triage them (fix or `# nosemgrep`/`.semgrepignore` the noise; consider a
|
||||||
|
tighter ruleset than `p/default` if the GitHub-Actions-policy rules aren't wanted), then add
|
||||||
|
`--error` to `semgrep scan` so it's a real gate.
|
||||||
|
|
||||||
## Acceptance criteria
|
## Acceptance criteria
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user