The github package has the HTTP transport layer (retry logic, rate limiting, redirect safety, SSRF protection) but no higher-level API methods. The TODO comment in client.go notes that baseURL is populated but not yet used.
Currently, review-bot supports Gitea PRs but cannot review GitHub PRs despite having GitHub Actions runner support via the composite action.
What to implement
Mirror the methods from gitea/client.go for the GitHub API:
All listed API methods implemented in github/client.go
Each method has a corresponding test using httptest.NewServer
TODO comment removed from client.go
cmd/review-bot/main.go routes to either client based on VCS_TYPE env var (or --vcs-type flag)
Integration test updated/extended for GitHub
go test ./... passes
## Problem
The `github` package has the HTTP transport layer (retry logic, rate limiting, redirect safety, SSRF protection) but no higher-level API methods. The `TODO` comment in `client.go` notes that `baseURL` is populated but not yet used.
Currently, review-bot supports Gitea PRs but cannot review GitHub PRs despite having GitHub Actions runner support via the composite action.
## What to implement
Mirror the methods from `gitea/client.go` for the GitHub API:
- `GetPullRequest(ctx, owner, repo, number)` → `/repos/{owner}/{repo}/pulls/{number}`
- `GetPullRequestDiff(ctx, owner, repo, number)` → `/repos/{owner}/{repo}/pulls/{number}` with `Accept: application/vnd.github.diff`
- `GetPullRequestFiles(ctx, owner, repo, number)` → `/repos/{owner}/{repo}/pulls/{number}/files`
- `GetCommitStatuses(ctx, owner, repo, sha)` → `/repos/{owner}/{repo}/commits/{sha}/statuses` (or `/check-runs`)
- `GetFileContent(ctx, owner, repo, filepath)` → `/repos/{owner}/{repo}/contents/{path}`
- `GetFileContentRef(ctx, owner, repo, filepath, ref)` → same with `?ref=`
- `ListContents(ctx, owner, repo, path)` → `/repos/{owner}/{repo}/contents/{path}`
- `PostReview(ctx, owner, repo, number, event, body, commitID, comments)` → `/repos/{owner}/{repo}/pulls/{number}/reviews`
- `ListReviews(ctx, owner, repo, number)` → `/repos/{owner}/{repo}/pulls/{number}/reviews`
- `DeleteReview(ctx, owner, repo, number, reviewID)` → DELETE `/repos/{owner}/{repo}/pulls/{number}/reviews/{review_id}`
- `GetAuthenticatedUser(ctx)` → `/user`
## Notes
- The action.yml already supports GitHub runners and detects `VCS_TYPE=github`
- The binary needs a way to route to either `gitea.Client` or `github.Client` based on `VCS_TYPE`
- Both clients should satisfy a common `VCSClient` interface (defined in `cmd/review-bot` per Go conventions)
- Review verdict mapping: GitHub uses `APPROVE`, `REQUEST_CHANGES`, `COMMENT` (same as Gitea)
## Acceptance Criteria
- [ ] All listed API methods implemented in `github/client.go`
- [ ] Each method has a corresponding test using `httptest.NewServer`
- [ ] `TODO` comment removed from `client.go`
- [ ] `cmd/review-bot/main.go` routes to either client based on `VCS_TYPE` env var (or `--vcs-type` flag)
- [ ] Integration test updated/extended for GitHub
- [ ] `go test ./...` passes
rodin
self-assigned this 2026-05-14 20:35:50 +00:00
Plan: feat: implement GitHub API methods for PR review
Problem
The github package has the HTTP transport layer but no higher-level API methods. The review-bot supports Gitea PRs but cannot route to GitHub despite the action.yml supporting GitHub runners. This issue adds the missing API methods to github/client.go and wires them into cmd/review-bot/main.go via a VCS_TYPE flag.
Constraints
No new third-party dependencies (CONVENTIONS.md strict allowlist)
All new code must pass go test ./... and go vet ./...
Each method needs a test using httptest.NewServer
VCSClient interface defined in cmd/review-bot per Go conventions
GitHub uses APPROVE, REQUEST_CHANGES, COMMENT — same event names as Gitea
Proposed Approach
Phase 1: Create vcs package with shared types
New package at vcs/types.go with:
type ReviewEvent string with constants ReviewEventApprove, ReviewEventRequestChanges, ReviewEventComment
type ReviewComment struct { Path, Body string; Position int; CommitID string }
type Review struct { ID int64; Body, State, CommitID string; User UserInfo }
type UserInfo struct { Login string }
type ReviewRequest struct { Body string; Event ReviewEvent; Comments []ReviewComment }
This package is imported by the github package review methods.
Phase 2: Add doRequestWithBody to github/client.go
New helper method that handles POST/PUT/DELETE with a JSON body. No retry (non-idempotent). Sets Content-Type: application/json. Respects HTTP/SSRF security (blocks HTTP unless AllowInsecureHTTP set).
Phase 3: Add local types to github/client.go
type PullRequest struct (Title, Body, Head.Sha, Head.Ref)
type CommitStatus struct (Status, Context, Description, TargetURL)
type ChangedFile struct (Filename, Status)
type ContentEntry struct (Name, Path, Type)
Plus max diff size constant + ErrDiffTooLarge error
Phase 4: Add API methods to github/client.go
GetPullRequest → GET /repos/{owner}/{repo}/pulls/{number}
GetPullRequestDiff → same URL with Accept: application/vnd.github.diff
GetPullRequestFiles → GET /repos/{owner}/{repo}/pulls/{number}/files
GetCommitStatuses → GET /repos/{owner}/{repo}/commits/{sha}/statuses
GetFileContent → GET /repos/{owner}/{repo}/contents/{path} (base64 decode response)
GetFileContentRef → same with ?ref= param
ListContents → GET /repos/{owner}/{repo}/contents/{path} (returns array)
Remove TODO comment
Phase 5: Add review.go and identity.go to github package
review.go: PostReview, ListReviews, DeleteReview, DismissReview using vcs types
identity.go: GetAuthenticatedUser
Phase 6: Update cmd/review-bot/main.go
Add --vcs-type flag (values: gitea, github; default: gitea for backward compat).
Define VCSClient interface in cmd/review-bot/ using local adapter types.
Extend giteaClientAdapter and add githubClientAdapter to satisfy the interface.
Route based on VCS_TYPE env var or --vcs-type flag.
Open Questions
GetCommitStatuses uses GitHub's legacy /statuses endpoint. If github.concur.com uses only check-runs, a separate GetCheckRuns method will be needed. Starting with statuses for now (matches issue spec).
ListContents: GitHub returns an object (not array) when path is a file. Will handle both shapes.
Integration test: adding a note that the integration test can be run against GitHub by setting VCS_TYPE=github.
Acceptance Criteria
All listed API methods implemented in github/client.go
Each method has a corresponding test using httptest.NewServer
TODO comment removed from client.go
cmd/review-bot/main.go routes to either client based on VCS_TYPE env var / --vcs-type flag
Integration test updated/extended for GitHub
go test ./... passes
## Plan: feat: implement GitHub API methods for PR review
## Problem
The `github` package has the HTTP transport layer but no higher-level API methods. The review-bot supports Gitea PRs but cannot route to GitHub despite the action.yml supporting GitHub runners. This issue adds the missing API methods to `github/client.go` and wires them into `cmd/review-bot/main.go` via a `VCS_TYPE` flag.
## Constraints
- No new third-party dependencies (CONVENTIONS.md strict allowlist)
- All new code must pass `go test ./...` and `go vet ./...`
- Each method needs a test using `httptest.NewServer`
- VCSClient interface defined in `cmd/review-bot` per Go conventions
- GitHub uses `APPROVE`, `REQUEST_CHANGES`, `COMMENT` — same event names as Gitea
## Proposed Approach
### Phase 1: Create `vcs` package with shared types
New package at `vcs/types.go` with:
- `type ReviewEvent string` with constants `ReviewEventApprove`, `ReviewEventRequestChanges`, `ReviewEventComment`
- `type ReviewComment struct { Path, Body string; Position int; CommitID string }`
- `type Review struct { ID int64; Body, State, CommitID string; User UserInfo }`
- `type UserInfo struct { Login string }`
- `type ReviewRequest struct { Body string; Event ReviewEvent; Comments []ReviewComment }`
This package is imported by the `github` package review methods.
### Phase 2: Add `doRequestWithBody` to `github/client.go`
New helper method that handles POST/PUT/DELETE with a JSON body. No retry (non-idempotent). Sets `Content-Type: application/json`. Respects HTTP/SSRF security (blocks HTTP unless AllowInsecureHTTP set).
### Phase 3: Add local types to `github/client.go`
- `type PullRequest struct` (Title, Body, Head.Sha, Head.Ref)
- `type CommitStatus struct` (Status, Context, Description, TargetURL)
- `type ChangedFile struct` (Filename, Status)
- `type ContentEntry struct` (Name, Path, Type)
- Plus max diff size constant + `ErrDiffTooLarge` error
### Phase 4: Add API methods to `github/client.go`
- `GetPullRequest` → `GET /repos/{owner}/{repo}/pulls/{number}`
- `GetPullRequestDiff` → same URL with `Accept: application/vnd.github.diff`
- `GetPullRequestFiles` → `GET /repos/{owner}/{repo}/pulls/{number}/files`
- `GetCommitStatuses` → `GET /repos/{owner}/{repo}/commits/{sha}/statuses`
- `GetFileContent` → `GET /repos/{owner}/{repo}/contents/{path}` (base64 decode response)
- `GetFileContentRef` → same with `?ref=` param
- `ListContents` → `GET /repos/{owner}/{repo}/contents/{path}` (returns array)
- Remove `TODO` comment
### Phase 5: Add `review.go` and `identity.go` to `github` package
- `review.go`: `PostReview`, `ListReviews`, `DeleteReview`, `DismissReview` using `vcs` types
- `identity.go`: `GetAuthenticatedUser`
### Phase 6: Update `cmd/review-bot/main.go`
Add `--vcs-type` flag (values: `gitea`, `github`; default: `gitea` for backward compat).
Define `VCSClient` interface in `cmd/review-bot/` using local adapter types.
Extend `giteaClientAdapter` and add `githubClientAdapter` to satisfy the interface.
Route based on `VCS_TYPE` env var or `--vcs-type` flag.
## Open Questions
1. `GetCommitStatuses` uses GitHub's legacy `/statuses` endpoint. If `github.concur.com` uses only check-runs, a separate `GetCheckRuns` method will be needed. Starting with statuses for now (matches issue spec).
2. `ListContents`: GitHub returns an object (not array) when path is a file. Will handle both shapes.
3. Integration test: adding a note that the integration test can be run against GitHub by setting `VCS_TYPE=github`.
## Acceptance Criteria
- [ ] All listed API methods implemented in `github/client.go`
- [ ] Each method has a corresponding test using `httptest.NewServer`
- [ ] `TODO` comment removed from `client.go`
- [ ] `cmd/review-bot/main.go` routes to either client based on `VCS_TYPE` env var / `--vcs-type` flag
- [ ] Integration test updated/extended for GitHub
- [ ] `go test ./...` passes
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
The
githubpackage has the HTTP transport layer (retry logic, rate limiting, redirect safety, SSRF protection) but no higher-level API methods. TheTODOcomment inclient.gonotes thatbaseURLis populated but not yet used.Currently, review-bot supports Gitea PRs but cannot review GitHub PRs despite having GitHub Actions runner support via the composite action.
What to implement
Mirror the methods from
gitea/client.gofor the GitHub API:GetPullRequest(ctx, owner, repo, number)→/repos/{owner}/{repo}/pulls/{number}GetPullRequestDiff(ctx, owner, repo, number)→/repos/{owner}/{repo}/pulls/{number}withAccept: application/vnd.github.diffGetPullRequestFiles(ctx, owner, repo, number)→/repos/{owner}/{repo}/pulls/{number}/filesGetCommitStatuses(ctx, owner, repo, sha)→/repos/{owner}/{repo}/commits/{sha}/statuses(or/check-runs)GetFileContent(ctx, owner, repo, filepath)→/repos/{owner}/{repo}/contents/{path}GetFileContentRef(ctx, owner, repo, filepath, ref)→ same with?ref=ListContents(ctx, owner, repo, path)→/repos/{owner}/{repo}/contents/{path}PostReview(ctx, owner, repo, number, event, body, commitID, comments)→/repos/{owner}/{repo}/pulls/{number}/reviewsListReviews(ctx, owner, repo, number)→/repos/{owner}/{repo}/pulls/{number}/reviewsDeleteReview(ctx, owner, repo, number, reviewID)→ DELETE/repos/{owner}/{repo}/pulls/{number}/reviews/{review_id}GetAuthenticatedUser(ctx)→/userNotes
VCS_TYPE=githubgitea.Clientorgithub.Clientbased onVCS_TYPEVCSClientinterface (defined incmd/review-botper Go conventions)APPROVE,REQUEST_CHANGES,COMMENT(same as Gitea)Acceptance Criteria
github/client.gohttptest.NewServerTODOcomment removed fromclient.gocmd/review-bot/main.goroutes to either client based onVCS_TYPEenv var (or--vcs-typeflag)go test ./...passesPlan: feat: implement GitHub API methods for PR review
Problem
The
githubpackage has the HTTP transport layer but no higher-level API methods. The review-bot supports Gitea PRs but cannot route to GitHub despite the action.yml supporting GitHub runners. This issue adds the missing API methods togithub/client.goand wires them intocmd/review-bot/main.govia aVCS_TYPEflag.Constraints
go test ./...andgo vet ./...httptest.NewServercmd/review-botper Go conventionsAPPROVE,REQUEST_CHANGES,COMMENT— same event names as GiteaProposed Approach
Phase 1: Create
vcspackage with shared typesNew package at
vcs/types.gowith:type ReviewEvent stringwith constantsReviewEventApprove,ReviewEventRequestChanges,ReviewEventCommenttype ReviewComment struct { Path, Body string; Position int; CommitID string }type Review struct { ID int64; Body, State, CommitID string; User UserInfo }type UserInfo struct { Login string }type ReviewRequest struct { Body string; Event ReviewEvent; Comments []ReviewComment }This package is imported by the
githubpackage review methods.Phase 2: Add
doRequestWithBodytogithub/client.goNew helper method that handles POST/PUT/DELETE with a JSON body. No retry (non-idempotent). Sets
Content-Type: application/json. Respects HTTP/SSRF security (blocks HTTP unless AllowInsecureHTTP set).Phase 3: Add local types to
github/client.gotype PullRequest struct(Title, Body, Head.Sha, Head.Ref)type CommitStatus struct(Status, Context, Description, TargetURL)type ChangedFile struct(Filename, Status)type ContentEntry struct(Name, Path, Type)ErrDiffTooLargeerrorPhase 4: Add API methods to
github/client.goGetPullRequest→GET /repos/{owner}/{repo}/pulls/{number}GetPullRequestDiff→ same URL withAccept: application/vnd.github.diffGetPullRequestFiles→GET /repos/{owner}/{repo}/pulls/{number}/filesGetCommitStatuses→GET /repos/{owner}/{repo}/commits/{sha}/statusesGetFileContent→GET /repos/{owner}/{repo}/contents/{path}(base64 decode response)GetFileContentRef→ same with?ref=paramListContents→GET /repos/{owner}/{repo}/contents/{path}(returns array)TODOcommentPhase 5: Add
review.goandidentity.gotogithubpackagereview.go:PostReview,ListReviews,DeleteReview,DismissReviewusingvcstypesidentity.go:GetAuthenticatedUserPhase 6: Update
cmd/review-bot/main.goAdd
--vcs-typeflag (values:gitea,github; default:giteafor backward compat).Define
VCSClientinterface incmd/review-bot/using local adapter types.Extend
giteaClientAdapterand addgithubClientAdapterto satisfy the interface.Route based on
VCS_TYPEenv var or--vcs-typeflag.Open Questions
GetCommitStatusesuses GitHub's legacy/statusesendpoint. Ifgithub.concur.comuses only check-runs, a separateGetCheckRunsmethod will be needed. Starting with statuses for now (matches issue spec).ListContents: GitHub returns an object (not array) when path is a file. Will handle both shapes.VCS_TYPE=github.Acceptance Criteria
github/client.gohttptest.NewServerTODOcomment removed fromclient.gocmd/review-bot/main.goroutes to either client based onVCS_TYPEenv var /--vcs-typeflaggo test ./...passesrodin referenced this issue2026-05-14 20:44:26 +00:00