chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /web #59
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
| # .github/workflows/go-quality-check.yml (安全修复版本) | |
| name: Go Code Quality Check | |
| # 🔒 工作流级权限控制 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| actions: read | |
| on: | |
| pull_request: | |
| branches: [main, master, develop] | |
| paths: | |
| - "**/*.go" | |
| - "go.mod" | |
| - "go.sum" | |
| - "server/**" | |
| - "pkg/**" | |
| - "coraza-spoa/**" | |
| - "go.work" | |
| # 专门用于 PR 评论的触发器 | |
| pull_request_target: | |
| types: [opened, synchronize, reopened] | |
| branches: [main, master, develop] | |
| push: | |
| branches: [main, master, develop] | |
| paths: | |
| - "**/*.go" | |
| - "go.mod" | |
| - "go.sum" | |
| - "server/**" | |
| - "pkg/**" | |
| - "coraza-spoa/**" | |
| - "go.work" | |
| workflow_dispatch: | |
| jobs: | |
| # 主要的 CI 检查 job(使用 pull_request,安全执行外部代码) | |
| go-check: | |
| name: Go Code Quality Check | |
| runs-on: ubuntu-latest | |
| # 只在 pull_request 和 push 事件时运行,不在 pull_request_target 时运行 | |
| if: github.event_name != 'pull_request_target' | |
| outputs: | |
| format-issues: ${{ steps.set-status.outputs.format_issues }} | |
| format-files: ${{ steps.set-status.outputs.format_files }} | |
| style-suggestions-found: ${{ steps.set-status.outputs.style_suggestions_found }} | |
| style-suggestions-count: ${{ steps.set-status.outputs.style_suggestions_count }} | |
| style-suggestions: ${{ steps.set-status.outputs.style_suggestions }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.24.1" | |
| # 缓存 Go 模块 | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go- | |
| # 检查 Go 代码格式 | |
| - name: Check Go formatting | |
| run: | | |
| echo "🔍 检查 Go 代码格式..." | |
| unformatted=$(gofmt -l .) | |
| if [ ! -z "$unformatted" ]; then | |
| echo "⚠️ 以下文件格式需要优化:" | |
| echo "$unformatted" | |
| echo "" | |
| echo "💡 建议运行 'gofmt -w .' 来格式化代码" | |
| echo "FORMAT_ISSUES=true" >> $GITHUB_ENV | |
| echo "FORMAT_FILES<<EOF" >> $GITHUB_ENV | |
| echo "$unformatted" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| else | |
| echo "✅ Go 代码格式正确" | |
| echo "FORMAT_ISSUES=false" >> $GITHUB_ENV | |
| echo "FORMAT_FILES=" >> $GITHUB_ENV | |
| fi | |
| continue-on-error: true | |
| # 运行 go vet | |
| - name: Run go vet | |
| run: | | |
| echo "🔍 运行 go vet..." | |
| failed=false | |
| if [ -d "server" ]; then | |
| echo "检查 server 模块..." | |
| cd server && go vet ./... || failed=true | |
| cd .. | |
| fi | |
| if [ -d "pkg" ]; then | |
| echo "检查 pkg 模块..." | |
| cd pkg && go vet ./... || failed=true | |
| cd .. | |
| fi | |
| if [ -d "coraza-spoa" ]; then | |
| echo "检查 coraza-spoa 模块..." | |
| cd coraza-spoa && go vet ./... || failed=true | |
| cd .. | |
| fi | |
| if [ "$failed" = "true" ]; then | |
| echo "❌ go vet 发现重要问题" | |
| exit 1 | |
| fi | |
| echo "✅ go vet 检查通过" | |
| # 运行 staticcheck(核心检查 + 详细风格建议) | |
| - name: Run staticcheck | |
| run: | | |
| go install honnef.co/go/tools/cmd/staticcheck@latest | |
| echo "🔍 运行 staticcheck..." | |
| # 核心检查(bug、性能和安全问题) | |
| critical_checks="SA,S1,QF,ST1001,ST1005,ST1006,ST1008,ST1011,ST1012,ST1013,ST1015,ST1016,ST1017,ST1018,ST1019" | |
| critical_failed=false | |
| echo "📋 执行核心质量检查..." | |
| for module in server pkg coraza-spoa; do | |
| if [ -d "$module" ]; then | |
| echo "核心检查 $module 模块..." | |
| cd "$module" && staticcheck -checks "$critical_checks" ./... || critical_failed=true | |
| cd .. | |
| fi | |
| done | |
| # 风格检查(详细输出) | |
| echo "" | |
| echo "📝 检查代码风格建议..." | |
| style_checks="ST1000,ST1003,ST1020,ST1021,ST1023" | |
| style_output="" | |
| style_count=0 | |
| for module in server pkg coraza-spoa; do | |
| if [ -d "$module" ]; then | |
| echo "风格检查 $module 模块..." | |
| module_style_output=$(cd "$module" && staticcheck -checks "$style_checks" ./... 2>/dev/null || true) | |
| if [ ! -z "$module_style_output" ]; then | |
| style_output="${style_output}${module_style_output}\n" | |
| module_count=$(echo "$module_style_output" | wc -l) | |
| style_count=$((style_count + module_count)) | |
| fi | |
| fi | |
| done | |
| # 保存风格建议到环境变量 | |
| echo "STYLE_SUGGESTIONS_COUNT=$style_count" >> $GITHUB_ENV | |
| if [ $style_count -gt 0 ]; then | |
| echo "STYLE_SUGGESTIONS_FOUND=true" >> $GITHUB_ENV | |
| echo "STYLE_SUGGESTIONS<<EOF" >> $GITHUB_ENV | |
| echo -e "$style_output" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| echo "ℹ️ 发现 $style_count 个代码风格改进点(不影响功能)" | |
| else | |
| echo "STYLE_SUGGESTIONS_FOUND=false" >> $GITHUB_ENV | |
| echo "STYLE_SUGGESTIONS=" >> $GITHUB_ENV | |
| echo "✨ 代码风格很棒!" | |
| fi | |
| # 检查核心问题结果 | |
| if [ "$critical_failed" = "true" ]; then | |
| echo "❌ staticcheck 发现重要问题需要修复" | |
| exit 1 | |
| fi | |
| echo "✅ staticcheck 核心检查通过" | |
| # 运行测试 | |
| - name: Run tests | |
| run: | | |
| echo "🧪 运行 Go 测试..." | |
| test_failed=false | |
| for module in server pkg coraza-spoa; do | |
| if [ -d "$module" ]; then | |
| echo "测试 $module 模块..." | |
| cd "$module" && go test -v -race -coverprofile=coverage.out ./... || test_failed=true | |
| cd .. | |
| fi | |
| done | |
| if [ "$test_failed" = "true" ]; then | |
| echo "❌ 测试失败" | |
| exit 1 | |
| fi | |
| echo "✅ 所有测试通过" | |
| # 使用官方 govulncheck-action 检查安全漏洞(支持多模块) | |
| - name: Run govulncheck for server module | |
| if: always() | |
| uses: golang/govulncheck-action@v1 | |
| with: | |
| work-dir: server | |
| go-package: ./... | |
| continue-on-error: true | |
| - name: Run govulncheck for pkg module | |
| if: always() | |
| uses: golang/govulncheck-action@v1 | |
| with: | |
| work-dir: pkg | |
| go-package: ./... | |
| continue-on-error: true | |
| - name: Run govulncheck for coraza-spoa module | |
| if: always() | |
| uses: golang/govulncheck-action@v1 | |
| with: | |
| work-dir: coraza-spoa | |
| go-package: ./... | |
| continue-on-error: true | |
| # 📤 设置输出状态(修复VS Code警告) | |
| - name: Set job outputs | |
| id: set-status | |
| if: always() | |
| run: | | |
| echo "format_issues=${FORMAT_ISSUES:-false}" >> $GITHUB_OUTPUT | |
| echo "format_files=${FORMAT_FILES:-}" >> $GITHUB_OUTPUT | |
| echo "style_suggestions_found=${STYLE_SUGGESTIONS_FOUND:-false}" >> $GITHUB_OUTPUT | |
| echo "style_suggestions_count=${STYLE_SUGGESTIONS_COUNT:-0}" >> $GITHUB_OUTPUT | |
| echo "style_suggestions=${STYLE_SUGGESTIONS:-}" >> $GITHUB_OUTPUT | |
| # 生成详细检查报告 | |
| - name: Generate Go check summary | |
| if: always() | |
| run: | | |
| echo "## ⚡ Go Code Quality Check Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # 检查状态 | |
| echo "### 📋 Core Check Results" >> $GITHUB_STEP_SUMMARY | |
| echo "| Check Item | Status | Description |" >> $GITHUB_STEP_SUMMARY | |
| echo "|---------|------|------|" >> $GITHUB_STEP_SUMMARY | |
| # 格式检查状态 | |
| if [ "$FORMAT_ISSUES" = "true" ]; then | |
| echo "| Code Formatting | ⚠️ Suggestions Available | Found formatting improvement points |" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| Code Formatting | ✅ Passed | Standard formatting |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "| go vet | ✅ Passed | No important issues |" >> $GITHUB_STEP_SUMMARY | |
| echo "| staticcheck (core) | ✅ Passed | No bugs or security issues |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Unit Tests | ✅ Passed | Functionality verified |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Security Check | ✅ Passed | Using official govulncheck-action |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # 详细改进建议 | |
| if [ "$FORMAT_ISSUES" = "true" ] || [ "$STYLE_SUGGESTIONS_FOUND" = "true" ]; then | |
| echo "### 💡 Optional Improvement Suggestions" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "$FORMAT_ISSUES" = "true" ]; then | |
| echo "#### 🎨 Code Formatting Optimization" >> $GITHUB_STEP_SUMMARY | |
| echo "The following files can be formatted using \`gofmt -w .\`:" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "$FORMAT_FILES" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if [ "$STYLE_SUGGESTIONS_FOUND" = "true" ]; then | |
| echo "#### 📝 Code Style Suggestions (${STYLE_SUGGESTIONS_COUNT} items)" >> $GITHUB_STEP_SUMMARY | |
| echo "The following are staticcheck style suggestions, which can be adopted based on team standards:" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "$STYLE_SUGGESTIONS" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| fi | |
| # 代码质量概览 | |
| echo "### 📊 Code Quality Overview" >> $GITHUB_STEP_SUMMARY | |
| echo "- **🔧 Core Quality**: Passed all important checks" >> $GITHUB_STEP_SUMMARY | |
| echo "- **🧪 Functionality Verification**: Complete test coverage" >> $GITHUB_STEP_SUMMARY | |
| echo "- **🔒 Security Check**: Module-wise scanning using official govulncheck-action" >> $GITHUB_STEP_SUMMARY | |
| echo "- **🏗️ Project Structure**: Complete multi-module workspace support" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 📊 Project Information" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Go Version**: 1.24.1" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Check Strategy**: Module-wise checks (server, pkg, coraza-spoa)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Commit SHA**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Branch**: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Triggered by**: @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Check Time**: $(date '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY | |
| # 🔒 安全的 PR 评论 job(使用 pull_request_target,但不 checkout 外部代码) | |
| pr-comment: | |
| name: PR Comment Handler | |
| runs-on: ubuntu-latest | |
| # 只在 pull_request_target 事件时运行 | |
| if: github.event_name == 'pull_request_target' | |
| steps: | |
| # 🔒 重要:不 checkout 任何代码,特别是 PR 代码! | |
| # 🔒 只使用 GitHub API 获取工作流运行结果 | |
| - name: Wait for main check to complete | |
| uses: actions/github-script@v7 | |
| id: wait-for-check | |
| with: | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const headSha = context.payload.pull_request.head.sha; | |
| console.log(`等待 commit ${headSha} 的检查完成...`); | |
| // 等待最多 10 分钟 | |
| const maxWaitTime = 10 * 60 * 1000; // 10 minutes | |
| const startTime = Date.now(); | |
| while (Date.now() - startTime < maxWaitTime) { | |
| try { | |
| // 获取 commit 的所有 check runs | |
| const { data: checkRuns } = await github.rest.checks.listForRef({ | |
| owner, | |
| repo, | |
| ref: headSha, | |
| }); | |
| // 查找我们的Go检查工作流 | |
| const goCheck = checkRuns.check_runs.find(run => | |
| run.name === 'Go Code Quality Check' | |
| ); | |
| if (goCheck) { | |
| console.log(`发现检查: ${goCheck.name}, 状态: ${goCheck.status}`); | |
| if (goCheck.status === 'completed') { | |
| console.log(`检查完成,结论: ${goCheck.conclusion}`); | |
| return { | |
| completed: true, | |
| conclusion: goCheck.conclusion, | |
| details_url: goCheck.details_url | |
| }; | |
| } | |
| } | |
| // 等待 30 秒后重试 | |
| await new Promise(resolve => setTimeout(resolve, 30000)); | |
| } catch (error) { | |
| console.log(`获取检查状态时出错: ${error.message}`); | |
| await new Promise(resolve => setTimeout(resolve, 30000)); | |
| } | |
| } | |
| // 超时情况 | |
| console.log('等待超时,使用默认值'); | |
| return { | |
| completed: false, | |
| conclusion: 'timed_out', | |
| details_url: null | |
| }; | |
| - name: Comment on PR | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const checkResult = ${{ steps.wait-for-check.outputs.result }}; | |
| const prNumber = context.payload.pull_request.number; | |
| let emoji, statusEn, statusCn, conclusion; | |
| if (!checkResult.completed) { | |
| emoji = '⏰'; | |
| statusEn = 'In Progress'; | |
| statusCn = '进行中'; | |
| conclusion = 'pending'; | |
| } else { | |
| switch(checkResult.conclusion) { | |
| case 'success': | |
| emoji = '✅'; | |
| statusEn = 'Passed'; | |
| statusCn = '通过'; | |
| conclusion = 'success'; | |
| break; | |
| case 'failure': | |
| emoji = '❌'; | |
| statusEn = 'Failed'; | |
| statusCn = '失败'; | |
| conclusion = 'failure'; | |
| break; | |
| default: | |
| emoji = '⚠️'; | |
| statusEn = 'Unknown'; | |
| statusCn = '未知'; | |
| conclusion = 'neutral'; | |
| } | |
| } | |
| // 构建中文报告 | |
| let chineseReport = `### 中文报告\n\n`; | |
| if (!checkResult.completed) { | |
| chineseReport += `**⏰ 状态:** Go 代码质量检查正在进行中,请稍候查看结果。`; | |
| } else if (checkResult.conclusion === 'success') { | |
| chineseReport += `**🎉 结果:** Go 代码核心质量检查全部通过!代码功能稳定可靠。\n\n`; | |
| chineseReport += `**📋 核心检查项目:**\n`; | |
| chineseReport += `- ✅ go vet 静态分析\n`; | |
| chineseReport += `- ✅ staticcheck 核心检查(bug & 安全)\n`; | |
| chineseReport += `- ✅ 单元测试\n`; | |
| chineseReport += `- ✅ 安全检查(官方 govulncheck-action)\n`; | |
| chineseReport += `- ✅ 代码格式检查\n\n`; | |
| chineseReport += `**🔧 多模块支持:** 已分别检查 server、pkg、coraza-spoa 三个模块。`; | |
| } else if (checkResult.conclusion === 'failure') { | |
| chineseReport += `**⚠️ 需要关注:** 发现需要修复的重要问题,请查看详细日志。\n\n`; | |
| chineseReport += `点击下方链接查看详细检查结果。`; | |
| } else { | |
| chineseReport += `**ℹ️ 状态:** 检查状态异常,请检查工作流配置。`; | |
| } | |
| // 构建英文报告 | |
| let englishReport = `### English Report\n\n`; | |
| if (!checkResult.completed) { | |
| englishReport += `**⏰ Status:** Go code quality check is in progress, please wait for results.`; | |
| } else if (checkResult.conclusion === 'success') { | |
| englishReport += `**🎉 Result:** All Go code quality checks passed! Code is stable and reliable.\n\n`; | |
| englishReport += `**📋 Core Checks:**\n`; | |
| englishReport += `- ✅ go vet static analysis\n`; | |
| englishReport += `- ✅ staticcheck core checks (bugs & security)\n`; | |
| englishReport += `- ✅ unit tests\n`; | |
| englishReport += `- ✅ security scan (official govulncheck-action)\n`; | |
| englishReport += `- ✅ code formatting check\n\n`; | |
| englishReport += `**🔧 Multi-module Support:** Checked server, pkg, and coraza-spoa modules separately.`; | |
| } else if (checkResult.conclusion === 'failure') { | |
| englishReport += `**⚠️ Attention Required:** Important issues found that need to be fixed. Please check the detailed logs.\n\n`; | |
| englishReport += `Click the link below to view detailed check results.`; | |
| } else { | |
| englishReport += `**ℹ️ Status:** Check status is abnormal, please check workflow configuration.`; | |
| } | |
| // 组合最终内容 | |
| let body = `## ⚡ Go Code Quality Check ${statusEn} ${emoji}\n\n`; | |
| body += `**PR #${prNumber}** Go code quality check completed.\n\n`; | |
| body += `${chineseReport}\n\n---\n\n${englishReport}`; | |
| // 如果有详细链接,添加到报告中 | |
| if (checkResult.details_url) { | |
| body += `\n\n**🔗 View Details:** [Click here to see the full check results](${checkResult.details_url})`; | |
| } | |
| // 查找并更新现有评论 | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('⚡ Go Code Quality Check') | |
| ); | |
| if (botComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: body | |
| }); | |
| console.log('已更新现有的 PR 评论'); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body: body | |
| }); | |
| console.log('已创建新的 PR 评论'); | |
| } |