name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main, develop] # Concurrency control to cancel previous runs concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: BUN_VERSION: '1.2.5' # Pin version for consistency jobs: # Job 1: Quick checks that can fail fast quick-checks: name: Quick Checks runs-on: ubuntu-latest outputs: cache-key: ${{ steps.cache-key.outputs.key }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Generate cache key id: cache-key run: echo "key=bun-${{ hashFiles('bun.lock') }}" >> $GITHUB_OUTPUT - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: ${{ env.BUN_VERSION }} - name: Cache dependencies uses: actions/cache@v4 id: cache-deps with: path: ~/.bun/install/cache key: ${{ steps.cache-key.outputs.key }} restore-keys: bun- - name: Install dependencies run: bun install --frozen-lockfile - name: Cache node_modules uses: actions/cache@v4 with: path: node_modules key: node-modules-${{ steps.cache-key.outputs.key }} - name: Run TypeScript type check run: bun run type-check - name: Check Prettier formatting run: bun run format:check # Job 2: Linting (can run in parallel with type checking) lint: name: ESLint runs-on: ubuntu-latest needs: quick-checks steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: ${{ env.BUN_VERSION }} - name: Restore node_modules cache uses: actions/cache@v4 with: path: node_modules key: node-modules-${{ needs.quick-checks.outputs.cache-key }} - name: Install dependencies (if cache miss) run: bun install - name: Run ESLint run: bun run lint # Job 3: Testing with optimizations test: name: Test & Coverage runs-on: ubuntu-latest needs: quick-checks steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: ${{ env.BUN_VERSION }} - name: Restore node_modules cache uses: actions/cache@v4 with: path: node_modules key: node-modules-${{ needs.quick-checks.outputs.cache-key }} - name: Install dependencies (if cache miss) run: bun install - name: Cache Jest cache uses: actions/cache@v4 with: path: .jest-cache key: jest-cache-${{ hashFiles('jest.config.js', 'src/**/*.{ts,tsx}') }} restore-keys: jest-cache- - name: Run tests with optimizations run: bun run test:ci --maxWorkers=2 --cacheDirectory=.jest-cache env: NODE_OPTIONS: --max_old_space_size=4096 - name: Upload coverage reports uses: actions/upload-artifact@v4 if: always() with: name: coverage-report path: coverage/ retention-days: 7 # Job 4: Build (depends on tests passing) build: name: Build Application runs-on: ubuntu-latest needs: [quick-checks, lint, test] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: ${{ env.BUN_VERSION }} - name: Restore node_modules cache uses: actions/cache@v4 with: path: node_modules key: node-modules-${{ needs.quick-checks.outputs.cache-key }} - name: Install dependencies (if cache miss) run: bun install - name: Cache Next.js build uses: actions/cache@v4 with: path: | .next/cache .next/static key: nextjs-${{ hashFiles('next.config.ts', 'src/**/*.{ts,tsx}', 'public/**/*') }} restore-keys: nextjs- - name: Build application run: bun run build env: NODE_OPTIONS: --max_old_space_size=4096 - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: build-files path: .next/ retention-days: 7 # Job 5: Security audit (can run in parallel) security-audit: name: Security Audit runs-on: ubuntu-latest needs: quick-checks steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: ${{ env.BUN_VERSION }} - name: Restore node_modules cache uses: actions/cache@v4 with: path: node_modules key: node-modules-${{ needs.quick-checks.outputs.cache-key }} - name: Install dependencies (if cache miss) run: bun install - name: Run security audit run: bun audit --audit-level moderate - name: Run dependency vulnerability check run: bunx audit-ci --moderate --report-type summary