name: CI on: push: branches: [master] pull_request: branches: [master] permissions: contents: read security-events: write env: NODE_VERSION: "20" PNPM_VERSION: "9.0.0" jobs: # Code quality checks quality: name: Code Quality runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: "pnpm" - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run linting run: pnpm lint - name: Type checking run: pnpm type-check - name: Check formatting run: pnpm prettier --check . # Testing test: name: Test Suite runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: "pnpm" - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run unit tests run: pnpm test:run:coverage env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Run integration tests run: pnpm test:integration:coverage env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Run tests with junit reporter run: pnpm vitest run --reporter=junit --outputFile=test-report.junit.xml if: always() - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: ${{ !cancelled() }} uses: codecov/test-results-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} # Build verification build: name: Build Application needs: [quality, test] runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: "pnpm" - name: Install dependencies run: pnpm install --frozen-lockfile - name: Build application run: pnpm build env: NODE_ENV: production - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: next-build path: | .next/ out/ retention-days: 7 if-no-files-found: warn # Security scanning security: name: Security Scan runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: "pnpm" - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run security audit run: pnpm audit --audit-level=moderate continue-on-error: true - name: Check for known vulnerabilities uses: aquasecurity/trivy-action@master with: scan-type: "fs" scan-ref: "." format: "sarif" output: "trivy-results.sarif" severity: "CRITICAL,HIGH" exit-code: 0 - name: Upload Trivy results uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: "trivy-results.sarif"