PostReview, DeleteReview, and RequestReviewer were calling c.httpClient.Do
directly, bypassing the scheme check in doRequest that rejects http:// URLs
unless AllowInsecureHTTP is explicitly enabled.
Introduce doRequestWithBody(ctx, method, url, body) with the same HTTPS guard,
and refactor all three write methods to use it. This ensures tokens are never
sent over plaintext regardless of which API path is exercised.
Add scheme validation tests for each method.
Wire up the new GitHub API methods to the review-bot CLI via VCS
type detection. review-bot can now review PRs on both Gitea and
GitHub (including GitHub Enterprise Server).
Changes:
- vcs.go: define vcsClient interface with all PR operations
- giteaVCSAdapter: wraps gitea.Client, satisfies vcsClient + giteaExtClient
- githubVCSAdapter: wraps github.Client, satisfies vcsClient
- giteaExtClient: Gitea-specific extension (supersede, comment resolution)
- main.go: detect VCS type via VCS_TYPE env var (auto-detects github.com URLs)
- Creates appropriate client (gitea or github) based on vcs_type
- GitHub API URL derived from server URL (github.com → api.github.com,
GHES → /api/v3)
- All main flow uses vcsClient interface
- Gitea-specific supersede operations gated via giteaExtClient type assertion
- GitHub: logs info when skipping supersede (not supported)
- Removes old giteaClientAdapter (replaced by giteaVCSAdapter in vcs.go)
- giteaVCSAdapter satisfies review.GiteaClient for persona loading
GitHub limitations handled gracefully:
- Review supersede skipped (GitHub doesn't allow editing submitted reviews)
- DeleteReview returns error for non-pending reviews (documented in adapter)
- Inline comments use absolute line + side='RIGHT' instead of diff position
Closes#130.
Co-authored-by: Rodin <rodin@forgedthought.ai>
Implement the higher-level GitHub API methods that were TODO since
issue #120. The github package now provides:
- GetPullRequest: PR metadata (title, body, head SHA/ref, draft)
- GetPullRequestDiff: unified diff via Accept: application/vnd.github.diff
- GetPullRequestFiles: changed files list (paginated, 100/page)
- GetCommitStatuses: CI statuses (GitHub uses 'state' field, normalized)
- GetFileContent: file content with base64 decode (strips embedded newlines)
- GetFileContentRef: file at a specific ref
- ListContents: directory listing or single-file normalization
- GetAllFilesInPath: recursive file fetching
- PostReview: submit review with event/body/commit/inline comments
- ListReviews: list PR reviews (paginated)
- DeleteReview: delete review (GitHub only allows PENDING deletion)
- GetAuthenticatedUser: returns login of the authed user
- RequestReviewer: add a user as requested reviewer
API types added: PullRequest, CommitStatus, ChangedFile, ReviewComment,
Review, ContentEntry.
Notable edge cases handled:
- GitHub embeds newlines in base64 content; stripped before decode
- GetFileContent returns error for non-file paths (type=dir)
- ListContents normalizes single-file response to a slice
- DeleteReview documents GitHub's PENDING-only constraint
Removes TODO comment from baseURL field (now consumed by all methods).
Closes part of #130.
Co-authored-by: Rodin <rodin@forgedthought.ai>