53931d9d2b
CI — Build, Lint & Security Scan / backend (push) Failing after 1m24s
CI — Build, Lint & Security Scan / frontend (push) Failing after 48s
CI — Build, Lint & Security Scan / image-scan (push) Has been skipped
CI — Build, Lint & Security Scan / secrets-scan (push) Failing after 27s
Deploy to TrueNAS / deploy (push) Successful in 3m0s
- Remove @ConditionalOnProperty from RetentionService class; guard only @Scheduled method - Fix QuotaStatus property references in frontend tests - Downgrade upload-artifact to v3 for Gitea compatibility
196 lines
6.9 KiB
YAML
196 lines
6.9 KiB
YAML
name: CI — Build, Lint & Security Scan
|
|
|
|
# Runs on every push to main. Must pass before deploy.
|
|
# Security scans catch CVEs, license issues, and secrets BEFORE they reach prod.
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Backend: compile + test + dependency audit
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
backend:
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
env:
|
|
POSTGRES_DB: cannamanage_test
|
|
POSTGRES_USER: test
|
|
POSTGRES_PASSWORD: test
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v4
|
|
with:
|
|
distribution: temurin
|
|
java-version: 21
|
|
cache: maven
|
|
|
|
- name: Maven compile
|
|
run: ./mvnw compile -B -q -DskipTests -T 1C
|
|
|
|
- name: Maven test
|
|
run: ./mvnw test -B -T 1C
|
|
env:
|
|
CI_POSTGRES_URL: jdbc:postgresql://localhost:5432/cannamanage_test
|
|
CI_POSTGRES_USER: test
|
|
CI_POSTGRES_PASSWORD: test
|
|
|
|
- name: OWASP Dependency-Check (SCA)
|
|
run: |
|
|
./mvnw org.owasp:dependency-check-maven:check \
|
|
-DfailBuildOnCVSS=7 \
|
|
-DsuppressionFile=.snyk-maven-suppressions.xml \
|
|
-Dformats=JSON,HTML \
|
|
-B -q
|
|
# failBuildOnCVSS=7: High/Critical CVEs fail the build.
|
|
# Suppress known false positives in .snyk-maven-suppressions.xml.
|
|
|
|
- name: Upload dependency-check report
|
|
if: always()
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: dependency-check-report
|
|
path: target/dependency-check-report.*
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Frontend: lint + type-check + dependency audit
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
frontend:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Node 22
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Install pnpm
|
|
run: corepack enable && corepack prepare pnpm@10.8.1 --activate
|
|
|
|
- name: Install dependencies
|
|
run: cd cannamanage-frontend && pnpm install --frozen-lockfile
|
|
|
|
- name: Lint
|
|
run: cd cannamanage-frontend && pnpm lint
|
|
|
|
- name: Type check
|
|
run: cd cannamanage-frontend && pnpm type-check
|
|
|
|
- name: pnpm audit (SCA)
|
|
run: |
|
|
cd cannamanage-frontend
|
|
pnpm audit --audit-level=high
|
|
# Fails on High/Critical. Use .pnpmauditrc or --ignore for known exceptions.
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Docker image security scan (Trivy)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
image-scan:
|
|
runs-on: ubuntu-latest
|
|
needs: [backend, frontend]
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Build images (parallel)
|
|
run: |
|
|
set -euo pipefail
|
|
docker build -t cannamanage-backend:scan -f Dockerfile.backend . &
|
|
PID1=$!
|
|
docker build -t cannamanage-frontend:scan -f cannamanage-frontend/Dockerfile cannamanage-frontend/ &
|
|
PID2=$!
|
|
wait $PID1 $PID2
|
|
|
|
- name: Install Trivy
|
|
run: |
|
|
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
|
|
|
|
- name: Scan backend image
|
|
run: |
|
|
trivy image \
|
|
--severity HIGH,CRITICAL \
|
|
--exit-code 1 \
|
|
--ignore-unfixed \
|
|
--format table \
|
|
cannamanage-backend:scan
|
|
|
|
- name: Scan frontend image
|
|
run: |
|
|
trivy image \
|
|
--severity HIGH,CRITICAL \
|
|
--exit-code 1 \
|
|
--ignore-unfixed \
|
|
--format table \
|
|
cannamanage-frontend:scan
|
|
|
|
- name: Scan backend image (full report — JSON)
|
|
if: always()
|
|
run: |
|
|
trivy image \
|
|
--format json \
|
|
--output trivy-backend.json \
|
|
cannamanage-backend:scan
|
|
|
|
- name: Scan frontend image (full report — JSON)
|
|
if: always()
|
|
run: |
|
|
trivy image \
|
|
--format json \
|
|
--output trivy-frontend.json \
|
|
cannamanage-frontend:scan
|
|
|
|
- name: Upload Trivy reports
|
|
if: always()
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: trivy-reports
|
|
path: trivy-*.json
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Secret detection (Gitleaks)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
secrets-scan:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Install Gitleaks
|
|
run: |
|
|
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz \
|
|
| tar -xz -C /usr/local/bin gitleaks
|
|
|
|
- name: Run Gitleaks
|
|
run: |
|
|
gitleaks detect \
|
|
--source . \
|
|
--report-format json \
|
|
--report-path gitleaks-report.json \
|
|
--exit-code 1
|
|
|
|
- name: Upload Gitleaks report
|
|
if: always()
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: gitleaks-report
|
|
path: gitleaks-report.json
|