完整实现企业级 DevOps 全链路解决方案 ## 核心功能 ✅ Plane 任务管理系统部署 (Docker Compose + K8s) ✅ Gitea ↔ GitHub 双向镜像同步 ✅ Plane ↔ Gitea 集成 (Issue/PR 双向同步) ✅ Plane ↔ GitHub 集成 (Issue/PR 双向同步) ✅ CI/CD Pipeline 配置 ✅ Claude AI 辅助开发工作流 ## 主要组件 ### 部署配置 - plane/docker-compose.yaml - Plane 完整部署 - k3s/plane.yaml - Kubernetes 生产部署 - gitea/docker-compose.yaml - Gitea 配置 ### 同步服务 - gitea-to-github-sync/ - Gitea ↔ GitHub 镜像同步 - plane-integration/gitea-sync/ - Plane ↔ Gitea 同步 - plane-integration/github-sync/ - Plane ↔ GitHub 同步 ### 文档 - README.md - 完整系统文档 - DEPLOYMENT-CHECKLIST.md - 部署检查清单 - docs/plane-templates.md - Plane Issue 模板 - docs/claude-dev-workflow.md - Claude AI 工作流 ### 自动化脚本 - deploy.sh - 一键部署脚本 - gitea/gitea-mirror.sh - Gitea 镜像管理 ## 快速开始 ```bash ./deploy.sh ``` 详见 README.md --- 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
11 KiB
Plane ↔ GitHub Webhook 集成配置指南
概述
本指南介绍如何配置 Plane 和 GitHub 之间的 webhook 集成,实现双向同步和 GitHub Actions 集成。
架构
Plane ←→ Plane-GitHub-Sync Service ←→ GitHub
前置条件
- Plane 已部署并运行
- GitHub 账号和仓库
- Plane-GitHub-Sync 服务已部署
步骤 1: 获取 Token
1.1 获取 Plane API Token
- 登录 Plane:
http://localhost:8000 - 进入 Settings → API Tokens
- 创建新的 API Token
- 复制 Token
1.2 创建 GitHub Personal Access Token
- 登录 GitHub
- Settings → Developer settings → Personal access tokens → Tokens (classic)
- Generate new token (classic)
- 选择权限:
- ✅
repo(完整权限) - ✅
workflow - ✅
write:org(如果需要组织权限) - ✅
admin:repo_hook(webhook 管理)
- ✅
- 生成并复制 Token
1.3 创建 GitHub OAuth App (可选,用于用户认证)
- Settings → Developer settings → OAuth Apps → New OAuth App
- 填写信息:
- Application name:
Plane Integration - Homepage URL:
http://localhost:8000 - Authorization callback URL:
http://localhost:8000/api/oauth/github/callback
- Application name:
- 生成 Client Secret
- 保存 Client ID 和 Client Secret
步骤 2: 配置环境变量
编辑 plane/.env:
# Plane API
PLANE_API_URL=http://plane-api:8000
PLANE_API_TOKEN=plane_your_token_here
# GitHub
GITHUB_TOKEN=ghp_your_token_here
GITHUB_CLIENT_ID=your_oauth_client_id
GITHUB_CLIENT_SECRET=your_oauth_client_secret
# Webhook Secret
WEBHOOK_SECRET=your-random-secret-string
步骤 3: 在 GitHub 配置 Webhook
3.1 仓库级 Webhook
- 进入 GitHub 仓库
- Settings → Webhooks → Add webhook
- 填写配置:
Payload URL: http://your-domain:8002/webhook/github
Content type: application/json
Secret: <your-webhook-secret>
-
选择触发事件:
- ✅ Push
- ✅ Pull requests
- ✅ Issues
- ✅ Issue comments
- ✅ Pull request reviews
- ✅ Pull request review comments
- ✅ Statuses
- ✅ Check runs
-
勾选 "Active"
-
点击 "Add webhook"
3.2 组织级 Webhook (可选)
- 进入 GitHub 组织
- Settings → Webhooks
- 按照上述步骤配置
3.3 使用 GitHub App (推荐生产环境)
创建 GitHub App 比 webhook 更安全:
- Settings → Developer settings → GitHub Apps → New GitHub App
- 填写基本信息
- 配置权限:
- Repository permissions:
- Contents: Read & write
- Issues: Read & write
- Pull requests: Read & write
- Metadata: Read-only
- Repository permissions:
- 订阅事件 (同 webhook)
- Webhook URL:
http://your-domain:8002/webhook/github - 生成并下载 Private key
- 安装到组织/仓库
步骤 4: 在 Plane 配置项目集成
4.1 添加 GitHub 集成信息
在 Plane 项目中创建自定义属性:
github_integration:
owner: your-username-or-org
repo: your-repo-name
sync_enabled: true
auto_close_on_merge: true
4.2 用户映射 (可选)
创建 Plane 用户到 GitHub 用户的映射:
在 Plane 用户 profile 中添加:
- GitHub Username:
your-github-username
步骤 5: 测试集成
5.1 测试 GitHub → Plane
测试 Issue 同步
- 在 GitHub 创建新 Issue
- 检查 Plane 是否创建对应 Issue
- 查看日志:
docker logs plane-github-sync
测试 PR 更新
- 创建 PR, 标题包含
Fixes #123 - 合并 PR
- 检查 Plane Issue #123 是否更新为 "Completed"
5.2 测试 Plane → GitHub
- 在 Plane 创建 Issue
- 手动触发同步:
curl -X POST http://localhost:8002/sync/manual \
-H "Content-Type: application/json" \
-d '{
"workspace_slug": "my-workspace",
"project_id": "proj_123",
"github_owner": "your-username",
"github_repo": "your-repo"
}'
- 检查 GitHub 是否创建对应 Issue
5.3 测试 Webhook 签名验证
# 发送测试 webhook
curl -X POST http://localhost:8002/webhook/github \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: ping" \
-H "X-Hub-Signature-256: sha256=test" \
-d '{"zen": "test"}'
事件映射表
GitHub Events → Plane Actions
| GitHub Event | Plane Action | 说明 |
|---|---|---|
| Issue Created | Create Plane Issue | 自动创建对应 Issue |
| Issue Updated | Update Plane Issue | 同步标题、描述、标签 |
| Issue Closed | Update state to "Completed" | 自动关闭 |
| Issue Reopened | Update state to "In Progress" | 重新打开 |
| PR Opened | Add comment to linked Issue | 记录 PR 信息 |
| PR Merged | Update Issue to "Completed" | 自动完成 |
| PR Closed | Add comment | 记录关闭信息 |
| PR Review Approved | Add comment | 记录 Review |
| Push (with issue ref) | Add commit comment | 追踪提交 |
| Check Run Completed | Add status comment | CI/CD 状态 |
Plane Events → GitHub Actions
| Plane Event | GitHub Action | 说明 |
|---|---|---|
| Issue Created | Create GitHub Issue | 自动创建 Issue |
| Issue Updated | Update GitHub Issue | 同步更新 |
| Issue State Changed | Update Issue state | 同步状态 |
| Issue Assigned | Update Issue assignees | 同步负责人 |
| Issue Completed | Close GitHub Issue | 自动关闭 |
Issue 关联规则
从 Commit Message 关联
支持的关键词:
# 关闭 Issue
git commit -m "Fixes #123"
git commit -m "Closes #456"
git commit -m "Resolves #789"
# 关联但不关闭
git commit -m "Related to #101"
git commit -m "See #202"
git commit -m "Part of #303"
# 多个 Issue
git commit -m "Fixes #123, #456, #789"
从 PR 关联
在 PR 标题:
[Feature] Add user authentication (Fixes #123)
在 PR 描述:
## Description
User authentication feature
## Related Issues
Closes #123
Related to #456
使用 GitHub Keywords
GitHub 官方支持的关键词:
close,closes,closedfix,fixes,fixedresolve,resolves,resolved
GitHub Actions 集成
自动更新 Plane Issue
创建 .github/workflows/plane-sync.yml:
name: Sync with Plane
on:
pull_request:
types: [opened, closed, merged]
issues:
types: [opened, closed, reopened]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Notify Plane
env:
PLANE_WEBHOOK_URL: ${{ secrets.PLANE_WEBHOOK_URL }}
PLANE_API_TOKEN: ${{ secrets.PLANE_API_TOKEN }}
run: |
curl -X POST $PLANE_WEBHOOK_URL \
-H "Authorization: Bearer $PLANE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event": "${{ github.event_name }}",
"action": "${{ github.event.action }}",
"repository": "${{ github.repository }}",
"number": "${{ github.event.number }}",
"sender": "${{ github.actor }}"
}'
PR 质量检查
创建 .github/workflows/pr-check.yml:
name: PR Quality Check
on:
pull_request:
types: [opened, synchronize]
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Check PR has issue reference
run: |
if ! echo "${{ github.event.pull_request.title }}" | grep -qE '#[0-9]+'; then
if ! echo "${{ github.event.pull_request.body }}" | grep -qE '(Closes|Fixes|Resolves) #[0-9]+'; then
echo "❌ PR must reference an issue"
exit 1
fi
fi
echo "✅ PR references an issue"
- name: Update Plane Issue
env:
PLANE_SYNC_URL: http://plane-github-sync:8002/webhook/github
run: |
# Trigger Plane update
curl -X POST $PLANE_SYNC_URL \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"event": "pull_request",
"pr": {
"number": ${{ github.event.pull_request.number }},
"title": "${{ github.event.pull_request.title }}",
"state": "${{ github.event.pull_request.state }}",
"html_url": "${{ github.event.pull_request.html_url }}"
}
}
EOF
高级配置
1. 自动标签映射
在 sync_service.py 中配置:
LABEL_MAPPING = {
'bug': 'type:bug',
'feature': 'type:feature',
'enhancement': 'type:enhancement',
'documentation': 'type:docs',
'high priority': 'priority:high',
'low priority': 'priority:low',
}
2. 自定义同步规则
只同步特定标签的 Issue:
SYNC_FILTERS = {
'labels': ['sync-to-plane'], # 只同步带此标签的 Issue
'exclude_labels': ['wontfix', 'duplicate'], # 排除这些标签
}
3. 双向冲突解决
当 Plane 和 GitHub 同时更新时:
CONFLICT_RESOLUTION = 'github_wins' # 可选: 'plane_wins', 'github_wins', 'manual'
安全最佳实践
- ✅ 使用 GitHub App 而非 Personal Access Token (生产环境)
- ✅ 启用 webhook secret 验证
- ✅ 使用 HTTPS (生产环境)
- ✅ 限制 Token 权限范围
- ✅ 定期轮换 Token
- ✅ 监控 webhook 调用
- ✅ 使用 IP 白名单 (GitHub webhook IPs)
GitHub Webhook IP 白名单
# 获取 GitHub webhook IPs
curl https://api.github.com/meta | jq -r '.hooks[]'
# 在防火墙配置中添加
故障排查
Webhook 未收到
- 检查 GitHub webhook deliveries:
- Repository → Settings → Webhooks → Recent Deliveries
- 检查响应状态码
- 查看错误信息
签名验证失败
# 验证签名计算
echo -n '{"test": "data"}' | openssl dgst -sha256 -hmac "your-secret"
Issue 未同步
- 检查日志:
docker logs -f plane-github-sync
- 手动测试 API:
# 测试 GitHub API
curl -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/owner/repo/issues
# 测试 Plane API
curl -H "Authorization: Bearer $PLANE_API_TOKEN" \
$PLANE_API_URL/api/v1/workspaces/workspace-slug/projects/
监控和日志
健康检查
curl http://localhost:8002/health
查看同步统计
# 查看最近 100 条日志
docker logs plane-github-sync --tail 100
# 实时查看日志
docker logs -f plane-github-sync
# 只看错误
docker logs plane-github-sync 2>&1 | grep ERROR
Prometheus 监控 (可选)
添加 metrics endpoint:
from prometheus_client import Counter, generate_latest
webhook_received = Counter('webhook_received_total', 'Total webhooks received')
sync_success = Counter('sync_success_total', 'Total successful syncs')
sync_errors = Counter('sync_errors_total', 'Total sync errors')
@app.route('/metrics')
def metrics():
return generate_latest()