name: CI on: push: branches: [main, develop] pull_request: branches: [main, develop] paths: - 'src/**' - 'e2e/**' - 'public/**' - 'package.json' - 'pnpm-lock.yaml' - 'tsconfig.json' - 'vitest.config.ts' - 'next.config.ts' - 'tailwind.config.*' - 'playwright.config.ts' - 'lighthouserc.json' - '.github/workflows/ci.yml' - '.github/actions/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: contents: read jobs: lint: name: Lint runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup - name: Run ESLint run: pnpm lint - name: Check formatting run: pnpm format:check typecheck: name: Type Check runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup - name: Run TypeScript run: pnpm typecheck test: name: Test runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup - name: Run tests run: pnpm test build: name: Build runs-on: ubuntu-latest timeout-minutes: 20 needs: [lint, typecheck, test] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup - name: Cache Next.js build uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: .next/cache key: nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('src/**', 'public/**', 'next.config.ts') }} restore-keys: | nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}- nextjs-${{ runner.os }}- - name: Build application run: pnpm build accessibility: name: Accessibility Audit runs-on: ubuntu-latest timeout-minutes: 30 needs: build steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup - name: Install Playwright browsers run: pnpm exec playwright install --with-deps chromium - name: Cache Next.js build uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: .next/cache key: nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('src/**', 'public/**', 'next.config.ts') }} restore-keys: | nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}- nextjs-${{ runner.os }}- - name: Build application run: pnpm build - name: Prepare standalone server run: | cp -r .next/static .next/standalone/.next/static cp -r public .next/standalone/public - name: Start standalone server run: node .next/standalone/server.js & env: PORT: '3000' HOSTNAME: '0.0.0.0' - name: Wait for server run: | for i in $(seq 1 30); do curl -s http://localhost:3000 > /dev/null 2>&1 && break sleep 1 done - name: Run Playwright a11y tests run: pnpm test:e2e - name: Run pa11y-ci run: pnpm test:a11y - name: Run Lighthouse CI run: pnpm test:lighthouse env: CHROME_PATH: /usr/bin/google-chrome-stable - name: Upload Playwright report if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: playwright-report path: playwright-report/ retention-days: 7 - name: Upload Lighthouse report if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: lighthouse-report path: .lighthouseci/ retention-days: 7 security: name: Security Scan runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup - name: Security audit with retry run: | for attempt in 1 2 3; do output=$(pnpm audit --audit-level=high --prod 2>&1) && { echo "$output"; exit 0; } if echo "$output" | grep -q "ERR_PNPM_AUDIT_BAD_RESPONSE\|ECONNREFUSED\|ETIMEDOUT\|EAI_AGAIN"; then echo "::warning::Audit registry unavailable (attempt $attempt/3), retrying in 15s..." sleep 15 else echo "$output" exit 1 fi done echo "::warning::Audit registry unavailable after 3 attempts, skipping"