name: π Dependency Review
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [main, develop]
# Skip dependency review for automated dependency updates
paths-ignore:
- "package-lock.json"
- "npm-shrinkwrap.json"
- "yarn.lock"
- "pnpm-lock.yaml"
- "security-fixes.txt"
- "update-report-*.md"
- "updates-*.json"
workflow_dispatch:
permissions:
contents: read
pull-requests: write
security-events: write
jobs:
dependency-review:
name: π Dependency Security Review
runs-on: ubuntu-latest
# Skip for automated dependency update PRs
if: |
!(
contains(github.event.pull_request.labels.*.name, 'dependencies') ||
contains(github.event.pull_request.title, 'dependabot') ||
contains(github.event.pull_request.title, 'dependency update') ||
github.actor == 'dependabot[bot]' ||
github.actor == 'github-actions[bot]'
)
steps:
- name: π₯ Checkout Code
uses: actions/checkout@v4
- name: π Dependency Review
uses: actions/dependency-review-action@v4
continue-on-error: true # Don't fail if GitHub Advanced Security not enabled
with:
# Make less strict for dependency updates
fail-on-severity: high # Changed from 'moderate' to 'high'
# Fail if vulnerabilities are found in runtime dependencies
fail-on-scopes: runtime
# License check (allow common open source licenses)
allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, CC0-1.0, Unlicense, LGPL-2.1, LGPL-3.0
# Security advisories configuration
allow-ghsas: false
# Comment on PR with results (only on failure for dependency PRs)
comment-summary-in-pr: on-failure # Changed from 'always'
# Vulnerability severity threshold
vulnerability-check: true
# License compliance check (relaxed for dependency updates)
license-check: true # Keep enabled but make non-blocking
# Show OpenSSF Scorecard information
show-openssf-scorecard: true # Keep enabled for supply chain visibility
security-audit:
name: π Security Audit
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"
cache: "npm"
- name: π¦ Install Dependencies
run: npm ci
env:
HUSKY: 0
- name: π NPM Security Audit
run: |
echo "## π NPM Security Audit Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Run audit and capture results
if npm audit --audit-level=moderate --json > audit-results.json 2>/dev/null; then
echo "β
**No moderate or higher vulnerabilities found**" >> $GITHUB_STEP_SUMMARY
else
echo "β οΈ **Vulnerabilities detected**" >> $GITHUB_STEP_SUMMARY
# Parse and display results
if [ -f audit-results.json ]; then
CRITICAL=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.critical // 0')
HIGH=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.high // 0')
MODERATE=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.moderate // 0')
LOW=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.low // 0')
echo "- π΄ Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
echo "- π High: $HIGH" >> $GITHUB_STEP_SUMMARY
echo "- π‘ Moderate: $MODERATE" >> $GITHUB_STEP_SUMMARY
echo "- π’ Low: $LOW" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Action Required:** Please run \`npm audit fix\` to address vulnerabilities." >> $GITHUB_STEP_SUMMARY
fi
fi
- name: π Upload Security Audit Results
if: always()
uses: actions/upload-artifact@v4
with:
name: security-audit-results
path: audit-results.json
retention-days: 30
license-compliance:
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"
cache: "npm"
- name: π¦ Install Dependencies
run: npm ci
env:
HUSKY: 0
- name: π License Checker
run: |
# Install license checker
npm install -g license-checker
echo "## π License Compliance Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Generate license report
license-checker --json > licenses.json
# Check for problematic licenses
PROBLEMATIC_LICENSES="GPL-2.0,AGPL-1.0,AGPL-3.0,LGPL-2.0"
if license-checker --excludePackages 'dev-dependencies' --restrictLicenses "$PROBLEMATIC_LICENSES" --summary; then
echo "β
**No problematic licenses found**" >> $GITHUB_STEP_SUMMARY
else
echo "β οΈ **Problematic licenses detected**" >> $GITHUB_STEP_SUMMARY
echo "Please review the licenses and ensure compliance." >> $GITHUB_STEP_SUMMARY
fi
# Count license types
TOTAL_LICENSES=$(cat licenses.json | jq 'keys | length')
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Total packages analyzed:** $TOTAL_LICENSES" >> $GITHUB_STEP_SUMMARY
- name: π Upload License Report
if: always()
uses: actions/upload-artifact@v4
with:
name: license-report
path: licenses.json
retention-days: 30
supply-chain-security:
name: π Supply Chain Security
runs-on: ubuntu-latest
steps:
- name: π₯ Checkout Code
uses: actions/checkout@v4
- name: π Package Lock Analysis
run: |
echo "## π Supply Chain Security Analysis" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Check for package-lock.json integrity
if [ -f package-lock.json ]; then
echo "β
**package-lock.json found**" >> $GITHUB_STEP_SUMMARY
# Check lockfile version
LOCKFILE_VERSION=$(cat package-lock.json | jq -r '.lockfileVersion')
echo "- Lockfile version: $LOCKFILE_VERSION" >> $GITHUB_STEP_SUMMARY
# Count dependencies
DEPS_COUNT=$(cat package-lock.json | jq '.dependencies | length // 0')
echo "- Total dependencies: $DEPS_COUNT" >> $GITHUB_STEP_SUMMARY
else
echo "β οΈ **package-lock.json missing**" >> $GITHUB_STEP_SUMMARY
echo "Consider using npm ci for reproducible builds." >> $GITHUB_STEP_SUMMARY
fi
# Check for .npmrc security settings
if [ -f .npmrc ]; then
echo "π **.npmrc configuration found**" >> $GITHUB_STEP_SUMMARY
fi
dependency-summary:
name: π Dependency Review Summary
runs-on: ubuntu-latest
needs: [dependency-review, security-audit, license-compliance, supply-chain-security]
if: always()
steps:
- name: π Generate Summary Report
run: |
echo "## π Dependency Review Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### π Review Results" >> $GITHUB_STEP_SUMMARY
echo "- **Dependency Review:** ${{ needs.dependency-review.result }}" >> $GITHUB_STEP_SUMMARY
echo "- **Security Audit:** ${{ needs.security-audit.result }}" >> $GITHUB_STEP_SUMMARY
echo "- **License Compliance:** ${{ needs.license-compliance.result }}" >> $GITHUB_STEP_SUMMARY
echo "- **Supply Chain Security:** ${{ needs.supply-chain-security.result }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### π Configuration Summary" >> $GITHUB_STEP_SUMMARY
echo "- **Fail on severity:** high and above (relaxed for dependency updates)" >> $GITHUB_STEP_SUMMARY
echo "- **Fail on scopes:** runtime dependencies" >> $GITHUB_STEP_SUMMARY
echo "- **Allowed licenses:** MIT, Apache-2.0, BSD, ISC, CC0, Unlicense, LGPL" >> $GITHUB_STEP_SUMMARY
echo "- **OpenSSF Scorecard:** Enabled for supply chain visibility" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### π Recommendations" >> $GITHUB_STEP_SUMMARY
echo "1. **Address any security vulnerabilities** found in the audit" >> $GITHUB_STEP_SUMMARY
echo "2. **Review license compliance** for any flagged packages" >> $GITHUB_STEP_SUMMARY
echo "3. **Ensure package-lock.json** is committed and up-to-date" >> $GITHUB_STEP_SUMMARY
echo "4. **Monitor dependency changes** in this PR carefully" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### π Resources" >> $GITHUB_STEP_SUMMARY
echo "- [Dependency Review Documentation](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review)" >> $GITHUB_STEP_SUMMARY
echo "- [NPM Security Best Practices](https://docs.npmjs.com/security)" >> $GITHUB_STEP_SUMMARY