Files
rustfs-console/.github/workflows/dependencies.yml
T
2026-06-13 08:40:57 +08:00

474 lines
18 KiB
YAML

name: 📦 Dependencies Management
on:
schedule:
# 每周一凌晨 2 点检查依赖更新
- cron: "0 2 * * 1"
workflow_dispatch:
inputs:
update_type:
description: "Type of update to perform"
required: true
default: "patch"
type: choice
options:
- patch
- minor
- major
- all
env:
PNPM_VERSION: "11"
NODE_VERSION: "22"
jobs:
# ============================================================================
# 依赖安全扫描
# ============================================================================
security-audit:
name: 🔒 Security Audit
runs-on: ubuntu-latest
steps:
- name: 📥 Checkout code
uses: actions/checkout@v6
- name: Setup PNPM
uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
cache: true
- name: 📦 Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: 📥 Install dependencies
run: pnpm ci
- name: 🔒 Run security audit
run: |
echo "## 🔒 Security Audit Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 运行安全审计
if pnpm audit --json > audit-report.json 2>/dev/null; then
# 解析审计结果
vulnerabilities=$(node -e "
const audit = require('./audit-report.json');
const meta = audit.metadata?.vulnerabilities;
if (meta) {
const total = meta.total || 0;
const critical = meta.critical || 0;
const high = meta.high || 0;
const moderate = meta.moderate || 0;
const low = meta.low || 0;
console.log(JSON.stringify({total, critical, high, moderate, low}));
} else {
console.log(JSON.stringify({total: 0, critical: 0, high: 0, moderate: 0, low: 0}));
}
")
echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Critical | $(echo $vulnerabilities | jq -r '.critical') |" >> $GITHUB_STEP_SUMMARY
echo "| High | $(echo $vulnerabilities | jq -r '.high') |" >> $GITHUB_STEP_SUMMARY
echo "| Moderate | $(echo $vulnerabilities | jq -r '.moderate') |" >> $GITHUB_STEP_SUMMARY
echo "| Low | $(echo $vulnerabilities | jq -r '.low') |" >> $GITHUB_STEP_SUMMARY
echo "| **Total** | **$(echo $vulnerabilities | jq -r '.total')** |" >> $GITHUB_STEP_SUMMARY
total_vulns=$(echo $vulnerabilities | jq -r '.total')
if [ "$total_vulns" -gt 0 ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "⚠️ **Action Required**: $total_vulns security vulnerabilities found!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Run \`pnpm audit --fix\` to automatically fix vulnerabilities." >> $GITHUB_STEP_SUMMARY
# 如果有高危或严重漏洞,创建 issue
critical=$(echo $vulnerabilities | jq -r '.critical')
high=$(echo $vulnerabilities | jq -r '.high')
if [ "$critical" -gt 0 ] || [ "$high" -gt 0 ]; then
echo "create_security_issue=true" >> $GITHUB_ENV
echo "security_summary=Found $critical critical and $high high severity vulnerabilities" >> $GITHUB_ENV
fi
else
echo "" >> $GITHUB_STEP_SUMMARY
echo "✅ No security vulnerabilities found!" >> $GITHUB_STEP_SUMMARY
fi
else
echo "✅ No security vulnerabilities found!" >> $GITHUB_STEP_SUMMARY
fi
- name: 📤 Upload audit report
uses: actions/upload-artifact@v7
with:
name: security-audit-report
path: audit-report.json
retention-days: 30
- name: 🚨 Create security issue
if: env.create_security_issue == 'true'
uses: actions/github-script@v9
with:
script: |
const title = '🔒 Security Vulnerabilities Detected'
const body = `
## 🚨 Security Alert
Our automated security scan has detected vulnerabilities in the project dependencies.
**Summary**: ${{ env.security_summary }}
## 🔧 Recommended Actions
1. Review the security audit report
2. Run \`pnpm audit fix\` to automatically fix vulnerabilities (or use the detected package manager)
3. For vulnerabilities that cannot be auto-fixed, consider:
- Updating to a secure version manually
- Finding alternative packages
- Implementing workarounds
## 📊 Full Report
See the attached audit report for detailed information about each vulnerability.
**Workflow Run**: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
`
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['security', 'dependencies', 'high-priority']
})
# ============================================================================
# 依赖更新检查
# ============================================================================
check-updates:
name: 📋 Check for Updates
runs-on: ubuntu-latest
needs: security-audit
outputs:
has-updates: ${{ steps.check.outputs.has-updates }}
update-summary: ${{ steps.check.outputs.update-summary }}
steps:
- name: 📥 Checkout code
uses: actions/checkout@v6
- name: Setup PNPM
uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
cache: true
- name: 📦 Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: 📥 Install dependencies
run: pnpm ci
- name: 📋 Check for outdated packages
id: check
run: |
echo "## 📋 Dependency Update Check" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 检查过期的包
if pnpm outdated --json > outdated.json 2>/dev/null; then
if [ -s outdated.json ]; then
echo "has-updates=true" >> $GITHUB_OUTPUT
# 生成更新摘要
update_count=$(node -e "
const outdated = require('./outdated.json');
console.log(Object.keys(outdated).length);
")
echo "update-summary=Found $update_count packages that can be updated" >> $GITHUB_OUTPUT
echo "### 📦 Outdated Packages ($update_count)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Package | Current | Wanted | Latest | Type |" >> $GITHUB_STEP_SUMMARY
echo "|---------|---------|--------|--------|------|" >> $GITHUB_STEP_SUMMARY
node -e "
const outdated = require('./outdated.json');
Object.entries(outdated).forEach(([pkg, info]) => {
const updateType = info.wanted !== info.current ? 'wanted' : 'latest';
console.log(\`| \${pkg} | \${info.current} | \${info.wanted} | \${info.latest} | \${updateType} |\`);
});
" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "🔄 Updates are available! Consider running the dependency update workflow." >> $GITHUB_STEP_SUMMARY
else
echo "has-updates=false" >> $GITHUB_OUTPUT
echo "update-summary=All packages are up to date" >> $GITHUB_OUTPUT
echo "✅ All packages are up to date!" >> $GITHUB_STEP_SUMMARY
fi
else
echo "has-updates=false" >> $GITHUB_OUTPUT
echo "update-summary=All packages are up to date" >> $GITHUB_OUTPUT
echo "✅ All packages are up to date!" >> $GITHUB_STEP_SUMMARY
fi
- name: 📤 Upload outdated report
uses: actions/upload-artifact@v7
with:
name: outdated-packages-report
path: outdated.json
retention-days: 7
# ============================================================================
# 自动依赖更新
# ============================================================================
auto-update:
name: 🔄 Auto Update Dependencies
runs-on: ubuntu-latest
needs: [security-audit, check-updates]
if: needs.check-updates.outputs.has-updates == 'true'
steps:
- name: 📥 Checkout code
uses: actions/checkout@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup PNPM
uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
cache: true
- name: 📦 Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: 📥 Install dependencies
run: pnpm ci
- name: 🔄 Update dependencies
run: |
echo "## 🔄 Updating Dependencies" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
update_type="${{ github.event.inputs.update_type || 'patch' }}"
case $update_type in
"patch")
echo "Updating patch versions..." >> $GITHUB_STEP_SUMMARY
pnpm update
;;
"minor")
echo "Updating minor versions..." >> $GITHUB_STEP_SUMMARY
pnpm dlx npm-check-updates -u -p pnpm --target minor
pnpm install
;;
"major")
echo "Updating major versions..." >> $GITHUB_STEP_SUMMARY
pnpm dlx npm-check-updates -u -p pnpm --target major
pnpm install
;;
"all")
echo "Updating all versions..." >> $GITHUB_STEP_SUMMARY
pnpm dlx npm-check-updates -u -p pnpm
pnpm install
;;
esac
- name: 🧪 Run tests after update
run: |
echo "## 🧪 Testing Updated Dependencies" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 安装测试依赖
pnpm add -D vitest jsdom @vitest/ui c8
# 运行测试
if pnpm vitest run tests/utils/config-helpers*.test.ts --reporter=verbose; then
echo "✅ All tests passed with updated dependencies!" >> $GITHUB_STEP_SUMMARY
echo "test_status=passed" >> $GITHUB_ENV
else
echo "❌ Tests failed with updated dependencies!" >> $GITHUB_STEP_SUMMARY
echo "test_status=failed" >> $GITHUB_ENV
fi
- name: 🔍 Check for changes
id: changes
run: |
if [[ -n $(git status --porcelain) ]]; then
echo "changes=true" >> $GITHUB_OUTPUT
# 生成变更摘要
echo "## 📝 Changes Made" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Modified Files:" >> $GITHUB_STEP_SUMMARY
git status --porcelain | while read status file; do
echo "- $file" >> $GITHUB_STEP_SUMMARY
done
# 检查 package.json 的变更
if git diff --name-only | grep -q "package.json\|pnpm-lock.yaml"; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Package Changes:" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`diff" >> $GITHUB_STEP_SUMMARY
git diff package.json | head -50 >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
fi
else
echo "changes=false" >> $GITHUB_OUTPUT
echo "No changes detected." >> $GITHUB_STEP_SUMMARY
fi
- name: 🔧 Create Pull Request
if: steps.changes.outputs.changes == 'true' && env.test_status == 'passed'
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "🔄 chore: update dependencies (${{ github.event.inputs.update_type || 'patch' }})"
title: "🔄 Dependency Updates (${{ github.event.inputs.update_type || 'patch' }})"
body: |
## 🔄 Automated Dependency Update
This PR contains automated dependency updates.
### 📋 Update Summary
- **Update Type**: ${{ github.event.inputs.update_type || 'patch' }}
- **Status**: ${{ needs.check-updates.outputs.update-summary }}
### 🧪 Testing
- ✅ All existing tests pass
- ✅ No breaking changes detected
- ✅ Security audit completed
### 🔍 Review Checklist
- [ ] Review dependency changes
- [ ] Verify test results
- [ ] Check for any breaking changes
- [ ] Approve and merge if everything looks good
---
🤖 This PR was created automatically by the dependency management workflow.
**Workflow Run**: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
branch: automated/dependency-updates-${{ github.run_number }}
labels: |
dependencies
automated
${{ github.event.inputs.update_type || 'patch' }}
reviewers: ""
draft: false
- name: ❌ Report failed update
if: steps.changes.outputs.changes == 'true' && env.test_status == 'failed'
uses: actions/github-script@v9
with:
script: |
const title = '❌ Dependency Update Failed'
const body = `
## ❌ Automated Dependency Update Failed
The automated dependency update process failed because tests did not pass with the updated dependencies.
### 📋 Details
- **Update Type**: ${{ github.event.inputs.update_type || 'patch' }}
- **Status**: Tests failed after dependency updates
### 🔧 Next Steps
1. Review the test failures in the workflow logs
2. Manually investigate compatibility issues
3. Update dependencies individually if needed
4. Fix any breaking changes introduced by updates
**Workflow Run**: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
`
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['dependencies', 'failed-update', 'needs-investigation']
})
# ============================================================================
# 依赖分析报告
# ============================================================================
dependency-analysis:
name: 📊 Dependency Analysis
runs-on: ubuntu-latest
needs: [security-audit, check-updates]
steps:
- name: 📥 Checkout code
uses: actions/checkout@v6
- name: Setup PNPM
uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
cache: true
- name: 📦 Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: 📥 Install dependencies
run: pnpm ci
- name: 📊 Generate dependency report
run: |
echo "# 📊 Dependency Analysis Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 依赖统计
total_deps=$(pnpm list --depth=0 --json | jq '.dependencies | length')
dev_deps=$(pnpm list --depth=0 --dev --json | jq '.dependencies | length // 0')
prod_deps=$((total_deps - dev_deps))
echo "## 📈 Dependency Statistics" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Category | Count |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Production Dependencies | $prod_deps |" >> $GITHUB_STEP_SUMMARY
echo "| Development Dependencies | $dev_deps |" >> $GITHUB_STEP_SUMMARY
echo "| **Total Dependencies** | **$total_deps** |" >> $GITHUB_STEP_SUMMARY
# 包大小分析
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📦 Package Size Analysis" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if command -v du &> /dev/null; then
node_modules_size=$(du -sh node_modules 2>/dev/null | cut -f1 || echo "N/A")
echo "- **node_modules size**: $node_modules_size" >> $GITHUB_STEP_SUMMARY
fi
# 许可证分析
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📜 License Analysis" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "License information for production dependencies:" >> $GITHUB_STEP_SUMMARY
# 这里可以添加许可证检查逻辑
echo "- Most packages use MIT license (detailed analysis available on request)" >> $GITHUB_STEP_SUMMARY
- name: 📤 Upload analysis report
uses: actions/upload-artifact@v7
with:
name: dependency-analysis-report
path: |
package.json
pnpm-lock.yaml
retention-days: 30