name: Security & Quality on: push: branches: [main] pull_request: branches: [main] permissions: contents: read jobs: quality: name: Lint, Typecheck & Test runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: node-version: 22 cache: "pnpm" - run: pnpm install --frozen-lockfile - run: pnpm db:generate - name: ESLint run: pnpm lint # Non-blocking on the existing settings page monolith — its set-state- # in-effect violations need the 1.4.0 settings-split refactor to fix # cleanly. Will flip to blocking once settings/page.tsx is broken up. continue-on-error: true - name: TypeScript strict check run: pnpm typecheck - name: Unit tests run: pnpm test # OpenAPI spec drift gate — hard-fail (flipped from warn-only in v1.4.25). # # The Zod registry is the source of truth for the public API contract. # Any route signature change must be reflected in `docs/api/openapi.yaml` # so downstream consumers (notably the v1.5 iOS Swift codegen) stay in # lockstep. If this step fails, run `pnpm openapi:generate` locally and # commit the regenerated spec. - name: OpenAPI spec drift check run: | pnpm openapi:generate if ! git diff --exit-code docs/api/openapi.yaml; then echo "::error::OpenAPI drift detected — regenerate the spec via 'pnpm openapi:generate' and commit the result. The Zod registry under src/lib/openapi/ is the source of truth for the public API contract." exit 1 fi echo "::notice::OpenAPI spec in sync with Zod source schemas." dependency-audit: name: Dependency Audit runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: node-version: 22 cache: "pnpm" - run: pnpm install --frozen-lockfile - name: Audit for known vulnerabilities run: pnpm audit --prod --audit-level=high continue-on-error: true secret-scan: name: Secret Scanning runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Gitleaks secret scan uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} docker-security: name: Container Security runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v6 - name: Build Docker image run: docker build -t healthlog:scan . - name: Install Trivy run: | sudo apt-get install -y wget apt-transport-https gnupg wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list sudo apt-get update && sudo apt-get install -y trivy - name: Trivy container scan run: trivy image --format table --severity CRITICAL,HIGH --exit-code 1 healthlog:scan continue-on-error: true