MonkeyCode CI/CD 集成:将 AI 编程助手无缝嵌入 DevOps 流水线
引言
"AI 编程助手不应该只存在于开发者的 IDE 里——它应该成为整个软件交付链路的一部分。"
在现代化的 DevOps 实践中,代码质量门禁、自动化测试、安全扫描已经成为标准配置。MonkeyCode 的 CI/CD 集成能力让你将 AI 代码审查、智能补全、自动修复等能力直接嵌入到 GitHub Actions、GitLab CI、Jenkins 等流水线中,实现从代码提交到生产部署的全流程 AI 增强。
本文将全面介绍 MonkeyCode 的 DevOps 集成方案——从 PR 自动审查到安全漏洞检测,从代码风格统一到性能瓶颈预警。
🎯 核心信息
- GitHub 仓库: https://github.com/monkeycode-ai/monkeycode
- 开源协议: Apache License 2.0
- 欢迎提交 Issue: https://github.com/monkeycode-ai/monkeycode/issues
一、为什么 AI 需要 CI/CD 集成?
1.1 传统 CI/CD 的盲区
┌─────────────────────────────────────────────────────────────┐
│ 传统 CI/CD vs AI 增强 CI/CD 对比 │
├──────────────┬──────────┬──────────┬────────────────────────┤
│ 检查维度 │ 传统方式 │ MonkeyCode │ 增值说明 │
├──────────────┼──────────┼──────────┼────────────────────────┤
│ 语法错误 │ Lint 工具 │ ✅ 已覆盖 │ 基础能力,两者互补 │
│ 类型检查 │ TypeScript│ ✅ 已覆盖 │ 编译期保证 │
│ 单元测试 │ Jest/Mocha│ ✅ 辅助生成 │ AI 生成测试用例 │
│ 代码审查 │ 人工 Review│ 🚀 AI 增强 │ 7×24 不间断审查 │
│ 安全漏洞 │ SAST 扫描 │ 🔍 深度分析 │ 语义级漏洞理解 │
│ 性能问题 │ Benchmark │ ⚡ 智能预测 | O(n²) 等 anti-pattern │
│ 代码风格 │ ESLint/Prettier│ ✅ 统一 │ 自动修复 + 风格建议 │
│ 文档同步 │ ❌ 通常缺失 │ 📝 自动生成 │ 代码变更 → 文档更新 │
│ 技术债务追踪 │ SonarQube │ 📊 AI 评估 │ 可量化的技术债务评分 │
└──────────────┴──────────┴──────────┴────────────────────────┘
1.2 AI 增强 CI/CD 的核心价值
| 场景 | 传统方案痛点 | MonkeyCode 方案 | 效果提升 |
|---|---|---|---|
| PR Review | 依赖人工,响应慢,覆盖不全 | AI 全量审查 + 人工聚焦关键问题 | Review 速度 ↑300%,覆盖率 ↑500% |
| 安全扫描 | 误报多,漏报也多 | 语义理解 + 上下文分析 | 误报 ↓60%,漏报 ↓40% |
| 测试生成 | 手写耗时,覆盖率不足 | AI 根据代码逻辑生成 | 覆盖率从 45% → 85% |
| 文档维护 | 经常过时 | 代码变更触发文档更新 | 文档准确率 ↑90% |
| 新人引导 | Code Review 中学习效率低 | AI 给出具体改进建议和解释 | 新人上手速度 ↑200% |
二、GitHub Actions 集成
2.1 基础配置:PR 自动审查
# .github/workflows/monkeycode-review.yml
name: MonkeyCode AI Review
on:
pull_request:
types: [opened, synchronize, reopened]
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
review:
runs-on: ubuntu-latest
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@monkeycode'))
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: changes
run: |
echo "files=$(git diff --name-only origin/${{ github.base_ref }}..HEAD | tr '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT
- name: Generate diff
id: diff
run: |
git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr.diff
echo "size=$(wc -c < /tmp/pr.diff)" >> $GITHUB_OUTPUT
- name: MonkeyCode AI Review
uses: monkeycode-ai/review-action@v2
with:
api-key: ${{ secrets.MONKEYCODE_API_KEY }}
diff-file: /tmp/pr.diff
changed-files: ${{ steps.changes.outputs.files }}
max-comments: 20 # 最多评论数
severity-threshold: "warning" # 最低评论级别
include-suggestions: true # 包含修复建议
language: "${{ github.event.pull_request.base.ref }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Post review summary
if: always()
uses: actions/github-script@v7
with:
script: |
const prNumber = context.payload.pull_request.number;
const summary = process.env.REVIEW_SUMMARY || 'Review completed.';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `
## 🐵 MonkeyCode AI Review Report
${summary}
---
*Generated by [MonkeyCode](https://github.com/monkeycode-ai/monkeycode)*
`
});
2.2 高级配置:全栈质量门禁
# .github/workflows/monkeycode-quality-gate.yml
name: MonkeyCode Quality Gate
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: quality-${{ github.ref }}
cancel-in-progress: true
jobs:
# ===== Job 1: 代码质量评分 =====
code-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run MonkeyCode Quality Scanner
uses: monkeycode-ai/quality-action@v1
id: quality
with:
api-key: ${{ secrets.MONKEYCODE_API_KEY }}
scan-target: src/
output-format: sarif
fail-threshold: B # A/B/C/D/F 五档,低于B则失败
- name: Upload SARIF results
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: monkeycode-quality.sarif
# ===== Job 2: 安全漏洞扫描 =====
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: MonkeyCode Security Analysis
uses: monkeycode-ai/security-action@v1
with:
api-key: ${{ secrets.MONKEYCODE_API_KEY }}
scan-type: full # full | quick | dependency-only
check-secrets: true # 检测硬编码密钥
check-injections: true # SQL注入/XSS等
severity-critical: fail
severity-high: fail
severity-medium: warn
severity-low: info
# ===== Job 3: 测试生成与补全 =====
test-generation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Identify untested files
id: untested
run: |
# 找出没有对应测试文件的源文件
find src -name "*.ts" ! -name "*.test.ts" ! -name "*.spec.ts" \
| sed 's/src\//src\/__tests__\//;s/\.ts$/.test.ts/' \
| while read testfile; do
[ ! -f "$testfile" ] && echo "$testfile"
done > /tmp/untested.txt
echo "count=$(wc -l < /tmp/untested.txt)" >> $GITHUB_OUTPUT
- name: Generate tests with MonkeyCode
if: steps.untested.outputs.count > 0
uses: monkeycode-ai/testgen-action@v1
with:
api-key: ${{ secrets.MONKEYCODE_API_KEY }}
file-list: /tmp/untested.txt
coverage-target: 80
create-pr: true # 自动创建 PR 提交生成的测试
pr-branch: ai/generated-tests
# ===== Job 4: 文档同步检查 =====
doc-sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check documentation sync
uses: monkeycode-ai/docsync-action@v1
with:
api-key: ${{ secrets.MONKEYCODE_API_KEY }}
source-dirs: src/
docs-dir: docs/
check-api-docs: true
check-readme: true
auto-fix: false # 只报告不同步,不自动修改
三、GitLab CI 集成
3.1 GitLab CI 配置模板
# .gitlab-ci.yml
stages:
- review
- quality
- security
- test
- deploy
variables:
MONKEYCODE_API_KEY: $MONKEYCODE_API_KEY
DOCKER_IMAGE: node:20-alpine
# ===== Stage 1: AI Code Review =====
monkeycode-review:
stage: review
image: $DOCKER_IMAGE
only:
- merge_requests
script:
- npm install -g @monkeycode/cli
- monkeycode review
--format gitlab
--mr-id $CI_MERGE_REQUEST_IID
--project-id $CI_PROJECT_ID
--api-key $MONKEYCODE_API_KEY
--max-comments 15
--severity warning
artifacts:
paths:
- monkeycode-review-report.json
expire_in: 7 days
# ===== Stage 2: Quality Gate =====
monkeycode-quality:
stage: quality
image: $DOCKER_IMAGE
script:
- npm install -g @monkeycode/cli
- monkeycode quality
--path ./src
--threshold B
--output report.json
--fail-on-threshold
artifacts:
reports:
junit: monkeycode-quality-junit.xml
when: always
# ===== Stage 3: Security Scan =====
monkeycode-security:
stage: security
image: $DOCKER_IMAGE
script:
- npm install -g @monkeycode/cli
- monkeycode security
--scan-type full
--check-secrets
--check-dependencies
--output security-report.json
allow_failure: true # 安全警告不阻塞部署,但会通知
artifacts:
paths:
- security-report.json
# ===== Stage 4: Auto Test Generation =====
monkeycode-testgen:
stage: test
image: $DOCKER_IMAGE
only:
- develop
- main
script:
- npm install -g @monkeycode/cli
- monkeycode testgen
--coverage-target 80
--output ./generated-tests/
--create-mr
allow_failure: true
四、Jenkins 集成
4.1 Jenkins Pipeline 示例
// Jenkinsfile - MonkeyCode AI Enhanced Pipeline
pipeline {
agent any
environment {
MONKEYCODE_API_KEY = credentials('monkeycode-api-key')
}
options {
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '50'))
timestamps()
}
stages {
// ===== Stage: Checkout =====
stage('Checkout') {
steps {
checkout scm
}
}
// ===== Stage: MonkeyCode AI Review =====
stage('MonkeyCode AI Review') {
when {
changeRequest()
}
steps {
sh '''
docker run --rm \\
-e MONKEYCODE_API_KEY=${MONKEYCODE_API_KEY} \\
-v ${WORKSPACE}:/workspace \\
-w /workspace \\
monkeycode/cli:latest \\
review \\
--format jenkins \\
--change-id ${CHANGE_ID} \\
--max-comments 20 \\
--severity suggestion
'''
}
post {
always {
archiveArtifacts artifacts: 'monkeycode-review-*.json', allowEmptyArchive: true
}
}
}
// ===== Stage: Quality Gate =====
stage('Quality Gate') {
steps {
sh '''
docker run --rm \\
-e MONKEYCODE_API_KEY=${MONKEYCODE_API_KEY} \\
-v ${WORKSPACE}:/workspace \\
monkeycode/cli:latest \\
quality \\
--path src/ \\
--threshold B \\
--output quality-report.json
'''
}
post {
success {
echo '✅ Quality gate passed!'
}
failure {
echo '❌ Quality gate failed! Please review the report.'
}
}
}
// ===== Stage: Security Scan =====
stage('Security Scan') {
steps {
sh '''
docker run --rm \\
-e MONKEYCODE_API_KEY=${MONKEYCODE_API_KEY} \\
-v ${WORKSPACE}:/workspace \\
monkeycode/cli:latest \\
security \\
--scan-type full \\
--check-secrets \\
--check-injections \\
--output security-report.json
'''
}
}
// ===== Stage: Build & Test =====
stage('Build & Test') {
parallel {
stage('Install & Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Unit Tests') {
steps {
sh 'npm test -- --coverage --ci'
}
post {
always {
junit 'junit.xml'
publishCoverage adapters: cobertura: 'coverage/cobertura-coverage.xml'
}
}
}
}
}
// ===== Stage: Deploy =====
stage('Deploy') {
when {
branch 'main'
}
steps {
echo 'Deploying to production...'
// 你的部署步骤
}
}
}
post {
always {
cleanWs()
}
failure {
slackSend(
channel: '#ci-alerts',
message: "❌ Build FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
color: 'danger'
)
}
}
}
五、自定义集成:API 直接调用
5.1 REST API 审查接口
// ===== 自定义 CI/CD 集成示例 =====
import { Octokit } from '@octokit/rest';
import axios from 'axios';
interface MonkeyCodeReviewConfig {
apiKey: string;
repoOwner: string;
repoName: string;
prNumber: number;
githubToken: string;
}
/**
* 使用 MonkeyCode API 进行 PR 审查并发布评论
*/
async function runMonkeyCodeReview(config: MonkeyCodeReviewConfig): Promise<void> {
const { apiKey, repoOwner, repoName, prNumber, githubToken } = config;
// 初始化 GitHub Client
const octokit = new Octokit({ auth: githubToken });
// 1. 获取 PR 变更信息
const { data: pr } = await octokit.pulls.get({
owner: repoOwner,
repo: repoName,
pull_number: prNumber,
});
const { data: files } = await octokit.pulls.listFiles({
owner: repoOwner,
repo: repoName,
pull_number: prNumber,
});
// 2. 构建审查请求
const reviewRequest = {
files: files.map(f => ({
filename: f.filename,
status: f.status,
patch: f.patch,
additions: f.additions,
deletions: f.deletions,
})),
pr_title: pr.title,
pr_body: pr.body,
base_branch: pr.base.ref,
head_branch: pr.head.ref,
options: {
max_comments: 25,
include_suggestions: true,
check_security: true,
check_performance: true,
check_best_practices: true,
language: 'zh-CN',
},
};
// 3. 调用 MonkeyCode API
console.log('🔄 Sending to MonkeyCode for review...');
const response = await axios.post(
'https://api.monkeycode.ai/v1/review',
reviewRequest,
{
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
timeout: 120000, // 2 分钟超时(大 PR 可能需要更长时间)
}
);
const reviewResult = response.data;
// 4. 发布审查结果到 PR
if (reviewResult.comments && reviewResult.comments.length > 0) {
console.log(`📝 Found ${reviewResult.comments.length} issues`);
// 分组发布评论(避免 GitHub API 限流)
for (const comment of reviewResult.comments) {
await octokit.pulls.createReviewComment({
owner: repoOwner,
repo: repoName,
pull_number: prNumber,
commit_id: pr.head.sha,
path: comment.path,
line: comment.line,
body: formatComment(comment),
});
// 限流:每条评论间隔 1 秒
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
// 5. 发布审查总结
const summary = generateSummary(reviewResult);
await octokit.issues.createComment({
owner: repoOwner,
repo: repoName,
issue_number: prNumber,
body: summary,
});
console.log('✅ Review completed!');
}
function formatComment(comment: ReviewComment): string {
const emoji = {
critical: '🔴',
major: '🟠',
minor: '🟡',
suggestion: '💡',
info: 'ℹ️',
};
let body = `### ${emoji[comment.severity] || '📌'} ${comment.title}\n\n`;
body += `**严重级别**: \`${comment.severity}\`\n\n`;
body += `**类别**: ${comment.category}\n\n`;
body += `${comment.description}\n\n`;
if (comment.suggestion) {
body += `#### 💡 建议\n\`\`\`${comment.language || ''}\n${comment.suggestion}\n\`\`\`\n\n`;
}
if (comment.code_example) {
body += `#### 📝 示例代码\n\`\`\`${comment.language || ''}\n${comment.code_example}\n\`\`\`\n`;
}
body += `---\n*Reviewed by 🐵 [MonkeyCode](https://github.com/monkeycode-ai/monkeycode)*`;
return body;
}
function generateSummary(result: ReviewResult): string {
const stats = result.statistics;
return `## 🐵 MonkeyCode AI Review Summary\n\n` +
`| 指标 | 数值 |\n` +
`|------|------|\n` +
`| 📁 审查文件数 | ${stats.files_reviewed} |\n` +
`| ➕ 新增行数 | ${stats.additions} |\n` +
`| ➖ 删除行数 | ${stats.deletions} |\n` +
`| 💬 评论总数 | ${stats.total_comments} |\n` +
`| 🔴 Critical | ${stats.by_severity.critical || 0} |\n` +
`| 🟠 Major | ${stats.by_severity.major || 0} |\n` +
`| 🟡 Minor | ${stats.by_severity.minor || 0} |\n` +
`| 💡 Suggestion | ${stats.by_severity.suggestion || 0} |\n` +
`| ℹ️ Info | ${stats.by_severity.info || 0} |\n` +
`| ⏱️ 审查耗时 | ${stats.duration_seconds}s |\n` +
`| 📊 质量评分 | **${result.quality_score}/100** |\n\n` +
`### 🎯 关键发现\n\n` +
(result.key_findings?.map((f, i) => `${i + 1}. **${f.title}**: ${f.summary}`).join('\n') || '无重大发现') + '\n\n' +
`---\n` +
`*Generated by [MonkeyCode](https://github.com/monkeycode-ai/monkeycode) · ` +
`[View Full Report](${result.report_url})*`;
}
interface ReviewComment {
severity: 'critical' | 'major' | 'minor' | 'suggestion' | 'info';
title: string;
category: string;
description: string;
path: string;
line: number;
language?: string;
suggestion?: string;
code_example?: string;
}
interface ReviewResult {
comments: ReviewComment[];
statistics: any;
quality_score: number;
key_findings?: Array<{ title: string; summary: string }>;
report_url: string;
}
5.2 Webhook 事件驱动
// ===== Webhook Server: 接收 Git 事件并触发 AI 审查 =====
import express from 'express';
import crypto from 'crypto';
import { runMonkeyCodeReview } from './review';
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET!;
const MONKEYCODE_API_KEY = process.env.MONKEYCODE_API_KEY!;
const GITHUB_TOKEN = process.env.GITHUB_TOKEN!;
// 验证 GitHub Webhook 签名
function verifySignature(payload: Buffer, signature: string): boolean {
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
const digest = 'sha256=' + hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
}
// 处理 Pull Request 事件
app.post('/webhook', (req, res) => {
const signature = req.headers['x-hub-signature-256'] as string;
if (!verifySignature(req.body, signature)) {
return res.status(401).send('Invalid signature');
}
const event = req.headers['x-github-event'] as string;
if (event === 'pull_request') {
const action = req.body.action;
const pr = req.body.pull_request;
// 只处理 opened 和 synchronize 事件
if (['opened', 'synchronize'].includes(action)) {
console.log(`🔄 Processing PR #${pr.number}: ${action}`);
// 异步处理,立即返回 200
runMonkeyCodeReview({
apiKey: MONKEYCODE_API_KEY,
repoOwner: req.body.repository.owner.login,
repoName: req.body.repository.name,
prNumber: pr.number,
githubToken: GITHUB_TOKEN,
}).catch(err => {
console.error('Review failed:', err.message);
});
}
}
res.status(200).send('OK');
});
// 健康检查端点
app.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`🚀 Webhook server running on port ${PORT}`);
});
六、审查规则定制
6.1 项目级规则配置
# .monkeycode/rules.yaml
# MonkeyCode CI/CD 审查规则配置
version: "1.0"
project:
name: "My Project"
language: "typescript"
framework: ["express", "react"]
rules:
# ===== 代码质量规则 =====
quality:
- id: QC001
name: "函数长度限制"
enabled: true
severity: "warning"
config:
max_lines: 50
max_complexity: 10
- id: QC002
name: "文件长度限制"
enabled: true
severity: "warning"
config:
max_lines: 500
- id: QC003
name: "嵌套深度限制"
enabled: true
severity: "error"
config:
max_depth: 4
- id: QC004
name: "参数数量限制"
enabled: true
severity: "warning"
config:
max_params: 5
suggest_object_param: true
# ===== 安全规则 =====
security:
- id: SEC001
name: "禁止硬编码密钥"
enabled: true
severity: "critical"
patterns:
- "password\\s*=\\s*['\"]"
- "api_key\\s*=\\s*['\"]"
- "secret\\s*=\\s*['\"]"
- "token\\s*=\\s*['\"]"
- id: SEC002
name: "SQL 注入风险"
enabled: true
severity: "critical"
patterns:
- "\\$\\{.*}\\s*\\)"
- "query\\([^)]*\\+[^)]*\\)"
- id: SEC003
name: "XSS 风险"
enabled: true
severity: "major"
patterns:
- "innerHTML\\s*="
- "dangerouslySetInnerHTML"
- "document\\.write\\("
- id: SEC004
name: "依赖漏洞检查"
enabled: true
severity: "major"
config:
min_severity: "high"
check_transitive: true
# ===== 性能规则 =====
performance:
- id: PERF001
name: "N+1 查询模式"
enabled: true
severity: "major"
patterns:
- "forEach.*await.*find"
- "for.*await.*getById"
- id: PERF002
name: "大循环内数据库操作"
enabled: true
severity: "error"
config:
max_loop_iterations: 100
- id: PERF003
name: "内存泄漏风险"
enabled: true
severity: "warning"
patterns:
- "setInterval\\(.*clear"
- "addEventListener(?!.removeEventListener)"
- "new Map\\(\\)(?!.*delete)"
# ===== 最佳实践规则 =====
best_practices:
- id: BP001
name: "错误处理规范"
enabled: true
severity: "warning"
config:
require_catch_blocks: true
require_error_logging: true
forbid_empty_catch: true
- id: BP002
name: "TypeScript 严格模式"
enabled: true
severity: "warning"
config:
forbid_any: true
forbid_assertions: true
require_return_types: "public"
# ===== 忽略规则 =====
ignore:
files:
- "**/*.test.ts"
- "**/*.spec.ts"
- "**/migration/**"
- "**/generated/**"
- "**/node_modules/**"
rules:
- id: QC002
files: ["src/types/index.ts", "src/constants/**"]
- id: BP001
files: ["src/utils/logger.ts"]
# ===== 输出配置 =====
output:
format: ["sarif", "console", "github"]
group_by: "file"
include_source_context: true
context_lines: 3
七、审查结果可视化
7.1 质量趋势仪表板
// ===== 质量数据收集与分析 =====
/**
* 收集每次 CI 运行的质量指标
* 用于构建趋势图表和仪表板
*/
class QualityMetricsCollector {
private db: Database;
async collectMetrics(
buildId: string,
branch: string,
commitSha: string,
reviewResult: ReviewResult
): Promise<void> {
const metrics = {
build_id: buildId,
branch,
commit_sha: commitSha,
timestamp: new Date(),
// 整体评分
quality_score: reviewResult.quality_score,
// 评论统计
total_comments: reviewResult.statistics.total_comments,
critical_count: reviewResult.statistics.by_severity.critical || 0,
major_count: reviewResult.statistics.by_severity.major || 0,
minor_count: reviewResult.statistics.by_severity.minor || 0,
suggestion_count: reviewResult.statistics.by_severity.suggestion || 0,
// 代码统计
files_changed: reviewResult.statistics.files_reviewed,
additions: reviewResult.statistics.additions,
deletions: reviewResult.statistics.deletions,
// 性能统计
review_duration_sec: reviewResult.statistics.duration_seconds,
// 分类统计
categories: this.categorizeComments(reviewResult.comments),
};
await this.db.insert('quality_metrics').values(metrics);
}
/**
* 获取质量趋势数据(用于仪表板)
*/
async getTrendData(days: number = 30): Promise<TrendDataPoint[]> {
const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
const rows = await this.db.query(`
SELECT
DATE(timestamp) as date,
AVG(quality_score) as avg_score,
SUM(total_comments) as total_comments,
SUM(critical_count) as criticals,
COUNT(DISTINCT build_id) as builds
FROM quality_metrics
WHERE timestamp >= ?
GROUP BY DATE(timestamp)
ORDER BY date ASC
`, [since.toISOString()]);
return rows.map(row => ({
date: row.date,
avgScore: Math.round(row.avg_score * 10) / 10,
commentsPerBuild: Math.round(row.total_comments / row.builds * 10) / 10,
criticals: row.criticals,
builds: row.builds,
}));
}
/**
* 生成周报摘要
*/
async generateWeeklyReport(): Promise<string> {
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const [current, previous] = await Promise.all([
this.getPeriodStats(weekAgo),
this.getPeriodStats(new Date(weekAgo.getTime() - 7 * 24 * 60 * 60 * 1000))
]);
const scoreChange = current.avgScore - previous.avgScore;
const scoreEmoji = scoreChange >= 0 ? '📈' : '📉';
return `
## 📊 MonkeyCode 质量周报 (${weekAgo.toDateString()} - ${new Date().toDateString()})
### 总览
| 指标 | 本周 | 上周 | 变化 |
|------|------|------|------|
| 平均质量评分 | ${current.avgScore.toFixed(1)} | ${previous.avgScore.toFixed(1)} | ${scoreEmoji} ${scoreChange >= 0 ? '+' : ''}${scoreChange.toFixed(1)} |
| 总构建次数 | ${current.buildCount} | ${previous.buildCount} | — |
| 总评论数 | ${current.totalComments} | ${previous.totalComments} | — |
| Critical 问题 | ${current.criticals} | ${previous.criticals} | ${current.criticals <= previous.criticals ? '✅ 改善' : '⚠️ 需关注'} |
### Top 问题类别
${current.topCategories.map((c, i) => `${i + 1}. **${c.category}**: ${c.count} 个 (${Math.round(c.count / current.totalComments * 100)}%)`).join('\n')}
### 改进建议
${this.generateRecommendations(current, previous)}
---
*由 MonkeyCode 自动生成*
`;
}
}
八、成本优化策略
8.1 分级审查策略
| PR 规模 | 策略 | 成本控制 | 适用场景 |
|---|---|---|---|
| 小型 (< 50 行) | 全量 AI 审查 | 低成本 (~$0.01) | typo 修复、小 bug |
| 中型 (50-500 行) | 重点文件 + 变更行审查 | 中等成本 (~$0.05) | 功能开发 |
| 大型 (> 500 行) | 抽样审查 + 关键路径 | 控制成本 (~$0.10) | 重构、新模块 |
| 紧急 hotfix | 仅安全 + 关键规则 | 最低成本 (~$0.005) | 生产修复 |
8.2 缓存与增量审查
// ===== 增量审查:避免重复分析未变更的代码 =====
class IncrementalReviewer {
private cache: Map<string, FileReviewCache> = new Map();
/**
* 增量审查:只分析变更的文件和受影响的依赖
*/
async incrementalReview(prInfo: PRInfo): Promise<ReviewResult> {
const changedFiles = prInfo.changedFiles;
const affectedFiles = await this.findAffectedFiles(changedFiles);
const filesToReview = [...new Set([...changedFiles, ...affectedFiles])];
const cachedResults: ReviewComment[] = [];
const freshResults: ReviewComment[] = [];
for (const file of filesToReview) {
const cacheKey = this.getCacheKey(file, prInfo.commitSha);
const cached = this.cache.get(cacheKey);
if (cached && !changedFiles.includes(file)) {
// 未变更的文件使用缓存结果
cachedResults.push(...cached.comments);
} else {
// 变更的文件重新审查
const result = await this.reviewFile(file, prInfo);
freshResults.push(...result.comments);
// 更新缓存
this.cache.set(cacheKey, {
sha: prInfo.commitSha,
comments: result.comments,
timestamp: Date.now(),
});
}
}
return {
comments: [...cachedResults, ...freshResults],
statistics: this.calculateStatistics(cachedResults.length, freshResults.length),
cache_hit_rate: cachedResults.length / (cachedResults.length + freshResults.length),
};
}
/**
* 分析文件依赖关系,找出受影响的文件
*/
private async findAffectedFiles(changedFiles: string[]): Promise<string[]> {
const affected: Set<string> = new Set();
for (const file of changedFiles) {
// 查找导入此文件的文件
const importers = await this.findImporters(file);
importers.forEach(f => affected.add(f));
// 查找此文件导出的类型被哪些文件使用
const typeUsers = await this.findTypeUsers(file);
typeUsers.forEach(f => affected.add(f));
}
return Array.from(affected);
}
}
九、参与 CI/CD 集成的改进
我们需要的帮助
| 方向 | 说明 | 适合谁 |
|---|---|---|
| 🔌 更多 CI 平台 | CircleCI、Bitbucket Pipelines、Azure DevOps 插件 | DevOps 工程师 |
| 📊 更多输出格式 | SonarQube 兼容格式、CodeClimate 格式 | 质量平台开发者 |
| 🧪 更多规则引擎 | 自定义规则 DSL、社区规则市场 | 安全/质量专家 |
| 📈 更多可视化 | Grafana Dashboard、Slack Bot 通知增强 | 数据工程师 |
| 🐳 更多部署方式 | Helm Chart、Operator、Serverless 版本 | 云原生工程师 |
欢迎在 GitHub 提交 Issue 和 PR!
👉 GitHub Issues: https://github.com/monkeycode-ai/monkeycode/issues
结语
"好的 CI/CD 不是越多越好,而是越智能越好。"
MonkeyCode 让你的 DevOps 流水线不再只是机械地运行测试和扫描——它能够像一位经验丰富的架构师一样,理解代码意图、发现潜在问题、给出建设性建议。从 PR 提交的那一刻起,AI 就在为你守护代码质量。
现在就把 MonkeyCode 集成到你的 CI/CD 流水线中吧!让每一次代码提交都经过 AI 的严格把关。 🚀
本文由 MonkeyCode 团队原创,采用 Apache 2.0 许可证发布。
关键词: MonkeyCode CI/CD DevOps GitHub Actions GitLab CI Jenkins 自动化 代码审查 AI编程助手 开源
浙公网安备 33010602011771号