Skip to content

chore: normalize .csproj line endings to LF via .gitattributes #161

chore: normalize .csproj line endings to LF via .gitattributes

chore: normalize .csproj line endings to LF via .gitattributes #161

Workflow file for this run

# workflow bump: force refresh after removing setup-trivy
name: CI
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# ───────────────────────── Backend (.NET 10) ─────────────────────────
backend:
name: backend (build + coverage + format)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Restore
run: dotnet restore DocAnalytics.slnx
- name: Build
run: dotnet build DocAnalytics.slnx --no-restore --configuration Release
- name: Format check (dotnet format)
run: dotnet format DocAnalytics.slnx --verify-no-changes
- name: Test + coverage gate (per layer)
shell: bash
run: bash scripts/coverage-gate.sh
# ──────────────────────── Frontend (Angular 22) ────────────────────────
frontend:
name: frontend (build + test + format)
runs-on: ubuntu-latest
defaults:
run:
working-directory: docanalytics-web
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
cache-dependency-path: docanalytics-web/package-lock.json
- name: Install (clean)
run: npm ci
- name: Prettier format check
run: npm run format:check
- name: Build
run: npm run build
- name: Test (Vitest, single run + coverage thresholds)
run: npx ng test --watch=false
# ──────────────────────── E2E (Playwright) ────────────────────────
e2e:
name: e2e (Playwright)
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: docanalytics
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
cache-dependency-path: docanalytics-web/package-lock.json
- name: Trust dev HTTPS cert (API serves https on :7001)
run: dotnet dev-certs https
- name: Restore + build API (so startup is fast)
run: |
dotnet restore DocAnalytics.slnx
dotnet build DocAnalytics.Api -c Release --no-restore
- name: Install web dependencies
working-directory: docanalytics-web
run: npm ci
- name: Install Playwright browsers
working-directory: docanalytics-web
run: npx playwright install --with-deps
- name: Start API and run Playwright E2E
working-directory: docanalytics-web
env:
ASPNETCORE_ENVIRONMENT: Development
ConnectionStrings__Default: "Host=localhost;Port=5432;Database=docanalytics;Username=postgres;Password=postgres"
Jwt__Key: ${{ secrets.E2E_JWT_KEY || 'ci-e2e-dummy-signing-key-not-a-secret-0123456789' }}
CI: 'true'
run: |
set -e
# Start the API in the background WITHIN this step so it stays alive
# while Playwright runs (background procs are killed at step end).
( cd .. && dotnet run --project DocAnalytics.Api -c Release --no-build > api.log 2>&1 & )
echo "Waiting for API on https://localhost:7001 ..."
up=""
for i in $(seq 1 90); do
if curl -sk https://localhost:7001/health >/dev/null 2>&1; then up=1; echo "API is up"; break; fi
sleep 2
done
if [ -z "$up" ]; then echo "API did not start"; cat ../api.log || true; exit 1; fi
npx playwright test
- name: Upload Playwright report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: docanalytics-web/playwright-report
retention-days: 7
# ──────────────────────── DevSecOps (scans) ────────────────────────
devsecops:
name: devsecops (secrets + deps + image scan)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gitleaks (working tree only, via Docker)
run: |
docker run --rm \
-v "${{ github.workspace }}:/repo" \
ghcr.io/gitleaks/gitleaks:v8.24.3 \
detect \
--source=/repo \
--no-git \
--redact \
--config=/repo/.gitleaks.toml \
--exit-code 1
# Backend dependency scan (.NET)
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: dotnet list package --vulnerable (fail on any)
shell: bash
run: |
set -euo pipefail
dotnet list DocAnalytics.slnx package --vulnerable --include-transitive | tee dotnet-vuln.txt
if grep -qi "has the following vulnerable packages" dotnet-vuln.txt; then
echo "❌ Vulnerable NuGet packages detected"
exit 1
fi
# Frontend dependency scan (npm)
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: '22'
- name: npm audit (HIGH+)
working-directory: docanalytics-web
run: |
npm ci
npm audit --audit-level=high
# Container image scan (Trivy) — run via Docker (no setup-trivy dependency)
- name: Build API image
run: docker build -t docanalytics-api:${{ github.sha }} -f DocAnalytics.Api/Dockerfile .
- name: Trivy scan (API image)
run: |
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:0.54.1 \
image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 \
docanalytics-api:${{ github.sha }}
- name: Build Web image
run: docker build -t docanalytics-web:${{ github.sha }} -f docanalytics-web/Dockerfile docanalytics-web
- name: Trivy scan (Web image)
run: |
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:0.54.1 \
image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 \
docanalytics-web:${{ github.sha }}