Skip to content

chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /web #59

chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /web

chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /web #59

# .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 评论');
}