Skip to content

Merge branch 'fix/code-review-findings-story-6-1' #10

Merge branch 'fix/code-review-findings-story-6-1'

Merge branch 'fix/code-review-findings-story-6-1' #10

Workflow file for this run

name: Build and Deploy
on:
push:
branches: [master]
pull_request:
branches: [master]
# Concurrency: For PRs, cancel in-progress runs. For master pushes, queue deployments.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# ============================================
# STAGE 1: Security & Linting (runs in parallel)
# ============================================
security:
name: Security Scan (npm audit)
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
- name: Run npm audit (high/critical)
run: npm audit --audit-level=high
semgrep:
name: Security Scan (Semgrep SAST)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run Semgrep SAST
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/javascript
p/typescript
p/security-audit
lint:
name: Lint & Type Check
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
- name: Generate Astro types
run: npx astro sync
- name: TypeScript check (src only)
run: npx tsc --noEmit --project tsconfig.ci.json
- name: Run gts lint
run: npm run lint
- name: Run gts check (formatting)
run: npm run check
# ============================================
# STAGE 2: Build + Unit Tests (parallel, needs lint/security)
# ============================================
build:
name: Build
needs: [security, semgrep, lint]
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
- name: Build Astro site
run: npm run build
- name: Run Closure Compiler lint check
run: npx google-closure-compiler --jscomp_warning=lintChecks --js='dist/**/*.js' --checks_only || true
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 1
unit-tests:
name: Unit Tests
needs: [security, semgrep, lint]
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
- name: Run Vitest with coverage
run: npm run test:coverage -- --reporter=github-actions
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 7
# ============================================
# STAGE 3: E2E + Lighthouse (after build, parallel)
# ============================================
e2e-tests:
name: E2E Tests
needs: build
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
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: playwright-browsers-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
- name: Install Playwright (all browsers)
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps
- name: Install Playwright deps (if cache hit)
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: npx playwright install-deps
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Start server and run E2E tests
run: |
npx serve dist -l 4321 &
npx wait-on http://localhost:4321
npm run test:e2e
env:
CI: true
- name: Upload Playwright report on failure
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
retention-days: 7
lighthouse:
name: Lighthouse CI
needs: build
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
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v12
with:
configPath: ./lighthouserc.json
uploadArtifacts: true
# ============================================
# STAGE 4: Deploy (master push only, after all checks)
# ============================================
deploy:
name: Deploy to GitHub Pages
needs: [build, unit-tests, e2e-tests, lighthouse]
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist