dev-manager-tauri/.blueprint/modules/gitea-integration.md
lanrtop d14b348845 feat(gitea): G2-G5 全链路——建仓/迁移/绑定 + webhook 收发 + 治理面板
G2 控制面:gitea_create_repo / gitea_migrate_repo / gitea_link_repo,
   upsert 绑定(换绑自动重置 webhook 字段),API 错误提取 Gitea message 可读返回
G3 观测面:MCP Server 新增 POST /webhook/gitea/:project_id——HMAC-SHA256 验签
   (X-Gitea-Signature,兼容 X-Hub-Signature-256)→ 解析 commits → 批量
   record_commit(sha 幂等,与本地 watcher 双路径不重复计数);验签失败记 log_event
G4 webhook 注册:gitea_setup_webhook 生成随机 secret 注册 push hook(重设先删旧)、
   gitea_unlink_repo 解绑顺带清理 Gitea 侧 hook
G5 治理面板:GiteaPanel——实例管理(添加/测试/删除)、当前项目三种绑定方式、
   webhook 注册与可复制回调地址、全部绑定概览

依赖:新增 hmac + sha2;project_id 与 commit_metrics 同源(Project.id),
避免双路径冲突复发;R10 修正设计文档错误签名头

验证:cargo test 58 passed(新增 upsert 换绑重置 + hmac 正反向 + payload 解析 5 测试)、
typecheck 全绿
2026-07-02 14:22:49 +09:00

9.9 KiB
Raw Blame History

Gitea 集成

对接已有的自建 Gitea 实例,作为所有被管理项目的统一 git 后端。接入包「增配档」的核心。

风筝线模型(炼境与 Gitea 的关系)

🪁 风筝 = Gitea 本体git 存储 + CI 执行):独立部署、独立运行,炼境不托管其进程、不背运维🧵 线 = 炼境的掌控(控制面):炼境是唯一持线人——Gitea 连接/token 统一存炼境,建仓/关联/迁移/配置 lefthook&CI 的操控全经炼境,子项目对 Gitea 的动作都从它手里过。 👀 关注风筝的动态 = 观测面(飞轮燃料):炼境持续感知每个子项目 ↔ Gitea 的连接动态push 的 commit type/scope、PR、CI 三阶段、review、停滞项目

「线」≠ 松散 API 对接:炼境是主动掌控者而非被动客户端。风筝越多 → 线越多 → 动态越丰富 → 飞轮越强(契合核心愿景)。

其他边界

  • 替代炼境现有 GitHub 能力:github-auth / github-publish 已退役2026-07-02见 github-decommissioncicd.rs 的 GitHub Actions 生成改造为 Gitea Actions
  • 炼境自身仓库也迁 Gitea发布产物仍走 OSS updater 不变)
  • 不使用 Gitea Issues / Projects / Milestones / Wiki任务跟踪的意图层acceptance/complexity/depends/复盘)由蓝图任务卡承载,与 Claude 工作流深度耦合Gitea 只做三件事——存代码、跑 CI、发事件。蓝图与 Gitea 的唯一耦合关节 = conventional commit scope ↔ 蓝图 module id 映射(单点、单向、可降级)

参考实现

enterprise-system 已趟通完整链路,属「照搬」而非「从零探索」:

  • Gitea origingit.yljt.info+ Gitee 镜像(备份)
  • lefthook 强制 conventional commit + typecheckpre-commit
  • Gitea Actions 三阶段 CI静态检查 → 测试DeepSeek-V3 自修)→ PR code reviewDeepSeek
  • Gitea Actions 语法兼容 GitHub Actions迁移成本低

详见 E:/code-project/enterprise-system/docs/ai-context/git-workflow.mdAGENTS.md

架构设计2026-06-30 /architect

实现策略

webhook 接收端:扩展已有 MCP ServerAxum端口 27190添加 POST /webhook/gitea/:project_id 路由。零新依赖,复用端口和进程。

HTTP 客户端ureqCargo.toml 已有github.rs 已有使用范例),调 Gitea API v1。

数据表:新增 gitea_instances(实例管理)+ gitea_repos(项目-仓库绑定)。

CREATE TABLE IF NOT EXISTS gitea_instances (
    id           TEXT PRIMARY KEY,
    name         TEXT NOT NULL,
    url          TEXT NOT NULL,           -- https://gitea.myserver.com
    access_token TEXT NOT NULL,
    is_default   INTEGER NOT NULL DEFAULT 0,
    created_at   TEXT DEFAULT (datetime('now'))
);

CREATE TABLE IF NOT EXISTS gitea_repos (
    id              TEXT PRIMARY KEY,
    instance_id     TEXT NOT NULL REFERENCES gitea_instances(id) ON DELETE CASCADE,
    project_id      TEXT NOT NULL,        -- blueprint_buffs.project_idUUID
    gitea_owner     TEXT NOT NULL,
    gitea_repo_name TEXT NOT NULL,
    clone_url       TEXT,
    webhook_secret  TEXT,                 -- HMAC-SHA256 secret
    webhook_id      INTEGER,              -- Gitea 返回的 hook ID
    linked_at       TEXT DEFAULT (datetime('now'))
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_gitea_repos_project ON gitea_repos(project_id);

webhook 流程

Gitea push → POST /webhook/gitea/:project_id
  1. 从 gitea_repos 查 webhook_secret
  2. HMAC-SHA256 验签 X-Gitea-Signature兼容 X-Hub-Signature-256
  3. 解析 payload.commits[]sha / message / timestamp
  4. 批量 record_commit(project_id, sha, message, date)
  5. 返回 200 OK验签失败记 log_event

修正2026-07-02R10原设计写的签名头 X-Gitea-Signature-256 有误Gitea 实际发送 X-Gitea-Signaturepayload 的 HMAC-SHA256 hex实现以实际行为为准并兼容 GitHub 风格头。 project_id 采用与 commit_metrics/ingest_full_git_history 相同的 Project.idgetProjects 体系), 避免重蹈 project_id 双路径冲突b13dc83 教训)。

网络说明Gitea 服务器需能访问宿主机 {ip}:27190MCP 端口。UI 显示可复制的 webhook 回调地址,用户自行确认网络可达。


任务卡concept待 /architect

💭 Gitea API 对接(握线基础)

  • status: concept
  • complexity: L
  • acceptance: TBD —— 建仓/关联、推送、读 CI 状态、读 PR review 结果

⚠️ 建仓/关联部分已被 G1/G2 实现取代;剩余范围收窄为「读 CI 状态、读 PR review 结果」(依赖 Gitea Actions 落地后再议)。

💭 观测面Gitea webhook 接入(持线人感知动态)

  • status: concept
  • complexity: L
  • files: src-tauri/src/mcp_server.rs内嵌 HTTP server 加 webhook 端点), src-tauri/src/commands/blueprint.rs
  • acceptance: TBD —— 复用炼境内嵌 HTTP server 新增 Gitea webhook 接收端点;实时接住各子项目 push/PR/CI/review 事件 → 解析 conventional commit对接 flywheel-intelligence 的 L0 解析层)→ 写飞轮快照 + 刷新连接动态webhook 不可达时降级为定时轮询 Gitea API

⚠️ push 事件部分已被 G3/G4 实现取代剩余范围收窄为「PR/CI/review 事件 + 轮询降级」见「PR 事件 ↔ 蓝图任务卡联动」concept 卡)。

📋 Gitea Actions workflow 生成

  • status: todo
  • complexity: M
  • depends: G1
  • files: src-tauri/src/commands/cicd.rs, src/components/dashboard/CicdModal.tsx
  • acceptance: generate_workflow 产出 Gitea Actions 模板(.gitea/workflows/,语法兼容 GitHub Actions参考 enterprise-system 三阶段 CIweb_ssh 与 tauri_oss 两类配置均支持CicdModal 的 Secrets 提示文案改为 Gitea 路径Settings → Actions → Secrets生成后模板中不残留 github.com 引用

一石三鸟:炼境自身仓库迁 Gitea 有了工具CicdModal 残留 GitHub 模板的问题解决(见 github-decommission 复盘遗留②CI 事实流有了源头。

💭 DeepSeek CI review 集成(可选插件)

  • status: concept
  • complexity: L
  • acceptance: TBD —— 静态检查 + 测试自修 + PR review作为复杂项目可选增配不进基线档

💭 旧项目 GitHub → Gitea 迁移

  • status: concept
  • complexity: M
  • acceptance: TBD —— remote 切换 + 推送,安全增量,不丢历史

💭 PR 事件 ↔ 蓝图任务卡联动

  • status: concept
  • depends: G3
  • notes: webhook 收到 PR 事件 → 解析 title 的 conventional scope → 匹配蓝图模块 → 对应任务卡置 🔵 in_progress加锁提示。铁律 R09绝不自动置 ,完成语义只能由 Claude/人工验收产生merge 事件仅在导师报告中生成"待验收提醒"。不使用 Gitea Issues/Projects 做任务系统(见决策记录)。

任务卡(可执行,拆自 2026-06-30 /architect

G1. DB schema + Gitea 实例 CRUD

  • status: done
  • complexity: M
  • files: src-tauri/src/db.rs, src-tauri/src/commands/gitea.rs, src-tauri/src/lib.rs, src/lib/commands.ts
  • acceptance: gitea_instances + gitea_repos 表建好migratesave/list/delete/test_connection 命令可调test_connection 调 GET /api/v1/user 返回 Gitea 用户名验证 token 有效性

G2. 仓库创建 / 迁移 / 绑定

  • status: done
  • complexity: M
  • depends: G1
  • files: src-tauri/src/commands/gitea.rs, src/lib/commands.ts
  • acceptance: gitea_create_repo 调 Gitea API 建仓后写 gitea_reposgitea_migrate_repo 能从 GitHub/GitLab 迁移仓库到 Giteagitea_link_repo 绑定已有仓库;命令失败返回可读错误

G3. Webhook 接收端MCP Server 扩展)

  • status: done
  • complexity: M
  • depends: G1
  • files: src-tauri/src/mcp_server.rs
  • acceptance: POST /webhook/gitea/:project_id 路由上线HMAC-SHA256 验签通过后解析 commits 数组批量写 commit_metrics验签失败记 log_event单元测试覆盖 parse_push_payload + hmac_verify

G4. Webhook 注册命令

  • status: done
  • complexity: M
  • depends: G2, G3
  • files: src-tauri/src/commands/gitea.rs, src/lib/commands.ts
  • acceptance: gitea_setup_webhook 生成随机 secret调 Gitea API POST /repos/:owner/:repo/hooks 注册events=push写 webhook_secret + webhook_id 到 gitea_reposgitea_unlink_repo 清理绑定

G5. Gitea 治理面板 UI

  • status: done
  • complexity: M
  • depends: G1, G2, G3, G4
  • files: src/components/dashboard/GiteaPanel.tsx, src/components/dashboard/BlueprintModal.tsx
  • acceptance: 治理面板新增"Gitea"区块;可添加/测试/删除实例;显示已绑定仓库列表(仓库名/webhook 状态);操作:新建仓库、迁移、绑定已有、设置 webhook显示可复制的 webhook 回调地址

复盘笔记

【复盘】G2-G5 控制面 + 观测面全链路2026-07-02 任务类型: 后端命令 + MCP工具 + 前端组件 复杂度: M×4 实际轮数: 1轮预估 2 轮) 是否返工: 否 有效策略: 续接 🔵 锁前先读代码判断真实断点G1 已含查询命令G2 只缺三个写命令webhook 验签/解析拆成纯函数使单元测试不依赖 HTTP 层;绑定 UI 的 project_id 显式对齐 ingest_full_git_history 的 Project.id 体系 遗留风险: ① 全链路未在真实 Gitea 实例上端到端验证(建仓/webhook 注册/push 接收),首次使用时按 G5 面板流程走一遍即是验收;② gitea_migrate_repo 未处理同名仓库已存在的场景Gitea 返回 409错误信息可读但需手动改名③ webhook 回调地址依赖用户确认网络可达,无自动探测 auto_applied_rules: R01, R05, R06, R07, R10 rule_effectiveness: R01=有效, R05=有效(复用已有表无新 migration, R06=有效upsert 依赖注入可测), R07=有效5 个新测试), R10=有效(纠正了设计文档中错误的签名头 X-Gitea-Signature-256 → 实际 X-Gitea-Signature