使用Claude CLI实现公关自动化
一个简单的基于Docker的自动化服务,接收Bitbucket拉取请求的webhooks,克隆/验证存储库,并使用 Claude CLI (不是API)。
特性
- 🔗 接收Bitbucket PR创建webhooks
- 🔒 Webhook签名验证和工作区限制(yourworkspace)
- 📦 如果存储库尚未存在,则自动克隆存储库
- 🔄 在处理之前更新现有存储库
- 🤖 使用Claude CLI处理PR数据(
--dangerously-skip-permissions) - 🐳 完全容器化Docker
- ⚡ Express.js REST API
- 📝 轻松配置环境变量
- 📊 Prometheus度量集成用于监控
先决条件
- 已安装Docker和Docker Compose
- 具有webhook访问权限的Bitbucket存储库
- Bitbucket凭据(应用程序密码令牌和用户名)
注: 这使用了Claude CLI(全局安装在Docker中), 不 人类API,所以你不需要API密钥!
快速开始
📖 有关完整的设置说明,请参阅 SETUP_GUIDE.md
快速启动命令
# Interactive setup (recommended)
npm run setup
# Or start manually after configuration
docker-compose up -d你需要什么
- ✅ 已安装Docker和Docker Compose
- ✅ 具有webhook访问权限的Bitbucket存储库
- ✅ 全局安装的Claude CLI:
npm install -g @anthropic-ai/claude-code
配置Bitbucket Webhook
- 转到您的Bitbucket存储库设置
- 导航至 网络钩子 部分
- 点击 添加webhook
- 配置:
- 标题:PR自动化 - 统一资源定位符: http://your-server:3000/webhook/bitbucket/pr - 状态:活动 - 触发器:选择“拉取请求”→ “已创建”
- 保存webhook
运作原理
工作流程
- 收到Webhook:创建PR时,Bitbucket会发送一个webhook
- 项目验证:系统检查存储库是否已克隆到
/app/projects
- 如果 未克隆:从Bitbucket克隆存储库 - 如果 已存在:更新存储库(git pull)
- Claude CLI处理:执行
claude --dangerously-skip-permissions随着提示
- 在具有终端访问权限的项目目录中运行 - 可以执行git命令、读取文件、分析代码 - 基于文本的审查输出
- 响应:克劳德的分析被记录下来(可以扩展到发表评论等)
Claude CLI与API
此实现使用 Claude CLI 而不是人类API:
| 功能 | Claude CLI | Anthropic API |
|---|---|---|
| 身份验证 | 使用CLI会话(不需要API密钥) | 需要 ANTHROPIC_API_KEY |
| 功能 | 完全终端访问,可以运行命令 | 仅文本,不执行命令 |
| 安装 | npm install -g @anthropic-ai/claude-code | npm install @anthropic-ai/sdk |
| 自动化 | 用途 --dangerously-skip-permissions | 直接API调用 |
| 费用 | 免费(使用Claude CLI会话) | 按令牌付费 |
Z.ai/GLM支持
您还可以使用Z.ai的GLM模型(与Claude Code兼容)代替Anthropic的模型。
- 设置:运行
npm run setup并选择“GLM模型”。 - 手动配置:
- 从获取API密钥 Z.ai型号API. - 集 ANTHROPIC_AUTH_TOKEN (您的Z.ai密钥)和 ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic 在您的环境中或 .claude/settings.json.
项目结构
@pr-automation/
├── src/
│ ├── index.js # Express server and webhook handler
│ ├── claude.js # Claude CLI integration (review + release note)
│ ├── git.js # Git operations (clone, update, validate)
│ ├── branch-matcher.js # Branch regex rules (prReview / releaseNote)
│ ├── metrics.js # Prometheus metrics collection
│ ├── logger.js # Logging configuration
│ ├── template-manager.js # Template management for PR reviews
│ └── config/
│ └── config.json # Templates + branch rules (prReview, releaseNote)
├── tests/ # Unit tests directory
│ ├── claude.test.js # Tests for Claude.js functionality
│ ├── git.test.js # Tests for Git operations
│ └── metrics.test.js # Tests for metrics collection
├── projects/ # Cloned repositories (volume mounted)
├── Dockerfile # Docker image with Claude CLI installed
├── docker-compose.yml # Docker Compose setup
├── jest.config.json # Jest testing configuration
├── package.json # Node.js dependencies and scripts
├── .env.example # Environment variables template
└── README.md # This fileAPI终点
健康检查
GET /health返回服务状态。
答复:
{
"status": "ok",
"message": "PR Automation service is running"
}Bitbucket PR Webhook
POST /webhook/bitbucket/pr接收Bitbucket拉取请求webhooks。
预期标题:
x-event-key:pullrequest:created,pullrequest:updated,或pullrequest:comment_created
答复:
{
"message": "Webhook received successfully",
"prTitle": "Add new feature",
"enqueued": ["review", "create-release-note"],
"queuePosition": 2
}enqueued 列出添加到队列中的作业类型(基于中的分支规则 config.json).一个PR可以同时排队审查和发布说明作业。
通过PR评论手动审查触发
当 manualTrigger.enabled 确实如此,用户可以通过发布PR评论来请求按需评论:
- 机器人提及(来自
manualTrigger.botNames),以及 - 触发器关键字(来自
manualTrigger.keywords,默认值:review).
例子:
@review-bot review手动评论触发排队 review 直接工作(他们绕过 eventFilter.processOnlyCreated 和分支模式过滤器 prReview).
自定义PR审核模板
该系统支持模块化模板,用于在不更改代码的情况下自定义审核行为。
快速模板设置
1.创建自定义模板:
touch src/templates/custom/my-review.md2.用变量编写模板:
**Role:** You are a security-focused code reviewer.
**Goal:** Review {{repository}} for vulnerabilities.
**PR:** `{{prUrl}}`
## Security Checklist
- Check for SQL injection
- Verify input validation
- Review authentication logic
## Final Step: Output Metrics{"isLgtm": true/false, "issueCount": 0}
**3.将存储库映射到模板:**
编辑 `src/config/config.json` (模板和分支规则):
{ "defaultTemplate": "default", "repositories": { "payment-api": "my-review" }, "prReview": { "enabled": true, "targetBranchPatterns": [], "sourceBranchPatterns": [] }, "releaseNote": { "enabled": false, "targetBranchPatterns": ["^release-"], "sourceBranchPatterns": [] } }
空 `prReview.targetBranchPatterns` =对所有PR进行审核。集 `releaseNote.enabled` 以及自动生成发行说明的模式(例如,当目标分支匹配时 `^release-`).看 [模板_GUIDE.md](TEMPLATE_GUIDE.md) 对于分支规则。
**4.重新启动服务:**
docker-compose restart pr-automation
### 可用变量
在模板中使用这些: `{{prUrl}}`, `{{title}}`, `{{author}}`, `{{repository}}`, `{{sourceBranch}}`, `{{destinationBranch}}`, `{{description}}`
### 内置示例模板
- **`security-focused`** -安全漏洞分析
- **`performance-review`** -性能瓶颈检测
- **`quick-review`** -快速审核小更改
### 完整文档
📖 **看 [模板_GUIDE.md](./TEMPLATE_GUIDE.md)**.
## 测试
该项目包括全面的单元测试,以确保代码质量和可靠性。
### 运行测试
Install dependencies
npm install
Run all tests
npm test
Run tests in watch mode (auto-reruns on file changes)
npm run test:watch
Run tests with coverage report
npm run test:coverage
______________________________________________________________________
## 发展
### 不使用Docker运行
Install Claude CLI globally
npm install -g @anthropic-ai/claude-code
Install dependencies
npm install
Run tests to verify setup
npm test
Create projects directory
mkdir projects
Start in development mode with auto-reload
npm run dev
### 使用Docker运行(开发)
docker-compose.yml包括用于热重新加载的卷挂载:
docker-compose up
## Claude CLI命令
系统执行Claude CLI如下:
claude --dangerously-skip-permissions \ -p "$(cat prompt.txt)" \ --model "sonnet" \ --output-format text
### 标志说明:
- `--dangerously-skip-permissions`:跳过交互式审批提示(自动化所需)
- `-p`:从文件中提供提示
- `--model`:选择模型(俳句、十四行诗、小品)
- `--output-format text`:获取纯文本输出
## Git操作
系统自动处理git操作:
- **克隆**:如果存储库不存在,则从Bitbucket克隆
- **更新**:如果存储库存在,则提取最新更改
- **认证**:使用环境变量中的令牌和用户名
### 支持的身份验证方法
**应用程序密码(令牌+用户):**
BITBUCKET_USER=your-username BITBUCKET_TOKEN=your-token-here
## 配置
非秘密应用程序设置已上线 **`src/config/config.json`**.环境变量覆盖config.json(用于Docker或每个环境覆盖)。机密永远不会存储在配置中,必须通过环境设置。
### 秘密(仅限环境)
|变量|必填|描述|
|----------|----------|-------------|
| `BITBUCKET_TOKEN` |是| Bitbucket应用程序密码或令牌|
| `BITBUCKET_USER` |是|比特桶用户名|
| `BITBUCKET_WEBHOOK_SECRET` |推荐| Webhook签名验证密钥|
也: `SHELL` 和 `NODE_ENV` 仅限runtime/env。
### 应用程序配置(config.json,可选环境覆盖)
默认值为 `src/config/config.json`。您可以通过环境覆盖其中任何一个:
|config.json路径|环境覆盖|默认值|描述|
|------------------|--------------|---------|-------------|
| `server.port` | `PORT` | `3000` |服务器端口|
| `claude.model` | `CLAUDE_MODEL` | `sonnet` |克劳德模型(如俳句、十四行诗、小品、glm-4.6)|
| `claude.timeoutMinutes` | `CLAUDE_TIMEOUT_CONFIG` | `10` |克劳德分析超时(分钟)|
| `claude.maxDiffSizeKb` | `MAX_DIFF_SIZE_KB` | `200` |提示中包含的最大差异大小(KB)|
| `bitbucket.allowedWorkspace` | `ALLOWED_WORKSPACE` | `yourworkspace` |Bitbucket工作区接受来自|
| `bitbucket.nonAllowedUsers` | `NON_ALLOWED_USERS` |-|要跳过的逗号分隔显示名称|
| `eventFilter.processOnlyCreated` | `PROCESS_ONLY_CREATED` | `false` |仅处理公关创建事件|
| `manualTrigger.enabled` | - | `true` |启用基于评论的手动审核触发器|
| `manualTrigger.requireMention` | - | `true` |需要 `@botName` 在触发器注释中提及|
| `manualTrigger.keywords` | - | `["review"]` |触发词开始手动审查|
| `manualTrigger.botNames` | - | `[]` (自动播种自 `BITBUCKET_USER` 当为空时)|在提及中识别的机器人名称|
| `metrics.persistence.*` | `METRICS_PERSISTENCE_*` |-|度量持久性(启用、类型、路径、saveIntervalMs)|
| `logging.*` | `LOG_*` |-|日志级别、文件保留、控制台/文件切换|
| `circuitBreaker.*` | `CB_*` |-|断路器阈值和复位超时|
| `promptLogs.enabled` / `.path` | `PROMPT_LOGS_*` | `false`, `/app/prompt-logs` |将提示日志持久化到路径|
模板和分支规则: `defaultTemplate`, `repositories`, `prReview`, `releaseNote` 也在config.json中(默认情况下没有环境覆盖)。
## 故障排除
### 检查服务是否正在运行
curl http://localhost:3000/health
### 查看日志
docker-compose logs -f pr-automation
### 在容器中测试Claude CLI
docker-compose exec pr-automation sh claude --help
### 检查克隆项目
docker-compose exec pr-automation ls -la /app/projects
### 手动测试git克隆
docker-compose exec pr-automation sh cd /app/projects git clone https://x-token-auth:YOUR_TOKEN@bitbucket.org/your-workspace/your-repo.git
### 重新启动服务
docker-compose restart
### 更改后重建
docker-compose down docker-compose build --no-cache docker-compose up -d
### 停止服务
docker-compose down
### 清除所有项目(重置)
rm -rf projects/* docker-compose restart
## Webhook安全
webhook端点有两层保护:
### 1.签名验证
所有webhook请求都必须在 `X-Hub-Signature` 头球这确保了请求实际上来自Bitbucket。
### 2.工作空间限制
只有webhooks从 `yourworkspace` Bitbucket工作区已被接受。这可以防止来自其他组织的未经授权的访问。
### 设置
1. **生成webhook密钥:**
openssl rand -hex 32
1. **添加 `.env` 文件:**
BITBUCKET_WEBHOOK_SECRET=your-generated-secret ALLOWED_WORKSPACE=yourworkspace
1. **在Bitbucket中配置:**
- 转到存储库设置→ 网络钩子
- 添加webhook URL: `https://bitbucket.tintinwinata.online/webhook/bitbucket/pr`
- 在“秘密”字段中添加相同的秘密
- 选择触发器:PR已创建,PR已更新
1. **重新启动服务:**
docker compose restart pr-automation
**📖 看 [网络安全.md](./WEBHOOK_SECURITY.md) 详细配置和故障排除。**
## 使用Prometheus进行监控
该应用程序在以下位置公开了Prometheus指标 `/metrics` 用于监控PR自动化活动和Claude审查绩效的端点。
### 可用指标
- **PR创建**: `pr_created_total` -创建的PR数量
- **PR已更新**: `pr_updated_total` -更新的PR数量
- **LGTM计数**: `claude_lgtm_total` -Claude的批准数量
- **发现的问题**: `claude_issues_found_total` -发现的所有问题的总数(例如,如果1个PR有3个问题,则将3添加到计数器中)
- **成功的评论**: `claude_review_success_total` -PR已成功审核
- **失败的评论**: `claude_review_failure_total` -失败的评论(有错误类型)
- **评审持续时间**: `claude_review_duration_seconds` -评审持续时间柱状图
### 访问指标
curl http://localhost:3000/metrics
### 详细文档
看 [普罗米修斯.md](./PROMETHEUS.md) 用于:
- 详细的度量描述
- Grafana仪表板示例
- PromQL查询示例
**备注**:Prometheus已在中配置 `/workspace/monitoring/prometheus.yml` 从中提取指标 `pr-automation:3000`.
### 指标持久性
默认情况下,指标存储在内存中,并在应用程序重新启动时重置。您可以启用指标持久性,以在重启和容器重建过程中保留指标。
#### 启用指标持久性
将这些环境变量添加到您的 `.env` 文件:
METRICS_PERSISTENCE_ENABLED=true METRICS_PERSISTENCE_TYPE=filesystem METRICS_PERSISTENCE_PATH=./metrics-storage METRICS_PERSISTENCE_SAVE_INTERVAL_MS=30000
#### 存储类型
**文件系统(建议用于大多数用例)**
- 将指标存储在JSON文件中
- 简单易检
- 适用于中小型部署
- 默认存储类型
**SQLite(推荐用于大型部署)**
- 将指标存储在SQLite数据库中
- 高容量指标的性能更好
- 需要 `better-sqlite3` 软件包(自动安装)
- 如果SQLite不可用,则回退到文件系统
#### 配置选项
|选项|描述|默认值|
|--------|-------------|---------|
| `METRICS_PERSISTENCE_ENABLED` |启用/禁用持久性| `false` |
| `METRICS_PERSISTENCE_TYPE` |存储类型: `filesystem` 或 `sqlite` | `filesystem` |
| `METRICS_PERSISTENCE_PATH` |存储指标的路径(相对或绝对)| `./metrics-storage` |
| `METRICS_PERSISTENCE_SAVE_INTERVAL_MS` |多久保存一次指标(毫秒)| `30000` (30秒)|
#### Docker设置
使用Docker时,请确保将metrics存储目录作为卷挂载:
volumes: - ./metrics-storage:/app/metrics-storage
这确保了即使在容器重建时,指标也会持续存在。
#### 运作原理
1. **启动时**:应用程序从存储中加载持久化指标,并将其还原到Prometheus注册表中
1. **运行时**:每30秒自动保存一次指标(可通过以下方式配置 `METRICS_PERSISTENCE_SAVE_INTERVAL_MS`)
1. **关机时**:在流程退出之前,最后一次保存度量值
#### 向后兼容
- 指标持久性是 **选择加入** -默认情况下禁用
- 如果持久性初始化失败,应用程序将在没有持久性的情况下继续运行(记录警告)
- 没有持久性的现有部署继续像以前一样工作
#### 故障排除
**指标不持久:**
- 检查一下 `METRICS_PERSISTENCE_ENABLED=true` 已设置
- 验证存储路径是否可写
- 检查应用程序日志中是否存在与持久性相关的错误
**权限错误:**
- 确保存储目录存在并且可写
- 在Docker中,验证卷装载是否配置正确
## 贡献
欢迎为这个项目做出贡献!您是否愿意:
- 🐛 **报告错误** 或问题
- 💡 **建议新功能** 或改进
- 🔧 **提交拉取请求** 带有修复或增强功能
- 📖 **改进文档** 或示例
- 🧪 **添加测试** 或改进现有的
### 入门指南
1. **分叉存储库**
1. **创建要素分支**: `git checkout -b feature/your-feature-name`
1. **进行更改** 并对其进行彻底测试
1. **提交您的更改**: `git commit -m "Add your feature"`
1. **推你的叉子**: `git push origin feature/your-feature-name`
1. **打开拉取请求**
### 问题或讨论?
我总是乐于讨论问题、审查PR,或者只是谈论项目!
**欢迎在LinkedIn上给我发DM** -我很乐意收到你的来信,并帮助你解决任何问题。
[领英个人资料](https://linkedin.com/in/tintinwinata)
______________________________________________________________________
**编码愉快! 🚀**