Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@
- `ghapp-scan` 增加 `actions: write`(仅用于 dispatch;App token 无法 dispatch hub 工作流)。
- 无匹配 runner 时任务保持排队(不静默回退 ubuntu),文档给出取消/补 runner 的指引。

### Fixed (retry semantics)

- `ai-decide retry` 之前无效:Issue 重新排队后 dispatcher 仍以"已有 open PR"为由跳过
(`skip ... (handled/running/pr open)`),只能手动关 PR。
- 现在以**标签**为准:有 `ai` 且无 `ai-pr`/`ai-failed`/… 就是要求重跑;重跑删除重名分支
(旧 PR 自动关闭),在新基线上重做并开新 PR。新增 `handledByLabels()` + 测试。
- 看门狗的自愈结果不再被 dispatcher 过滤掉(`action: none` 但有 healing 时也会打印)。

### Added (self-healing branches)

- 推送前 `git fetch` 基线 + rebase:基线在运行期间前进时不再产出 `DIRTY` PR;rebase 变了就重新验证。
Expand Down
5 changes: 4 additions & 1 deletion docs/ai-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,10 @@ gh api -X PATCH repos/EasyIndie/EasyGithub/branches/main/protection/required_pul
1. **推送前**:`git fetch` 基线 → `rebase` → 真的变了就**重新验证**再推;
2. **推送被拒**(竞态):自动再 rebase 一次并重试一次;
3. **开 PR 之后**:`ai-watch` 对 `DIRTY`/`BEHIND` 的 `ai/issue-*` 分支调用 GitHub 的
"Update branch"(合并基线进分支),真冲突才交给人。
"Update branch"(合并基线进分支);真冲突时调度日志写 `conflicts #N`,交给 `retry`。

`retry` 的语义是"重新排队",由标签决定(`ai` 在、`ai-pr` 等不在),**不看**是否还有旧 PR:
重跑会删除重名分支(旧 PR 随之关闭)、在新基线上重做、开新 PR。

rebase 会改写已推送的提交,所以推送用 `--force-with-lease`:只覆盖自己的分支,
别人往同一分支推过东西就会失败而不是被覆盖。
Expand Down
11 changes: 8 additions & 3 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ gh workflow run ai-decide.yml -R EasyIndie/EasyGithub \

| 动作 | 什么时候用 |
|---|---|
| `retry` | `ai-failed`、`ai-deferred`、分支冲突、想换基线上重来 |
| `retry` | `ai-failed`、`ai-deferred`、`CONFLICTING` 的 PR、想换基线上重来(会删分支、重跑、旧 PR 自动关闭) |
| `answer` | `ai-needs-input`:agent 抛出的问题你已经有结论了 |
| `cancel` | 卡住/不想要了;同时释放锁,避免 `ai-running` 挂着 |
| `waive` | 需要留下"人已复核"的痕迹(不会绕过路径/密钥检查) |
Expand Down Expand Up @@ -208,7 +208,8 @@ Secrets:`DEEPSEEK_API_KEY`(模型)、`EASYGH_APP_PRIVATE_KEY[_<ORG>]`(Ap
| `ai-deferred` | 当日 PR 配额用尽 | 等配额恢复,或调 `AI_MAX_PRS_PER_DAY` 后 `retry` |
| `ai-needs-input` | agent 明确要人做决定 | 用 `answer` 回复,或直接 `retry` 并改 Issue |
| PR 一直 `BLOCKED` | 缺少必需检查 / 分支落后 | 现在会自动 rebase;仍不行看 §9 |
| 两个 AI PR 改同一文件 | 后者分支过期 | **已自愈**:看门狗会调 GitHub "Update branch" 重放;真冲突会提示 |
| 两个 AI PR 改同一文件 | 后者分支过期 | **多数自愈**:看门狗调 GitHub "Update branch" 重放;日志会写 `updated #N` / `conflicts #N` |
| PR 显示 `CONFLICTING` | 两边改了同一行(真冲突) | `retry`:在新基线上重做,旧 PR 自动关闭,新 PR 重新开 |
| 任务一直排队 | `runsOn` 没有匹配的 runner | 检查自托管 runner 的标签与在线状态 |
| 什么标签都没加 | 触发条件没满足 | 确认 Issue 上有 `ai` 标签(不是标题关键词) |
| `incident` 不自动合并 | 上次 AI 合并把 main 弄坏了 | 处理事故 Issue → 关闭 → 自动合并恢复 |
Expand All @@ -220,7 +221,11 @@ Secrets:`DEEPSEEK_API_KEY`(模型)、`EASYGH_APP_PRIVATE_KEY[_<ORG>]`(Ap
- **开 PR 前**:runner 会 `fetch` 基线并 rebase;若基线在你跑的过程中前进过,rebase 后会**重新验证**再推送。
- **推送被拒**(极小竞态):自动 rebase 一次并重试。
- **开 PR 后**:`ai-watch` 会把 `DIRTY`/`BEHIND` 的 `ai/issue-*` 分支自动"Update branch"。
- **真冲突**(两边改同一行):rebase 会 abort,Issue 打 `ai-needs-input` 并列出冲突文件 → `retry`(在最新基线上重做,通常冲突就没了)或人工解决。
- **真冲突**(两边改同一行):rebase 会 abort,Issue 打 `ai-needs-input` 并列出冲突文件 → `retry`
(在新基线上从头重做,旧 PR 随分支删除自动关闭、新 PR 重新开),或人工解决。

> `retry` 之后 dispatcher **不会**因为"还有旧 PR 开着"而跳过——重新排队以标签为准
> (有 `ai` 且没有 `ai-pr`/`ai-failed` 等就是"请重跑")。

---

Expand Down
Loading