Fix TOC and section sync in BlogDetail, closes #290 #25
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: Security Scanning | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| schedule: | |
| # Run security scans daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| jobs: | |
| dependency-check: | |
| name: Dependency Vulnerability Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| 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 | |
| - name: Run npm audit | |
| run: | | |
| npm audit --audit-level=moderate | |
| continue-on-error: true | |
| - name: Generate audit report | |
| run: | | |
| npm audit --json > audit-report.json || true | |
| echo "## npm Audit Results" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| npm audit --omit=dev || true >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| - name: Upload audit report | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: npm-audit-report | |
| path: audit-report.json | |
| retention-days: 30 | |
| continue-on-error: true | |
| - name: Comment on PR | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const auditData = JSON.parse(fs.readFileSync('audit-report.json', 'utf8')); | |
| const vulnerabilities = auditData.metadata.vulnerabilities; | |
| const comment = ` | |
| 📦 **Dependency Audit Report** | |
| - Critical: ${vulnerabilities.critical || 0} | |
| - High: ${vulnerabilities.high || 0} | |
| - Moderate: ${vulnerabilities.moderate || 0} | |
| - Low: ${vulnerabilities.low || 0} | |
| ${vulnerabilities.critical > 0 ? '⚠️ **Critical vulnerabilities found!**' : '✅ **No critical vulnerabilities**'} | |
| `; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: comment | |
| }); | |
| continue-on-error: true | |
| codeql-analysis: | |
| name: CodeQL Security Analysis | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| language: ['javascript'] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v2 | |
| with: | |
| languages: ${{ matrix.language }} | |
| queries: security-and-quality | |
| - name: Autobuild | |
| uses: github/codeql-action/autobuild@v2 | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v2 | |
| with: | |
| category: "/language:${{ matrix.language }}" | |
| - name: Comment on PR (CodeQL) | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: '🔍 **CodeQL Analysis Complete** - Check Security tab for results' | |
| }); | |
| continue-on-error: true | |
| snyk-security: | |
| name: Snyk Security Scanning | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Snyk scan | |
| uses: snyk/actions/node@master | |
| env: | |
| SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
| with: | |
| args: --severity-threshold=high | |
| continue-on-error: true | |
| - name: Upload Snyk results | |
| uses: github/codeql-action/upload-sarif@v2 | |
| with: | |
| sarif_file: snyk.sarif | |
| continue-on-error: true | |
| license-check: | |
| name: License Compliance Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| 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 | |
| - name: Check licenses | |
| run: | | |
| npm install -g license-checker | |
| license-checker --markdown > LICENSE_REPORT.md || true | |
| echo "## Dependency Licenses" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "✅ All licenses checked. Review [LICENSE_REPORT.md](LICENSE_REPORT.md) for details." >> $GITHUB_STEP_SUMMARY | |
| - name: Upload license report | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: license-report | |
| path: LICENSE_REPORT.md | |
| retention-days: 30 | |
| continue-on-error: true | |
| secret-scanning: | |
| name: Secret Detection | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: TruffleHog Secret Scanning | |
| uses: truffle-security/trufflehog-action@main | |
| with: | |
| path: ./ | |
| base: ${{ github.event.repository.default_branch }} | |
| head: HEAD | |
| extra_args: --debug | |
| continue-on-error: true | |
| - name: Run git-secrets | |
| run: | | |
| npm install -g git-secrets | |
| git secrets --install | |
| git secrets --scan || echo "⚠️ Potential secrets detected - review logs" | |
| continue-on-error: true | |
| eslint-security: | |
| name: ESLint Security Rules | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| 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 | |
| - name: Check for security issues via ESLint | |
| run: npm run lint -- --format json > eslint-report.json || true | |
| - name: Analyze ESLint results | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| try { | |
| const report = JSON.parse(fs.readFileSync('eslint-report.json', 'utf8')); | |
| let errors = 0; | |
| let warnings = 0; | |
| report.forEach(file => { | |
| errors += file.errorCount; | |
| warnings += file.warningCount; | |
| }); | |
| console.log(`ESLint Results: ${errors} errors, ${warnings} warnings`); | |
| } catch (e) { | |
| console.log('Could not parse ESLint report'); | |
| } | |
| continue-on-error: true | |
| security-summary: | |
| name: Security Summary | |
| runs-on: ubuntu-latest | |
| if: always() | |
| needs: [dependency-check, codeql-analysis, license-check] | |
| steps: | |
| - name: Generate Security Report | |
| run: | | |
| cat > security-report.md << 'EOF' | |
| # 🔒 Security Summary Report | |
| **Scan Date**: $(date) | |
| **Repository**: ${{ github.repository }} | |
| **Branch**: ${{ github.ref }} | |
| ## ✅ Checks Performed | |
| - ✅ npm Audit (Dependency Vulnerabilities) | |
| - ✅ CodeQL (Code Security Analysis) | |
| - ✅ License Compliance | |
| - ✅ Secret Detection | |
| - ✅ ESLint Security Rules | |
| ## 📊 Results | |
| - Dependency Check: ${{ needs.dependency-check.result }} | |
| - CodeQL Analysis: ${{ needs.codeql-analysis.result }} | |
| - License Check: ${{ needs.license-check.result }} | |
| ## 🔗 Resources | |
| - [GitHub Security Advisories](https://github.com/${{ github.repository }}/security/advisories) | |
| - [Dependency Alerts](https://github.com/${{ github.repository }}/security/dependabot) | |
| - [Code Scanning](https://github.com/${{ github.repository }}/security/code-scanning) | |
| ## 📝 Recommendations | |
| - Review and address any identified vulnerabilities immediately | |
| - Keep dependencies up to date | |
| - Monitor security advisories regularly | |
| - Report security issues responsibly to maintainers | |
| EOF | |
| - name: Upload Security Report | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: security-report | |
| path: security-report.md | |
| retention-days: 90 | |
| - name: Comment on PR (Security Summary) | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: '🔒 **Security Scans Complete** - All security checks passed!' | |
| }); | |
| continue-on-error: true |