180 lines
7.2 KiB
JavaScript
180 lines
7.2 KiB
JavaScript
import { executeProjectScan } from "./projectScan.js";
|
||
import { executeLintCheck } from "./lintCheck.js";
|
||
import { executeAutoFix } from "./autoFix.js";
|
||
import { executeBuildProject } from "./buildProject.js";
|
||
import { executeRunTests } from "./runTests.js";
|
||
import { executeGitOps } from "./gitOps.js";
|
||
import { executeDepManage } from "./depManage.js";
|
||
export const workflowTool = {
|
||
name: "workflow",
|
||
description: "自动化工作流编排。串联多个工具形成流水线,一键执行完整开发流程。内置多种预设流程(全量检查、CI 模拟、项目初始化等),也支持自定义步骤。",
|
||
inputSchema: {
|
||
type: "object",
|
||
properties: {
|
||
project_path: {
|
||
type: "string",
|
||
description: "项目根目录(绝对路径)",
|
||
},
|
||
preset: {
|
||
type: "string",
|
||
description: "预设工作流",
|
||
enum: [
|
||
"full_check", // 全量检查:scan → lint → build → test
|
||
"fix_and_verify", // 修复验证:auto_fix → lint → build → test
|
||
"pre_commit", // 提交前检查:lint → build → test → git status
|
||
"ci_simulate", // CI 模拟:install → lint → build → test → audit
|
||
"quick_scan", // 快速扫描:scan → lint
|
||
"deploy_prep", // 部署准备:lint → build → test → git status
|
||
],
|
||
},
|
||
steps: {
|
||
type: "string",
|
||
description: "自定义步骤,逗号分隔(如 scan,lint,fix,build,test,git_status,audit)。与 preset 二选一。",
|
||
},
|
||
stop_on_error: {
|
||
type: "boolean",
|
||
description: "遇到错误是否停止(默认 true)",
|
||
},
|
||
},
|
||
required: ["project_path"],
|
||
},
|
||
};
|
||
const STEP_MAP = {
|
||
scan: {
|
||
name: "📋 项目扫描",
|
||
fn: (p) => executeProjectScan({ project_path: p }),
|
||
},
|
||
lint: {
|
||
name: "🔍 代码检查",
|
||
fn: (p) => executeLintCheck({ project_path: p }),
|
||
},
|
||
fix: {
|
||
name: "🔧 自动修复",
|
||
fn: (p) => executeAutoFix({ project_path: p }),
|
||
},
|
||
build: {
|
||
name: "🏗️ 构建项目",
|
||
fn: (p) => executeBuildProject({ project_path: p }),
|
||
},
|
||
test: {
|
||
name: "🧪 运行测试",
|
||
fn: (p) => executeRunTests({ project_path: p }),
|
||
},
|
||
git_status: {
|
||
name: "📊 Git 状态",
|
||
fn: (p) => executeGitOps({ project_path: p, action: "status" }),
|
||
},
|
||
git_diff: {
|
||
name: "📝 Git Diff",
|
||
fn: (p) => executeGitOps({ project_path: p, action: "diff" }),
|
||
},
|
||
audit: {
|
||
name: "🛡️ 安全审计",
|
||
fn: (p) => executeDepManage({ project_path: p, action: "audit" }),
|
||
},
|
||
outdated: {
|
||
name: "📦 过时依赖检查",
|
||
fn: (p) => executeDepManage({ project_path: p, action: "outdated" }),
|
||
},
|
||
install: {
|
||
name: "📥 安装依赖",
|
||
fn: (p) => executeDepManage({ project_path: p, action: "install" }),
|
||
},
|
||
};
|
||
const PRESETS = {
|
||
full_check: ["scan", "lint", "build", "test"],
|
||
fix_and_verify: ["fix", "lint", "build", "test"],
|
||
pre_commit: ["lint", "build", "test", "git_status"],
|
||
ci_simulate: ["install", "lint", "build", "test", "audit"],
|
||
quick_scan: ["scan", "lint"],
|
||
deploy_prep: ["lint", "build", "test", "git_status"],
|
||
};
|
||
export async function executeWorkflow(args) {
|
||
const { project_path, preset, steps, stop_on_error = true } = args;
|
||
// 确定步骤列表
|
||
let stepKeys;
|
||
let workflowName;
|
||
if (steps) {
|
||
stepKeys = steps.split(",").map((s) => s.trim());
|
||
workflowName = "自定义工作流";
|
||
}
|
||
else if (preset && PRESETS[preset]) {
|
||
stepKeys = PRESETS[preset];
|
||
workflowName = `预设: ${preset}`;
|
||
}
|
||
else {
|
||
// 默认全量检查
|
||
stepKeys = PRESETS.full_check;
|
||
workflowName = "预设: full_check(全量检查)";
|
||
}
|
||
// 验证步骤
|
||
const invalidSteps = stepKeys.filter((k) => !STEP_MAP[k]);
|
||
if (invalidSteps.length > 0) {
|
||
return `❌ 未知步骤: ${invalidSteps.join(", ")}\n\n可用步骤: ${Object.keys(STEP_MAP).join(", ")}`;
|
||
}
|
||
const totalSteps = stepKeys.length;
|
||
const startTime = Date.now();
|
||
const results = [];
|
||
const output = [
|
||
`# 🚀 工作流执行`,
|
||
``,
|
||
`📂 ${project_path}`,
|
||
`📋 ${workflowName}`,
|
||
`📊 共 ${totalSteps} 个步骤`,
|
||
`${stop_on_error ? "⛔ 遇错停止" : "⏭️ 遇错继续"}`,
|
||
``,
|
||
`---`,
|
||
``,
|
||
];
|
||
let hasError = false;
|
||
for (let i = 0; i < stepKeys.length; i++) {
|
||
const key = stepKeys[i];
|
||
const step = STEP_MAP[key];
|
||
output.push(`## [${i + 1}/${totalSteps}] ${step.name}`);
|
||
const stepStart = Date.now();
|
||
try {
|
||
const result = await step.fn(project_path);
|
||
const duration = Date.now() - stepStart;
|
||
// 判断步骤是否成功(检查输出中的错误标志)
|
||
const isError = result.includes("❌") && !result.includes("✅");
|
||
const stepSuccess = !isError;
|
||
results.push({
|
||
name: step.name,
|
||
success: stepSuccess,
|
||
duration,
|
||
output: result,
|
||
});
|
||
output.push(`${stepSuccess ? "✅ 通过" : "❌ 失败"} (${(duration / 1000).toFixed(1)}s)`, ``, `<details>`, `<summary>查看详情</summary>`, ``, result.slice(0, 3000), ``, `</details>`, ``);
|
||
if (!stepSuccess) {
|
||
hasError = true;
|
||
if (stop_on_error) {
|
||
output.push(`\n⛔ **遇到错误,工作流停止。** 后续步骤: ${stepKeys.slice(i + 1).join(" → ")}`);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
catch (error) {
|
||
const duration = Date.now() - stepStart;
|
||
results.push({ name: step.name, success: false, duration, output: error.message });
|
||
output.push(`❌ 异常 (${(duration / 1000).toFixed(1)}s): ${error.message}`, ``);
|
||
hasError = true;
|
||
if (stop_on_error) {
|
||
output.push(`\n⛔ **工作流中断**`);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
// 总结报告
|
||
const totalDuration = Date.now() - startTime;
|
||
const passed = results.filter((r) => r.success).length;
|
||
const failed = results.filter((r) => !r.success).length;
|
||
output.push(``, `---`, ``, `# 📊 工作流总结`, ``, `| 项目 | 值 |`, `|------|------|`, `| 总耗时 | ${(totalDuration / 1000).toFixed(1)}s |`, `| 已执行 | ${results.length}/${totalSteps} |`, `| ✅ 通过 | ${passed} |`, `| ❌ 失败 | ${failed} |`, `| 最终结果 | ${hasError ? "❌ 有问题需要处理" : "✅ 全部通过"} |`, ``);
|
||
if (hasError) {
|
||
output.push(`## 💡 建议`, `1. 查看失败步骤的详情`, `2. 使用 \`auto_fix\` 自动修复格式问题`, `3. 使用 \`code_debug\` 分析编译错误`, `4. 修复后运行 \`workflow preset=fix_and_verify\` 验证`);
|
||
}
|
||
else {
|
||
output.push(`✨ **所有检查通过,代码质量良好!**`);
|
||
}
|
||
return output.join("\n");
|
||
}
|
||
//# sourceMappingURL=workflow.js.map
|