|
| 1 | +# workflow bump: force refresh after removing setup-trivy |
1 | 2 | name: CI |
2 | 3 |
|
3 | | -# Runs on every PR (any target branch) + pushes to main. |
4 | 4 | on: |
5 | 5 | pull_request: |
6 | 6 | push: |
7 | 7 | branches: [main] |
8 | 8 |
|
9 | | -# Least-privilege token (status checks only need read). |
10 | 9 | permissions: |
11 | 10 | contents: read |
12 | 11 |
|
13 | | -# Fail-fast: cancel a superseded run when new commits land on the same ref. |
14 | 12 | concurrency: |
15 | 13 | group: ci-${{ github.workflow }}-${{ github.ref }} |
16 | 14 | cancel-in-progress: true |
|
35 | 33 | - name: Build |
36 | 34 | run: dotnet build DocAnalytics.slnx --no-restore --configuration Release |
37 | 35 |
|
38 | | - # Fast gate = 4 correctness projects (Round 0 decision). |
39 | | - # Performance.Tests is intentionally EXCLUDED from the blocking gate. |
40 | | - # bash runs with -eo pipefail, so the first failing project stops the job (fail-fast). |
41 | 36 | - name: Test (correctness projects) |
42 | 37 | run: | |
43 | 38 | dotnet test DocAnalytics.Domain.Tests/DocAnalytics.Domain.Tests.csproj --no-build --configuration Release |
|
46 | 41 | dotnet test DocAnalytics.Api.Tests/DocAnalytics.Api.Tests.csproj --no-build --configuration Release |
47 | 42 |
|
48 | 43 | # ──────────────────────── Frontend (Angular 22) ──────────────────────── |
49 | | - # Runs in PARALLEL with `backend` (no `needs:` dependency between them). |
50 | 44 | frontend: |
51 | 45 | name: frontend (build + test) |
52 | 46 | runs-on: ubuntu-latest |
|
72 | 66 |
|
73 | 67 | - name: Test (Vitest, single run) |
74 | 68 | run: npx ng test --watch=false |
| 69 | + |
| 70 | + # ──────────────────────── DevSecOps (scans) ──────────────────────── |
| 71 | + devsecops: |
| 72 | + name: devsecops (secrets + deps + image scan) |
| 73 | + runs-on: ubuntu-latest |
| 74 | + permissions: |
| 75 | + contents: read |
| 76 | + steps: |
| 77 | + - name: Checkout |
| 78 | + uses: actions/checkout@v4 |
| 79 | + |
| 80 | + - name: Gitleaks (working tree only, via Docker) |
| 81 | + run: | |
| 82 | + docker run --rm \ |
| 83 | + -v "${{ github.workspace }}:/repo" \ |
| 84 | + ghcr.io/gitleaks/gitleaks:v8.24.3 \ |
| 85 | + detect \ |
| 86 | + --source=/repo \ |
| 87 | + --no-git \ |
| 88 | + --redact \ |
| 89 | + --config=/repo/.gitleaks.toml \ |
| 90 | + --exit-code 1 |
| 91 | +
|
| 92 | +
|
| 93 | + # Backend dependency scan (.NET) |
| 94 | + - name: Setup .NET |
| 95 | + uses: actions/setup-dotnet@v4 |
| 96 | + with: |
| 97 | + dotnet-version: '10.0.x' |
| 98 | + |
| 99 | + - name: dotnet list package --vulnerable (fail on any) |
| 100 | + shell: bash |
| 101 | + run: | |
| 102 | + set -euo pipefail |
| 103 | + dotnet list DocAnalytics.slnx package --vulnerable --include-transitive | tee dotnet-vuln.txt |
| 104 | + if grep -qi "has the following vulnerable packages" dotnet-vuln.txt; then |
| 105 | + echo "❌ Vulnerable NuGet packages detected" |
| 106 | + exit 1 |
| 107 | + fi |
| 108 | +
|
| 109 | + # Frontend dependency scan (npm) |
| 110 | + - name: Setup Node 22 |
| 111 | + uses: actions/setup-node@v4 |
| 112 | + with: |
| 113 | + node-version: '22' |
| 114 | + |
| 115 | + - name: npm audit (HIGH+) |
| 116 | + working-directory: docanalytics-web |
| 117 | + run: | |
| 118 | + npm ci |
| 119 | + npm audit --audit-level=high |
| 120 | +
|
| 121 | + # Container image scan (Trivy) — run via Docker (no setup-trivy dependency) |
| 122 | + - name: Build API image |
| 123 | + run: docker build -t docanalytics-api:${{ github.sha }} -f DocAnalytics.Api/Dockerfile . |
| 124 | + |
| 125 | + - name: Trivy scan (API image) |
| 126 | + run: | |
| 127 | + docker run --rm \ |
| 128 | + -v /var/run/docker.sock:/var/run/docker.sock \ |
| 129 | + aquasec/trivy:0.54.1 \ |
| 130 | + image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 \ |
| 131 | + docanalytics-api:${{ github.sha }} |
| 132 | +
|
| 133 | + - name: Build Web image |
| 134 | + run: docker build -t docanalytics-web:${{ github.sha }} -f docanalytics-web/Dockerfile docanalytics-web |
| 135 | + |
| 136 | + - name: Trivy scan (Web image) |
| 137 | + run: | |
| 138 | + docker run --rm \ |
| 139 | + -v /var/run/docker.sock:/var/run/docker.sock \ |
| 140 | + aquasec/trivy:0.54.1 \ |
| 141 | + image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 \ |
| 142 | + docanalytics-web:${{ github.sha }} |
0 commit comments