Skip to content

CI/CD

GitHub Actions workflows for automated testing and deployment.

Overview

flowchart LR
    subgraph Trigger
        A[Push/PR to main]
    end

    subgraph Backend
        B[Path Filter] --> C[Restore]
        C --> D[Build]
        D --> E[Unit Tests]
        E --> F[Integration Tests]
        F --> G[Vulnerability Scan]
    end

    subgraph Frontend
        H[Path Filter] --> I[Install]
        I --> J[Audit]
        J --> K[Lint]
        K --> L[Type Check]
        L --> M[Unit Tests]
        M --> N[Build]
    end

    subgraph Security
        O[Gitleaks Scan]
    end

    A --> B
    A --> H
    A --> O

Workflows

Backend (backend.yml)

Trigger: Push or PR to main when UnicornTrails.API/** changes

Steps:

Step Command Purpose
Restore dotnet restore Install dependencies
Build dotnet build --warnaserror Compile with strict warnings
Unit Tests dotnet test Run unit tests with coverage
Integration Tests dotnet test Run integration tests
Vulnerability Scan dotnet list package --vulnerable Check for vulnerable packages

Configuration:

- uses: actions/setup-dotnet@v5
  with:
    dotnet-version: '10.0.x'

- uses: actions/cache@v5
  with:
    path: ~/.nuget/packages
    key: nuget-${{ runner.os }}-${{ hashFiles('UnicornTrails.API/**/*.csproj') }}

Frontend (frontend.yml)

Trigger: Push or PR to main when UnicornTrails.Client/** changes

Steps:

Step Command Purpose
Install npm ci Clean install
Audit npm audit --audit-level=high Security check
Lint npm run lint ESLint
Type Check tsc -b --noEmit TypeScript validation
Unit Tests npm run test:unit Vitest
Build npm run build Production build

Configuration:

- uses: actions/setup-node@v6
  with:
    node-version: '22.x'
    cache: 'npm'
    cache-dependency-path: './UnicornTrails.Client/package-lock.json'

Security (security.yml)

Trigger: All pushes and PRs to main

Tool: Gitleaks

Purpose: Detect leaked secrets in code

Path Filtering

Workflows only run when relevant files change:

paths:
  - 'UnicornTrails.API/**'
  - '!**/*.md'
  - '!**/.dockerignore'
  - '!**/dockerfile'

Concurrency Control

Cancel in-progress runs on new pushes:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Dependabot

Automated dependency updates:

Ecosystem Schedule Groups
NuGet Weekly (Monday) ef-core, microsoft
npm Weekly (Monday) mui, tanstack
GitHub Actions Weekly (Monday)

Secret Scanning

.gitleaks.toml defines patterns to detect:

  • Cloudflare R2 credentials
  • Resend API keys
  • Sentry auth tokens
  • Turnstile secrets
  • JWT signing keys
  • PostgreSQL passwords

Running Locally

# Backend
cd UnicornTrails.API
dotnet restore
dotnet build
dotnet test

# Frontend
cd UnicornTrails.Client
npm ci
npm run lint
npm run test:unit
npm run build