Initial documentation for route A (port claude-code-action to Gitea Actions). Research complete, no implementation code yet. See docs/02-roadmap.md for milestones.
5.4 KiB
5.4 KiB
03 - 移植计划
把
anthropics/claude-code-action源代码逐文件迁移到本仓库的清单。 上游版本:master @ 2026-05-23(克隆在/home/pangtiankai/projects/claude-code-action-upstream/)
目录映射
| 上游 | 本仓库 | 移植量 |
|---|---|---|
action.yml |
action.yml |
🟡 改 inputs:去掉 GitHub 特有字段(如 github_token → gitea_token) |
package.json |
package.json |
🟡 替换 @octokit/* 依赖 |
bunfig.toml |
bunfig.toml |
✅ 原样 |
tsconfig.json |
tsconfig.json |
✅ 原样 |
src/entrypoints/ |
src/entrypoints/ |
🟡 适配 Gitea 事件载荷字段 |
src/modes/tag/ |
src/modes/tag/ |
🟢 90% 原样,少量字段重命名 |
src/modes/agent/ |
— | ⛔ 暂不移植(后期再说) |
src/create-prompt/ |
src/create-prompt/ |
🟢 90% 原样 |
src/github/api/ |
src/gitea/api/ |
🔴 完全重写(Gitea API client) |
src/github/data/ |
src/gitea/data/ |
🔴 重写 schema |
src/github/operations/ |
src/gitea/operations/ |
🔴 重写(评论、branch、PR) |
src/github/validation/ |
src/gitea/validation/ |
🔴 重写 |
src/github/utils/ |
src/gitea/utils/ |
🟡 部分通用,部分重写 |
src/auth/ |
src/auth/ |
🟢 90% 原样(Anthropic API key 认证不变) |
src/mcp/ |
src/mcp/ |
✅ 原样 |
src/utils/ |
src/utils/ |
✅ 原样 |
base-action/ |
base-action/ |
🟢 90% 原样 |
统计:约 30% 文件要重写,60% 只改字段或导入路径,10% 完全不动。
重写优先级(P0 = 第一周必交付)
P0 — Gitea API client(src/gitea/api/)
最低要凑齐的 endpoint:
| 操作 | Gitea API | 备注 |
|---|---|---|
| 获取 issue | GET /repos/{owner}/{repo}/issues/{number} |
|
| 获取 issue 评论列表 | GET /repos/{owner}/{repo}/issues/{number}/comments |
|
| 创建评论 | POST /repos/{owner}/{repo}/issues/{number}/comments |
|
| 更新评论 | PATCH /repos/{owner}/{repo}/issues/comments/{id} |
用于流式更新("思考中..."→ 最终回复) |
| 获取 PR | GET /repos/{owner}/{repo}/pulls/{number} |
|
| 获取 PR diff | GET /repos/{owner}/{repo}/pulls/{number}.diff |
|
| 创建分支 | POST /repos/{owner}/{repo}/branches |
|
| 创建 PR | POST /repos/{owner}/{repo}/pulls |
|
| 获取仓库内容 | GET /repos/{owner}/{repo}/contents/{filepath} |
选择:直接用 fetch + zod schema,不引入完整 Gitea SDK(依赖最小化)。
P0 — Trigger 解析(src/modes/tag/)
需要适配的事件类型:
| Gitea 事件 | trigger 条件 |
|---|---|
issues.opened |
issue 正文含 @claude |
issues.edited |
同上 |
issue_comment.created |
评论正文含 @claude |
pull_request.opened |
PR 正文含 @claude |
pull_request_comment.created |
PR 评论含 @claude |
P0 — Entrypoint(src/entrypoints/)
读取 GITHUB_EVENT_PATH → 改成 GITEA_EVENT_PATH(Gitea Actions 自动注入)。
事件载荷字段:
github.event.issue.user.login → gitea.event.issue.user.login ✅ 一致
github.event.comment.user.login → gitea.event.comment.user.login ✅ 一致
github.repository → gitea.repository ✅ 一致
github.event.pull_request.head.sha → 一致
P1 — Status comment("我在干活" 进度评论)
上游用 GitHub Checks API 做进度展示,Gitea 没有等价 API(Gitea Issue #28381 是 commit status,不一样)。
替代方案:用一条评论的连续 edit 模拟。
- 第一条评论:"🤔 Claude 正在分析需求..."
- 边干边 PATCH 更新这条评论的正文
- 完成后定格成最终内容
P2 — agent mode、review mode
后期再说。
依赖替换
package.json
去掉:
"@actions/github": "^...",
"@octokit/rest": "^...",
"@octokit/graphql": "^...",
"@octokit/webhooks-types": "^..."
新增(如果需要):
// 如果用生成的 SDK
"gitea-js": "latest"
// 否则只用 fetch + zod,零新增
保留原样:
"@actions/core": "...", // 跟 Gitea Actions 兼容
"@anthropic-ai/claude-agent-sdk": "...",
"@modelcontextprotocol/sdk": "...",
"shell-quote": "...",
"zod": "..."
webhook payload 差异速查
Gitea 的 webhook payload 大部分字段和 GitHub 一致(这是有意为之的),主要差异:
| GitHub | Gitea | 说明 |
|---|---|---|
pull_request.head.repo |
pull_request.head.repo |
Gitea 始终有此字段(GH 偶尔 null) |
installation |
— | Gitea 没有 GitHub App 概念 |
sender.type === "Bot" |
sender.type === "user" |
Gitea 暂无 Bot 用户类型 |
完整差异参考:Gitea webhook 文档。
测试策略
- 本仓库自身做 dogfooding:在
claude-gitea-agent自己的 issue 里 @claude,让它给自己写功能 - mock 测试:
test/fixtures/放几个 Gitea webhook payload 样本 - CI:暂不上 CI,跑通 happy path 后再加
当前阻塞 / 风险
| 风险 | 缓解 |
|---|---|
| Gitea Actions 跑 bun 容器可能要装 bun | runner image 用 catthehacker/ubuntu:act-latest(已包含 node,bun 安装 1 行命令) |
Gitea webhook 评论事件名是 issue_comment 还是 issues_comment? |
写 entrypoint 时先 dump payload 验证 |
| Anthropic API rate limit 在循环交互场景下会不会爆 | 暂不优化,到了再说 |