feat: inline COMMENT-state PR review (findings anchored to changed lines)
Phase 3. Alongside the consensus comment, the consolidator now posts ONE Gitea pull review (state COMMENT — advisory, never request-changes/approve, so it can never block a merge) whose inline comments anchor each consensus finding to the exact changed line. The "reviewer integrated with Gitea" the project wanted, without the blocking. - review.go: a unified-diff parser (parseDiffNewLines — hunk-length-bounded, so a content line that looks like "+++ "/"@@" isn't mistaken for a header), inline comment building filtered to lines actually in the diff, and the Gitea reviews API client (raw new_position/event=COMMENT fields). Re-runs delete the prior gadfly review (body marker) instead of stacking. - consensus.go: cluster.detail restored (now consumed by the inline comment body); renderConsensus takes precomputed clusters; runConsolidate clusters once and drives both the consensus comment and the inline review. - entrypoint.sh: fetch the PR diff and pass GADFLY_DIFF_FILE to the consolidator (GITEA_API/TOKEN/PR already in its env). - README + reusable workflow (`inline_review` input) + entrypoint docs. Best-effort throughout: no diff / API creds, or any post error → the consensus comment still stands; the review is never required and never blocks. Validated the Gitea reviews API + line anchoring live before building. Tests: diff parser (incl. header-like content + multi-file), inline filtering. gofmt/vet/bash -n clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -306,6 +306,14 @@ back to posting the per-model comments. Controlled by `GADFLY_CONSOLIDATE`: `aut
|
||||
for ≥2 models), `1` (force on), `0` (force off, one comment per model). Single-model runs are
|
||||
unaffected.
|
||||
|
||||
**Inline PR review.** Alongside the consensus comment, Gadfly also posts a single Gitea **pull
|
||||
review** (state `COMMENT` — advisory, **never** request-changes or approve, so it can't block a
|
||||
merge) whose inline comments anchor each consensus finding to the exact changed line it's about.
|
||||
Only findings that land on a line in the diff are anchored (Gitea rejects comments off the diff);
|
||||
the rest stay in the consensus comment. A re-run replaces the previous review instead of stacking.
|
||||
It's the "reviewer integrated with Gitea" without the blocking — turn it off with
|
||||
`GADFLY_INLINE_REVIEW=0`.
|
||||
|
||||
### Triggers
|
||||
|
||||
1. A **new/reopened/ready** non-draft PR — automatic.
|
||||
@@ -392,6 +400,7 @@ The reviewer binary reads these (the stub/entrypoint set sane defaults):
|
||||
| `GADFLY_STATUS_BOARD` | on | set `0` to disable the live status-board comment |
|
||||
| `GADFLY_STATUS_POLL_SECS` | 12 | how often the status board re-renders/upserts |
|
||||
| `GADFLY_CONSOLIDATE` | `auto` | cross-model consensus comment: `auto` (on for ≥2 models), `1` (force on), `0` (off — one comment per model) |
|
||||
| `GADFLY_INLINE_REVIEW` | on | when consolidating, also post a `COMMENT`-state PR review with inline comments on changed lines; `0` disables |
|
||||
| `GADFLY_TRIGGER_PHRASE` | `@gadfly review` | comment phrase that re-triggers |
|
||||
| `GADFLY_ALLOWED_USERS` | *(collaborators)* | comma-separated allow-list for comment triggers |
|
||||
| `GADFLY_FINDINGS_URL` | — | gadfly-reports store base URL; set to enable findings telemetry (off when empty) |
|
||||
|
||||
Reference in New Issue
Block a user