feat: Major release with Remote Registry, Sigstore, and Custom UI #27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| node-version: [20.x, 22.x] | |
| 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 | |
| - name: Run linting | |
| run: npm run lint --if-present | |
| - name: Run tests | |
| run: npm test | |
| - name: Build TypeScript | |
| run: npm run build | |
| - name: Test CLI functionality | |
| run: | | |
| # Test basic CLI commands | |
| node dist/index.js --version | |
| node dist/index.js --help | |
| node dist/index.js list --json | |
| node dist/index.js doctor --json | |
| security: | |
| 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 security audit with known exceptions | |
| run: | | |
| echo "🔍 Running security audit..." | |
| # Run audit and capture output | |
| npm audit --audit-level=moderate --json > audit.json || true | |
| # Parse audit results | |
| if [ -f audit.json ]; then | |
| # Check if we have any vulnerabilities | |
| VULN_COUNT=$(cat audit.json | jq -r '.metadata.vulnerabilities.total // 0') | |
| if [ "$VULN_COUNT" -gt 0 ]; then | |
| echo "📋 Found $VULN_COUNT vulnerabilities, analyzing..." | |
| # Extract vulnerability details | |
| cat audit.json | jq -r '.vulnerabilities | to_entries[] | "\(.key): \(.value.severity) - \(.value.title)"' > vulnerabilities.txt | |
| # Check for known acceptable vulnerabilities | |
| KNOWN_PKG_VULN=$(grep -c "pkg.*Local Privilege Escalation" vulnerabilities.txt || echo "0") | |
| RUNTIME_VULNS=$(grep -v "pkg.*Local Privilege Escalation" vulnerabilities.txt | wc -l || echo "0") | |
| echo "📊 Vulnerability breakdown:" | |
| echo " - Known pkg build-time vulnerability: $KNOWN_PKG_VULN" | |
| echo " - Runtime/other vulnerabilities: $RUNTIME_VULNS" | |
| # Display all vulnerabilities for transparency | |
| echo "" | |
| echo "📋 All vulnerabilities found:" | |
| cat vulnerabilities.txt | |
| # Fail only if we have runtime vulnerabilities | |
| if [ "$RUNTIME_VULNS" -gt 0 ]; then | |
| echo "" | |
| echo "❌ SECURITY CHECK FAILED: Runtime vulnerabilities detected" | |
| echo "The following vulnerabilities affect runtime security and must be fixed:" | |
| grep -v "pkg.*Local Privilege Escalation" vulnerabilities.txt || true | |
| exit 1 | |
| else | |
| echo "" | |
| echo "✅ SECURITY CHECK PASSED: Only known build-time vulnerabilities present" | |
| echo "The pkg vulnerability is build-time only and does not affect end users." | |
| echo "See SECURITY_ADVISORY.md for details." | |
| fi | |
| else | |
| echo "✅ No vulnerabilities found" | |
| fi | |
| else | |
| echo "⚠️ Could not parse audit results, running basic check..." | |
| npm audit --audit-level=high | |
| fi | |
| - name: Check for high severity vulnerabilities | |
| run: | | |
| echo "🔍 Double-checking for high severity vulnerabilities..." | |
| # This will fail the job if any HIGH severity vulnerabilities are found | |
| # regardless of whether they're in known exceptions | |
| if ! npm audit --audit-level=high --json > high_audit.json; then | |
| echo "⚠️ High severity vulnerabilities detected:" | |
| cat high_audit.json | jq -r '.vulnerabilities | to_entries[] | select(.value.severity == "high" or .value.severity == "critical") | "\(.key): \(.value.severity) - \(.value.title)"' | |
| # Check if it's only the pkg vulnerability | |
| HIGH_VULN_COUNT=$(cat high_audit.json | jq -r '.vulnerabilities | to_entries[] | select(.value.severity == "high" or .value.severity == "critical") | .key' | wc -l) | |
| PKG_HIGH_COUNT=$(cat high_audit.json | jq -r '.vulnerabilities | to_entries[] | select(.value.severity == "high" or .value.severity == "critical") | select(.key == "pkg") | .key' | wc -l) | |
| if [ "$HIGH_VULN_COUNT" -eq "$PKG_HIGH_COUNT" ] && [ "$PKG_HIGH_COUNT" -gt 0 ]; then | |
| echo "ℹ️ Only pkg build-time vulnerability found at high severity" | |
| echo "This is acceptable as it doesn't affect runtime security" | |
| else | |
| echo "❌ Non-pkg high severity vulnerabilities found - failing build" | |
| exit 1 | |
| fi | |
| else | |
| echo "✅ No high severity vulnerabilities found" | |
| fi | |
| - name: Generate security report | |
| if: always() | |
| run: | | |
| echo "📄 Generating security report..." | |
| { | |
| echo "# Security Audit Report" | |
| echo "**Date**: $(date)" | |
| echo "**Status**: $([ -f audit.json ] && echo 'Completed' || echo 'Failed')" | |
| echo "" | |
| if [ -f audit.json ]; then | |
| TOTAL_VULNS=$(cat audit.json | jq -r '.metadata.vulnerabilities.total // 0') | |
| echo "**Total Vulnerabilities**: $TOTAL_VULNS" | |
| if [ "$TOTAL_VULNS" -gt 0 ]; then | |
| echo "" | |
| echo "## Vulnerability Details" | |
| cat audit.json | jq -r '.vulnerabilities | to_entries[] | "- **\(.key)**: \(.value.severity) - \(.value.title)"' | |
| echo "" | |
| echo "## Risk Assessment" | |
| if grep -q "pkg.*Local Privilege Escalation" vulnerabilities.txt 2>/dev/null; then | |
| echo "- ✅ pkg vulnerability: Build-time only, no runtime impact" | |
| fi | |
| echo "" | |
| echo "See [SECURITY_ADVISORY.md](../SECURITY_ADVISORY.md) for detailed security information." | |
| else | |
| echo "✅ No vulnerabilities detected" | |
| fi | |
| fi | |
| } > security-report.md | |
| echo "📋 Security report generated:" | |
| cat security-report.md | |
| code-quality: | |
| 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: Check TypeScript types | |
| run: npx tsc --noEmit | |
| - name: Run comprehensive checks | |
| run: npm run check | |
| - name: Test template structures | |
| run: | | |
| echo "🔍 Testing template structures..." | |
| # Verify hero templates have required directories | |
| echo "Checking nextjs-fullstack..." | |
| test -d templates/nextjs-fullstack/src/components || { echo "❌ Missing components dir"; exit 1; } | |
| test -d templates/nextjs-fullstack/src/app || { echo "❌ Missing app dir"; exit 1; } | |
| test -d templates/nextjs-fullstack/public || { echo "❌ Missing public dir"; exit 1; } | |
| echo "✅ nextjs-fullstack structure valid" | |
| echo "Checking express-fullstack..." | |
| test -d templates/express-fullstack/src/client/components || { echo "❌ Missing client components dir"; exit 1; } | |
| test -d templates/express-fullstack/src/client/pages || { echo "❌ Missing client pages dir"; exit 1; } | |
| test -d templates/express-fullstack/public || { echo "❌ Missing public dir"; exit 1; } | |
| echo "✅ express-fullstack structure valid" | |
| echo "Checking react-spa-advanced..." | |
| test -d templates/react-spa-advanced/src/components || { echo "❌ Missing components dir"; exit 1; } | |
| test -d templates/react-spa-advanced/src/pages || { echo "❌ Missing pages dir"; exit 1; } | |
| test -d templates/react-spa-advanced/public || { echo "❌ Missing public dir"; exit 1; } | |
| echo "✅ react-spa-advanced structure valid" | |
| echo "✅ All template structures validated" | |
| compatibility: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| node-version: [20.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build and test | |
| run: | | |
| npm run build | |
| npm test | |
| - name: Test CLI on ${{ matrix.os }} | |
| run: | | |
| node dist/index.js --version | |
| node dist/index.js list --json |