name: Dependency Review on: pull_request: paths: - 'package.json' - 'package-lock.json' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: dependency-review: runs-on: self-hosted name: Review Dependencies steps: - name: Checkout code uses: https://code.forgejo.org/actions/checkout@v4 - name: Setup Node.js run: | node --version npm --version - name: Check for major version changes run: | echo "Checking for major dependency updates..." git fetch origin main # Get the package.json from main branch git show origin/main:package.json > package-main.json # Compare dependencies node -e " const fs = require('fs'); const mainPkg = JSON.parse(fs.readFileSync('package-main.json', 'utf8')); const currentPkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); function compareDeps(mainDeps = {}, currentDeps = {}, type) { console.log(\`\\nChecking \${type}:\`); let hasChanges = false; for (const [pkg, currentVer] of Object.entries(currentDeps)) { const mainVer = mainDeps[pkg]; if (!mainVer) { console.log(\` āœ… Added: \${pkg}@\${currentVer}\`); hasChanges = true; } else if (mainVer !== currentVer) { const mainMajor = mainVer.match(/\\d+/)?.[0]; const currentMajor = currentVer.match(/\\d+/)?.[0]; if (mainMajor && currentMajor && mainMajor !== currentMajor) { console.log(\` āš ļø Major update: \${pkg} \${mainVer} → \${currentVer}\`); } else { console.log(\` šŸ“¦ Updated: \${pkg} \${mainVer} → \${currentVer}\`); } hasChanges = true; } } for (const [pkg, mainVer] of Object.entries(mainDeps)) { if (!currentDeps[pkg]) { console.log(\` āŒ Removed: \${pkg}@\${mainVer}\`); hasChanges = true; } } if (!hasChanges) { console.log(\` No changes\`); } } compareDeps(mainPkg.dependencies, currentPkg.dependencies, 'dependencies'); compareDeps(mainPkg.devDependencies, currentPkg.devDependencies, 'devDependencies'); " - name: Check for security advisories run: | npm audit --json > audit.json || true node -e " const audit = JSON.parse(require('fs').readFileSync('audit.json', 'utf8')); const vulns = audit.metadata?.vulnerabilities || {}; console.log('\\nSecurity Audit Summary:'); console.log(' Critical:', vulns.critical || 0); console.log(' High:', vulns.high || 0); console.log(' Moderate:', vulns.moderate || 0); console.log(' Low:', vulns.low || 0); if (vulns.critical > 0 || vulns.high > 0) { console.error('\\nāŒ Found critical or high severity vulnerabilities!'); process.exit(1); } " - name: Check bundle size impact run: | echo "Analyzing bundle size impact..." # Get changed files for this workflow git fetch origin main if git merge-base origin/main HEAD >/dev/null 2>&1; then CHANGED_FILES=$(git diff --name-only origin/main...HEAD) else CHANGED_FILES=$(git diff --name-only origin/main HEAD || echo "") fi # Skip bundle size check if no frontend changes if ! echo "$CHANGED_FILES" | grep -E "(src/frontend|scripts/build)" > /dev/null; then echo "No frontend changes detected, skipping bundle size analysis" exit 0 fi # Install dependencies from main (including devDependencies for build tools) git show origin/main:package-lock.json > package-lock-main.json || echo "No package-lock.json in main" git show origin/main:package.json > package-main.json || echo "No package.json in main" if [ -f "package-main.json" ]; then # Temporarily use main's package files cp package.json package-current.json cp package-lock.json package-lock-current.json cp package-main.json package.json cp package-lock-main.json package-lock.json 2>/dev/null || true npm ci --include=dev || echo "Failed to install main dependencies" npm run build:frontend > /dev/null 2>&1 || echo "Failed to build main frontend" du -sh public/dist 2>/dev/null > size-main.txt || echo "0B public/dist" > size-main.txt # Restore current package files mv package-current.json package.json mv package-lock-current.json package-lock.json else echo "No main branch package.json found" > size-main.txt fi # Install current dependencies npm ci --include=dev npm run build:frontend du -sh public/dist > size-current.txt echo "Bundle size comparison:" echo "Main branch: $(cat size-main.txt 2>/dev/null || echo 'Unable to determine')" echo "This branch: $(cat size-current.txt)"