给 opencode 用的 CI/CD agent + 三个 MCP server。 栈:GitHub Actions(CI)/ Jenkins(发布)/ SonarQube(扫描)。
MCP 是传感器和受控执行器,agent 才是修复者。
所以这里没有任何 fix_* 工具——那等于把判断塞进一个没有上下文的函数里。
MCP 负责把外部世界压缩成可采信的证据,以及提供带闸门的执行动作。
三条具体体现:
- 日志在服务端压缩。 单个 job 日志常达几十 MB,
get_failure_excerpt剔除噪音、只留错误行及上下文,并给出跨 run 可比对的 signature。 - 写操作默认是"提议"。
prepare_rollback只出方案不执行;trigger_job需要CICD_ALLOW_TRIGGER=1+confirm=True。 安全边界放在函数签名里,比放在 prompt 里可靠——prompt 能被绕过,签名不能。 - 错误信息要能指路。 每个异常都带"下一步该调什么",让 agent 能自纠而不是空转。
src/cicd_mcp/
common/ config.py(env) http.py(错误翻译) logs.py(日志压缩+指纹)
citriage/ GitHub Actions 失败诊断
release/ Jenkins 发布状态
secscan/ SonarQube 扫描分诊
agents/ cicd.md(主) ci-triage.md(只读诊断) sonar-fixer.md(批量修复)
opencode.json 三个 MCP server 的接入配置
docs/ENV.md 环境变量与最小权限
cd /Users/xlisp/PyPro/opencode-cicd-agent
uv sync # 或 pip install -e .
cp docs/ENV.md /dev/null # 按 docs/ENV.md 里的模板写 .env
set -a && source .env && set +a
# agent 放到项目级或全局
mkdir -p .opencode/agents && cp agents/*.md .opencode/agents/
# 或全局:cp agents/*.md ~/.config/opencode/agents/
opencode # Tab 切到 cicd agent验证 MCP 是否连上:
opencode mcp list # 应看到 citriage / release / secscan
npx @modelcontextprotocol/inspector uv run --directory . cicd-citriage| 工具 | 说明 |
|---|---|
list_runs |
最近的 run,默认只看失败 |
get_run_tree |
job/step 结构与耗时,不含日志 |
get_failure_excerpt |
⭐ 压缩后的错误上下文 + failure signature |
get_job_history |
⭐ 采样最近 N 次,给出 likely_flaky / likely_real 判定 |
diff_since_last_success |
上次成功到本次失败之间的代码/依赖/workflow 变更 |
rerun_failed_jobs |
重跑(需 Actions:Write) |
get_job_history 的判定逻辑是硬规则不是模型猜测:失败横跨 ≥3 个分支、
失败率在 5%~60% 之间、且成败交替 ≥3 次 → likely_flaky。
这样 agent 说"这是 flaky"的时候,背后有可复核的数字。
| 工具 | 说明 |
|---|---|
list_jobs |
列 job(支持 folder) |
list_deployments |
近期构建,自动解析出 ENV / SERVICE / VERSION / commit |
get_deployment |
Pipeline 各 stage 耗时与失败 stage(需 workflow-api 插件) |
get_deployment_log |
压缩后的 consoleText |
list_blocked |
队列里卡住的构建(等 executor / 等锁 / 等审批) |
prepare_rollback |
⭐ 出回滚方案 + 风险清单,不执行 |
trigger_job |
默认禁用,需显式开启 |
构建参数的键名靠猜(ENV/ENVIRONMENT/TARGET_ENV…),
你们如果用别的命名,改 release/server.py 顶部的 ENV_KEYS / VER_KEYS / SVC_KEYS。
| 工具 | 说明 |
|---|---|
list_findings |
默认只返回新代码里的 BLOCKER/CRITICAL,带 by_rule 分布 |
get_finding_context |
⭐ 代码上下文 + 污点传播路径 |
get_rule_guidance |
规则的根因与官方修复模式,批量修复前先调 |
get_quality_gate |
门禁状态与卡住的 metric |
list_hotspots |
安全热点 |
mark_false_positive |
需 ≥40 字理由,会作为评论留档 |
SonarQube 核心是 SAST,不做 SCA 依赖漏洞。 依赖 CVE 要另接
Dependabot / Trivy / Snyk,加一个 src/cicd_mcp/depscan/ 即可,
接口风格照抄 secscan。
MCP 工具名会拼成 <server>_<tool>,所以 agent 里可以按前缀切:
permission:
citriage_*: allow # 诊断全放行
release_prepare_rollback: allow # 出方案可以
release_trigger_job: ask # 真触发要问
secscan_mark_false_positive: ask # 消告警要问三个 agent 的权限梯度:
cicd(primary):能读能诊断,写操作 askci-triage(subagent):纯只读,连 bash 都 deny,适合并行分诊多个失败sonar-fixer(subagent):能改业务代码,但 deny 改 workflow/Jenkinsfile, 也 denymark_false_positive——不给它"消告警"这条捷径
CI 环境没人能应答 ask,所以要单独一份全 deny 的配置:
- name: AI triage on failure
if: failure()
run: |
opencode run --agent ci-triage \
"诊断 run ${{ github.run_id }} 的失败原因" > triage.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CICD_DEFAULT_REPO: ${{ github.repository }}ci-triage 是只读 subagent,正好适合这个场景。
- Jenkins 的 stage 信息依赖 workflow-api 插件;非 Pipeline job 只能拿到构建级信息。
- SonarQube 10.x 的
severities参数已标记 deprecated(新的是impactSeverities), 当前代码用的是兼容写法,10.x 上仍可用,未来版本可能需要调整。 - GitHub job 日志默认保留 90 天,超期的 run 取不到 excerpt。
prepare_rollback的风险清单是启发式的,不能替代人工确认 DB migration 的可逆性。