diff --git a/mcp-server/release-prepare/cmd/main.go b/mcp-server/release-prepare/cmd/main.go new file mode 100644 index 0000000..cbc4c5c --- /dev/null +++ b/mcp-server/release-prepare/cmd/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "qiniu1024-mcp-server/release-prepare/internal/orchestrator" +) + +func main() { + issue := orchestrator.RunReleasePreparation("user-service", "v1.1.0") + + // 序列化成 JSON + out, err := json.MarshalIndent(issue, "", " ") + if err != nil { + fmt.Println("json marshal error:", err) + return + } + + // 写入文件 + err = os.WriteFile("issue.json", out, 0644) + if err != nil { + fmt.Println("write file error:", err) + return + } + + fmt.Println("JSON 数据已写入 issue.json") +} diff --git a/mcp-server/release-prepare/internal/issue/issue.go b/mcp-server/release-prepare/internal/issue/issue.go new file mode 100644 index 0000000..620e277 --- /dev/null +++ b/mcp-server/release-prepare/internal/issue/issue.go @@ -0,0 +1,16 @@ +package issue + +import ( + "qiniu1024-mcp-server/pkg/models" + "time" +) + +func GenerateIssue(service, candidate string, steps []models.StepResult) map[string]interface{} { + return map[string]interface{}{ + "title": "Release Preparation - " + service + " " + candidate, + "service": service, + "candidate": candidate, + "steps": steps, + "created_at": time.Now().Format(time.RFC3339), + } +} diff --git a/mcp-server/release-prepare/internal/metrics/metrics.go b/mcp-server/release-prepare/internal/metrics/metrics.go new file mode 100644 index 0000000..2c377d8 --- /dev/null +++ b/mcp-server/release-prepare/internal/metrics/metrics.go @@ -0,0 +1,37 @@ +package metrics + +import ( + "fmt" + "qiniu1024-mcp-server/pkg/models" +) + +// 指标模板 +var metricTemplates = map[string][]string{ + "CPU": {"%s_service_cpu_user_seconds_total", "%s_service_cpu_system_seconds_total"}, + "Memory": {"%s_service_memory_used_bytes", "%s_service_memory_active_bytes"}, + "Error Rate": {"%s_service_errors_total"}, +} + +// BuildMetricsForService 根据服务名和指标模板拼接各问题对应的Prometheus指标列表 +func BuildMetricsForService(service string) []map[string]interface{} { + metrics := []map[string]interface{}{} + for name, templates := range metricTemplates { + candidates := []string{} + for _, tpl := range templates { + candidates = append(candidates, fmt.Sprintf(tpl, service)) + } + metrics = append(metrics, map[string]interface{}{ + "name": name, + "candidates": candidates, + }) + } + return metrics +} + +func GenerateMetricList(service string) models.StepResult { + details := map[string]interface{}{ + "service": service, + "metrics": BuildMetricsForService(service), + } + return models.NewStepResult("MetricAnalysis", fmt.Sprintf("%d group metrics identified", len(metricTemplates)), details) +} diff --git a/mcp-server/release-prepare/internal/orchestrator/orchestrator.go b/mcp-server/release-prepare/internal/orchestrator/orchestrator.go new file mode 100644 index 0000000..2957ff6 --- /dev/null +++ b/mcp-server/release-prepare/internal/orchestrator/orchestrator.go @@ -0,0 +1,23 @@ +package orchestrator + +import ( + "qiniu1024-mcp-server/pkg/models" + "qiniu1024-mcp-server/release-prepare/internal/issue" + "qiniu1024-mcp-server/release-prepare/internal/metrics" + "qiniu1024-mcp-server/release-prepare/internal/planner" + "qiniu1024-mcp-server/release-prepare/internal/risk" + "qiniu1024-mcp-server/release-prepare/internal/version" +) + +func RunReleasePreparation(service, candidate string) map[string]interface{} { + steps := []models.StepResult{} + + // 依次记录版本冲突、待监测指标列表、灰度策略和风险预案 + steps = append(steps, version.CheckVersion(service, candidate)) + steps = append(steps, metrics.GenerateMetricList(service)) + steps = append(steps, planner.ReleasePlan(service)) + steps = append(steps, risk.PredictRisk(service)) + + // 根据记录结果生成发布issue + return issue.GenerateIssue(service, candidate, steps) +} diff --git a/mcp-server/release-prepare/internal/planner/planner.go b/mcp-server/release-prepare/internal/planner/planner.go new file mode 100644 index 0000000..02bca80 --- /dev/null +++ b/mcp-server/release-prepare/internal/planner/planner.go @@ -0,0 +1,38 @@ +package planner + +import ( + "qiniu1024-mcp-server/pkg/models" +) + +func ReleasePlan(service string) models.StepResult { + details := map[string]interface{}{ + "service": service, + "gray_strategy": map[string]interface{}{ + "batches": []map[string]interface{}{ + { + "batch_id": 1, + "nodes": []map[string]interface{}{ + {"node_id": "bj1-node-001", "host_id": "127.0.0.1"}, + }, + }, + { + "batch_id": 2, + "nodes": []map[string]interface{}{ + {"node_id": "sh1-node-001", "host_id": "192.168.1.11"}, + {"node_id": "sh2-node-001", "host_id": "192.168.2.11"}, + }, + }, + { + "batch_id": 3, + "nodes": []map[string]interface{}{ + {"node_id": "sh1-node-002", "host_id": "192.168.1.12"}, + {"node_id": "sh1-node-003", "host_id": "192.168.1.13"}, + {"node_id": "sh2-node-002", "host_id": "192.168.2.12"}, + {"node_id": "sh2-node-003", "host_id": "192.168.2.13"}, + }, + }, + }, + }, + } + return models.NewStepResult("ReleasePlan", "2 batches created", details) +} diff --git a/mcp-server/release-prepare/internal/risk/risk.go b/mcp-server/release-prepare/internal/risk/risk.go new file mode 100644 index 0000000..0c07292 --- /dev/null +++ b/mcp-server/release-prepare/internal/risk/risk.go @@ -0,0 +1,14 @@ +package risk + +import "qiniu1024-mcp-server/pkg/models" + +func PredictRisk(service string) models.StepResult { + details := map[string]interface{}{ + "service": service, + "risks": []map[string]interface{}{ + {"type": "memory_leak", "mitigation": "restart"}, + {"type": "cpu_spike", "mitigation": "rollback"}, + }, + } + return models.NewStepResult("RiskPrediction", "2 risks identified", details) +} diff --git a/mcp-server/release-prepare/internal/version/version.go b/mcp-server/release-prepare/internal/version/version.go new file mode 100644 index 0000000..89b3e0c --- /dev/null +++ b/mcp-server/release-prepare/internal/version/version.go @@ -0,0 +1,15 @@ +package version + +import "qiniu1024-mcp-server/pkg/models" + +func CheckVersion(service, candidate string) models.StepResult { + details := map[string]interface{}{ + "service": service, + "current": "v1.0.0", + "candidate": candidate, + "has_conflict": false, + "conflict_reason": "", + } + summary := "No conflict detected" + return models.NewStepResult("VersionCheck", summary, details) +} diff --git a/mcp-server/release-prepare/issue.json b/mcp-server/release-prepare/issue.json new file mode 100644 index 0000000..6928f24 --- /dev/null +++ b/mcp-server/release-prepare/issue.json @@ -0,0 +1,127 @@ +{ + "candidate": "v1.1.0", + "created_at": "2025-08-25T16:17:24+08:00", + "service": "user-service", + "steps": [ + { + "step_name": "VersionCheck", + "status": "success", + "summary": "No conflict detected", + "details": { + "candidate": "v1.1.0", + "conflict_reason": "", + "current": "v1.0.0", + "has_conflict": false, + "service": "user-service" + }, + "timestamp": "2025-08-25T16:17:24+08:00" + }, + { + "step_name": "MetricAnalysis", + "status": "success", + "summary": "3 group metrics identified", + "details": { + "metrics": [ + { + "candidates": [ + "user-service_service_cpu_user_seconds_total", + "user-service_service_cpu_system_seconds_total" + ], + "name": "CPU" + }, + { + "candidates": [ + "user-service_service_memory_used_bytes", + "user-service_service_memory_active_bytes" + ], + "name": "Memory" + }, + { + "candidates": [ + "user-service_service_errors_total" + ], + "name": "Error Rate" + } + ], + "service": "user-service" + }, + "timestamp": "2025-08-25T16:17:24+08:00" + }, + { + "step_name": "ReleasePlan", + "status": "success", + "summary": "2 batches created", + "details": { + "gray_strategy": { + "batches": [ + { + "batch_id": 1, + "nodes": [ + { + "host_id": "127.0.0.1", + "node_id": "bj1-node-001" + } + ] + }, + { + "batch_id": 2, + "nodes": [ + { + "host_id": "192.168.1.11", + "node_id": "sh1-node-001" + }, + { + "host_id": "192.168.2.11", + "node_id": "sh2-node-001" + } + ] + }, + { + "batch_id": 3, + "nodes": [ + { + "host_id": "192.168.1.12", + "node_id": "sh1-node-002" + }, + { + "host_id": "192.168.1.13", + "node_id": "sh1-node-003" + }, + { + "host_id": "192.168.2.12", + "node_id": "sh2-node-002" + }, + { + "host_id": "192.168.2.13", + "node_id": "sh2-node-003" + } + ] + } + ] + }, + "service": "user-service" + }, + "timestamp": "2025-08-25T16:17:24+08:00" + }, + { + "step_name": "RiskPrediction", + "status": "success", + "summary": "2 risks identified", + "details": { + "risks": [ + { + "mitigation": "restart", + "type": "memory_leak" + }, + { + "mitigation": "rollback", + "type": "cpu_spike" + } + ], + "service": "user-service" + }, + "timestamp": "2025-08-25T16:17:24+08:00" + } + ], + "title": "Release Preparation - user-service v1.1.0" +} \ No newline at end of file