Phase 16: CI dependency audit & security checks #15
@@ -342,6 +342,82 @@ jobs:
|
|||||||
apps/pwa/playwright-report/
|
apps/pwa/playwright-report/
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
||||||
|
security:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [changes]
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
# Runs in PARALLEL with fast-checks (D-15). gitleaks always runs (D-12 — secrets
|
||||||
|
# can appear in doc-only commits). pnpm audit + pnpm outdated run only on
|
||||||
|
# code/lockfile-changing PRs (step-level if: keeps the job always-running).
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required: base.sha must be locally available for git log range (Pitfall 3)
|
||||||
|
|
||||||
|
# ── Probe PR base/head SHA with merge-base fallback (A2 / OQ-1) ──────────
|
||||||
|
# github.event.pull_request.base.sha may be empty on some Gitea versions.
|
||||||
|
# If so, fall back to git merge-base to compute the real branch-point SHA.
|
||||||
|
- name: Probe PR base/head SHA
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
echo "Event base.sha: ${{ github.event.pull_request.base.sha }}"
|
||||||
|
echo "Event head.sha: ${{ github.event.pull_request.head.sha }}"
|
||||||
|
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
||||||
|
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
|
||||||
|
if [ -z "$BASE_SHA" ]; then
|
||||||
|
echo "base.sha empty — computing merge-base fallback"
|
||||||
|
BASE_SHA=$(git merge-base "$(git rev-parse origin/${{ github.base_ref }})" HEAD)
|
||||||
|
echo "Computed BASE_SHA via merge-base: $BASE_SHA"
|
||||||
|
fi
|
||||||
|
echo "BASE_SHA=$BASE_SHA" >> "$GITHUB_ENV"
|
||||||
|
echo "HEAD_SHA=$HEAD_SHA" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
# ── Gitleaks (always runs, D-12) ─────────────────────────────────────────
|
||||||
|
- name: Install gitleaks
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
VERSION=8.30.1
|
||||||
|
curl -sL \
|
||||||
|
"https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" \
|
||||||
|
| tar -xz gitleaks
|
||||||
|
chmod +x gitleaks
|
||||||
|
mv gitleaks /usr/local/bin/gitleaks
|
||||||
|
|
||||||
|
- name: Secret scan (PR diff, blocking)
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
gitleaks git \
|
||||||
|
--log-opts="--no-merges ${BASE_SHA}..${HEAD_SHA}" \
|
||||||
|
--config .gitleaks.toml \
|
||||||
|
--baseline-path scripts/gitleaks-baseline.json \
|
||||||
|
--report-path /tmp/gitleaks-pr-report.json \
|
||||||
|
--exit-code 1
|
||||||
|
|
||||||
|
# ── pnpm audit + outdated (code-change PRs only, D-12) ───────────────────
|
||||||
|
# actions/cache@v4 intentionally omitted — same reasoning as fast-checks job (D-PROBE-04).
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
if: needs.changes.outputs.code == 'true'
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Enable pnpm
|
||||||
|
if: needs.changes.outputs.code == 'true'
|
||||||
|
run: corepack enable pnpm
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: needs.changes.outputs.code == 'true'
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Dependency audit (blocking on High+Critical)
|
||||||
|
if: needs.changes.outputs.code == 'true'
|
||||||
|
run: node scripts/check-audit.mjs
|
||||||
|
|
||||||
|
- name: Dependency outdated report (advisory only)
|
||||||
|
if: needs.changes.outputs.code == 'true'
|
||||||
|
run: node scripts/check-outdated.mjs
|
||||||
|
# Always exits 0 — log output only, never gates (D-06)
|
||||||
|
|
||||||
gate:
|
gate:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [fast-checks, changes, api, harness]
|
needs: [fast-checks, changes, api, harness]
|
||||||
|
|||||||
Reference in New Issue
Block a user