const fs = require('fs'); const path = require('path'); const summaryPath = path.resolve(__dirname, '../server/coverage/coverage-summary.json'); if (!fs.existsSync(summaryPath)) { console.error("No coverage summary found. Run 'npm run test:coverage' first."); process.exit(1); } const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf8')); // 初始阈值仅关键模块 lines>=70%,全局先告警 const KEY_MODULES = [ "src/services/featureFlags", "src/services/verification", "src/services/integrations/dispatcher.js", "src/services/integrations/outbox.js", "src/services/integrations/erp.js", "src/utils/workflow.js" ]; let allPassed = true; const messages = []; for (const [file, stats] of Object.entries(summary)) { if (file === "total") continue; const isKeyModule = KEY_MODULES.some(key => file.includes(key)); if (isKeyModule) { const linesCov = stats.lines.pct; if (linesCov < 70) { allPassed = false; messages.push(`FAIL: ${file} lines coverage is ${linesCov}%, which is below the 70% threshold.`); } else { messages.push(`PASS: ${file} lines coverage is ${linesCov}% (>= 70%).`); } } } const globalLines = summary.total?.lines?.pct ?? 0; messages.push(`Global lines coverage is ${globalLines}%. (Warn-only)`); console.log("=== Coverage Gate Report ==="); console.log(messages.join("\n")); if (process.env.GITHUB_STEP_SUMMARY) { fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, `\n## Coverage Gate\n\n\`\`\`text\n${messages.join("\n")}\n\`\`\`\n`); } const isPR = process.env.GITHUB_EVENT_NAME === "pull_request"; if (!allPassed) { if (isPR) { console.log("WARN: Coverage is below threshold. PRs will not be blocked currently, but please fix it."); process.exit(0); } else { console.error("ERROR: Coverage is below threshold and the branch is NOT a PR. Failing the gate."); process.exit(1); } } else { console.log("Coverage gate passed successfully."); process.exit(0); }