name: ๐Ÿ“Š Quality on: pull_request: types: [opened, synchronize, reopened] branches: [develop, main] push: branches: - main - develop workflow_dispatch: jobs: security: name: ๐Ÿ”’ Security Audit runs-on: ubuntu-latest steps: - name: โฌ‡๏ธ Checkout uses: actions/checkout@v6 - name: ๐Ÿงฐ Setup Node uses: actions/setup-node@v6 with: node-version: "20" cache: npm - name: ๐Ÿ“ฅ Install run: npm ci - name: ๐Ÿ”’ Audit run: npm audit --audit-level=high continue-on-error: true dependencies: name: ๐Ÿ“‹ Dependency Freshness runs-on: ubuntu-latest steps: - name: โฌ‡๏ธ Checkout uses: actions/checkout@v6 - name: ๐Ÿงฐ Setup Node uses: actions/setup-node@v6 with: node-version: "20" cache: npm - name: ๐Ÿ“ฅ Install run: npm ci - name: ๐Ÿ“‹ Check outdated run: npm outdated --depth=0 continue-on-error: true bundle-size: name: ๐Ÿ“ฆ Bundle Size runs-on: ubuntu-latest steps: - name: โฌ‡๏ธ Checkout uses: actions/checkout@v6 with: lfs: true - name: ๐Ÿงฐ Setup Node uses: actions/setup-node@v6 with: node-version: "20" cache: npm - name: ๐Ÿ“ฅ Install run: npm ci - name: ๐Ÿงน Lint run: npm run lint - name: ๐ŸŽจ Format check run: npm run format:check - name: ๐Ÿ“ฆ Build run: npm run build - name: ๐Ÿ“ Check bundle size run: | # Check generated JS/CSS bundles only; public runtime assets are copied to dist/assets too. SIZE=$(node -e "const fs=require('fs');const path=require('path');function walk(dir){return fs.readdirSync(dir,{withFileTypes:true}).flatMap((entry)=>{const file=path.join(dir,entry.name);return entry.isDirectory()?walk(file):file;});}const bytes=walk('dist/assets').filter((file)=>/\.(js|css)$/.test(file)).reduce((sum,file)=>sum+fs.statSync(file).size,0);console.log(Math.ceil(bytes/1024));") echo "Bundle size: ${SIZE}KB" THRESHOLD=5000 if [ "$SIZE" -gt "$THRESHOLD" ]; then echo "โŒ Bundle size ${SIZE}KB exceeds threshold ${THRESHOLD}KB" exit 1 fi echo "โœ… Bundle size ${SIZE}KB is under threshold"