name: CI on: push: branches: [main] pull_request: branches: [main] jobs: commitlint: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "24" cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Validate current commit if: github.event_name == 'push' run: npx commitlint --from HEAD~1 --to HEAD --verbose - name: Validate PR commits if: github.event_name == 'pull_request' run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose frontend: runs-on: ubuntu-latest strategy: matrix: node-version: [latest, 24.*, 25.*, 26.*] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Lint run: npm run lint - name: Unit Tests run: npm run test:run - name: Build run: npm run build - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: dist-${{ matrix.node-version }} path: dist/ retention-days: 7 backend: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20.x" - name: Install dependencies working-directory: ./backend run: npm ci --prefer-offline --no-audit --no-fund - name: Test working-directory: ./backend run: npm test integration: runs-on: ubuntu-latest needs: [frontend, backend, commitlint] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20.x" cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Run Integration Tests run: npm run test:integration e2e: runs-on: ubuntu-latest needs: [frontend, backend, commitlint] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20.x" cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Install Playwright browsers run: npx playwright install --with-deps chromium - name: Run E2E Tests run: npm run test:e2e - name: Upload Playwright report uses: actions/upload-artifact@v4 if: always() with: name: playwright-report path: playwright-report/ retention-days: 7 regression: runs-on: ubuntu-latest needs: [frontend, backend, commitlint] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20.x" cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Run Regression Tests run: npm run test:regression - name: Upload snapshot diffs uses: actions/upload-artifact@v4 if: failure() with: name: snapshot-diffs path: tests/regression/**/__diff_output__/ retention-days: 7 lighthouse: runs-on: ubuntu-latest needs: [frontend] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20.x" cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Build run: npm run build - name: Run Lighthouse CI run: npm run test:lighthouse continue-on-error: true quality: name: Quality Gates runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - name: Install dependencies run: npm ci --prefer-offline --no-audit --no-fund - name: Run tests with coverage run: npm run test:coverage - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: false - name: Build run: npm run build - name: Check bundle size run: npx bundlesize - name: Security audit run: npm audit --audit-level=moderate continue-on-error: true