Files
bruno fc185b9ab5 feat: 初始化 Plane + Gitea + GitHub 全链路集成系统
完整实现企业级 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>
2025-11-25 07:02:44 +08:00

11 KiB

Plane ↔ GitHub Webhook 集成配置指南

概述

本指南介绍如何配置 Plane 和 GitHub 之间的 webhook 集成,实现双向同步和 GitHub Actions 集成。

架构

Plane ←→ Plane-GitHub-Sync Service ←→ GitHub

前置条件

  1. Plane 已部署并运行
  2. GitHub 账号和仓库
  3. Plane-GitHub-Sync 服务已部署

步骤 1: 获取 Token

1.1 获取 Plane API Token

  1. 登录 Plane: http://localhost:8000
  2. 进入 Settings → API Tokens
  3. 创建新的 API Token
  4. 复制 Token

1.2 创建 GitHub Personal Access Token

  1. 登录 GitHub
  2. Settings → Developer settings → Personal access tokens → Tokens (classic)
  3. Generate new token (classic)
  4. 选择权限:
    • ✅ repo (完整权限)
    • ✅ workflow
    • ✅ write:org (如果需要组织权限)
    • ✅ admin:repo_hook (webhook 管理)
  5. 生成并复制 Token

1.3 创建 GitHub OAuth App (可选,用于用户认证)

  1. Settings → Developer settings → OAuth Apps → New OAuth App
  2. 填写信息:
    • Application name: Plane Integration
    • Homepage URL: http://localhost:8000
    • Authorization callback URL: http://localhost:8000/api/oauth/github/callback
  3. 生成 Client Secret
  4. 保存 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

  1. 进入 GitHub 仓库
  2. Settings → Webhooks → Add webhook
  3. 填写配置:
Payload URL: http://your-domain:8002/webhook/github
Content type: application/json
Secret: <your-webhook-secret>
  1. 选择触发事件:

    • ✅ Push
    • ✅ Pull requests
    • ✅ Issues
    • ✅ Issue comments
    • ✅ Pull request reviews
    • ✅ Pull request review comments
    • ✅ Statuses
    • ✅ Check runs
  2. 勾选 "Active"

  3. 点击 "Add webhook"

3.2 组织级 Webhook (可选)

  1. 进入 GitHub 组织
  2. Settings → Webhooks
  3. 按照上述步骤配置

3.3 使用 GitHub App (推荐生产环境)

创建 GitHub App 比 webhook 更安全:

  1. Settings → Developer settings → GitHub Apps → New GitHub App
  2. 填写基本信息
  3. 配置权限:
    • Repository permissions:
      • Contents: Read & write
      • Issues: Read & write
      • Pull requests: Read & write
      • Metadata: Read-only
  4. 订阅事件 (同 webhook)
  5. Webhook URL: http://your-domain:8002/webhook/github
  6. 生成并下载 Private key
  7. 安装到组织/仓库

步骤 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 同步

  1. 在 GitHub 创建新 Issue
  2. 检查 Plane 是否创建对应 Issue
  3. 查看日志:
docker logs plane-github-sync

测试 PR 更新

  1. 创建 PR, 标题包含 Fixes #123
  2. 合并 PR
  3. 检查 Plane Issue #123 是否更新为 "Completed"

5.2 测试 Plane → GitHub

  1. 在 Plane 创建 Issue
  2. 手动触发同步:
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"
  }'
  1. 检查 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, closed
  • fix, fixes, fixed
  • resolve, 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'

安全最佳实践

  1. ✅ 使用 GitHub App 而非 Personal Access Token (生产环境)
  2. ✅ 启用 webhook secret 验证
  3. ✅ 使用 HTTPS (生产环境)
  4. ✅ 限制 Token 权限范围
  5. ✅ 定期轮换 Token
  6. ✅ 监控 webhook 调用
  7. ✅ 使用 IP 白名单 (GitHub webhook IPs)

GitHub Webhook IP 白名单

# 获取 GitHub webhook IPs
curl https://api.github.com/meta | jq -r '.hooks[]'

# 在防火墙配置中添加

故障排查

Webhook 未收到

  1. 检查 GitHub webhook deliveries:
    • Repository → Settings → Webhooks → Recent Deliveries
  2. 检查响应状态码
  3. 查看错误信息

签名验证失败

# 验证签名计算
echo -n '{"test": "data"}' | openssl dgst -sha256 -hmac "your-secret"

Issue 未同步

  1. 检查日志:
docker logs -f plane-github-sync
  1. 手动测试 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()

参考资源