Add configurable PR comment upsert and fix UTF-8 truncation#411
Add configurable PR comment upsert and fix UTF-8 truncation#411wesm merged 12 commits intoroborev-dev:mainfrom
Conversation
roborev: Combined Review (
|
Embed an invisible HTML marker (<!-- roborev-pr-comment -->) in every roborev comment. On each post, search for an existing comment with the marker using `gh api`. If found, update it via PATCH; otherwise create a new one. Extracts shared logic into internal/github/comment.go and updates both the CLI path (cmd/roborev/ci.go) and the daemon path (internal/daemon/ci_poller.go) to delegate to UpsertPRComment.
- Use encoding/json.Marshal for PATCH payload instead of strconv.Quote to produce strictly valid JSON for all inputs (fixes \v/\a escapes). - Parse only the first non-empty line from gh api --paginate output to handle multi-page results that emit multiple comment IDs. - Replace shallow marker/truncation tests with ones that exercise UpsertPRComment and capture subprocess stdin. - Add tests for multi-line paginated output and PATCH payload validity.
- Add control characters (\v, \a) to PATCH payload test to directly protect against the strconv.Quote regression. - Assert JSON round-trip preserves the original body content. - Verify truncation boundary is exactly review.MaxCommentLen.
- Reserve suffix length before slicing so truncated body stays within MaxCommentLen (affects both github.UpsertPRComment and review.formatSingleResult) - Back up to valid UTF-8 boundary when slicing to avoid splitting multibyte characters - Fall back to creating a new comment when PATCH fails (e.g. comment owned by a different actor returns 403) - Add tests for create failure, patch-failure fallback, and UTF-8 safe truncation in both packages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…daries - PATCH fallback now checks for HTTP 403/404 in the error message; other failures (network, rate-limit) propagate as errors to avoid silent duplicate comments - Fix UTF-8 truncation tests in both packages to place the multibyte character straddling the actual cut boundary (maxBody), not an arbitrary offset Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Looking at this. I actually want to see all the review comments from my CI bot rather than updating them. I'm going to take a pass on this and make the upserting behavior configurable rather than the default |
PR comments now default to creating a new comment each run. Set ci.upsert_comments = true to restore the previous behavior of finding and patching an existing marker comment. - Add UpsertComments bool to CIConfig - Extract prepareBody helper, add exported CreatePRComment - Branch on config in postCIComment (CLI) and postPRComment (daemon) - Add tests for CreatePRComment (marker, truncation) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review findings: - Add UpsertComments *bool to RepoCIConfig so per-repo .roborev.toml can override the global setting (fixes CI-only pipelines with no global config) - Resolve with precedence: repo config > global config > false - Add resolveUpsertComments to daemon with repo config lookup - Add resolveCIUpsertComments to CLI with same precedence - Add 4 daemon tests covering default, global, and repo override paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover all precedence paths: nil/nil default, global true/false, repo overriding global in both directions, and repo nil falling through to global. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FindExistingComment now selects the newest (last) marker comment instead of the oldest, so upsert targets the comment most likely writable by the current token. Replace utf8.ValidString loop (O(N) full-string scan that could strip the entire body if interior invalid bytes exist) with TrimPartialRune, which only inspects the trailing rune boundary. Shared across github/comment.go and review/synthesize.go. - Add TrimPartialRune to review package with table-driven tests - Add mixed-ownership multi-ID test for 403 fallback - Update multi-line test to assert newest ID selected Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a string ended with orphan continuation bytes (e.g., 0x80) preceded by a valid ASCII byte, the backward scan would incorrectly trim the valid byte too. Now checks whether the rune-start byte found during the backward walk decodes to a valid rune — if so, keeps it and only removes the orphan tail. Add test cases for single and double orphan continuation bytes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
postCIComment was creating context.Background() instead of accepting the caller's context, preventing Ctrl+C from canceling in-flight GitHub API requests during roborev ci review. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
07d1117 to
5ec108d
Compare
roborev: Combined Review (
|
Summary
CI review comments are always created as new comments. This adds an opt-in
ci.upsert_commentssetting that finds the existing roborev marker comment and patches it in-place instead.ci.upsert_commentsconfig (global and per-repo, default false)FindExistingComment,UpsertPRComment, andCreatePRCommentininternal/githubutf8.ValidStringfull-string scan with boundary-onlyTrimPartialRunepostCICommentfor Ctrl+C cancellationConfig
🤖 Generated with Claude Code