Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25cb55449e | |||
| 7e3b6ec8f1 |
@@ -485,7 +485,7 @@ func main() {
|
||||
reviewReq := vcs.ReviewRequest{
|
||||
Body: reviewBody,
|
||||
Event: event,
|
||||
CommitID: evaluatedSHA,
|
||||
CommitID: pr.Head.SHA,
|
||||
Comments: inlineComments,
|
||||
}
|
||||
posted, err := client.PostReview(ctx, owner, repoName, prNumber, reviewReq)
|
||||
|
||||
+3
-3
@@ -170,9 +170,9 @@ func (a *Adapter) PostReview(ctx context.Context, owner, repo string, number int
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("translate position %d in %s: %w", c.Position, c.Path, err)
|
||||
}
|
||||
// Per-comment CommitID is not forwarded:
|
||||
// Gitea review comments are pinned to the PR head SHA automatically,
|
||||
// and the CreatePullReview API has no per-comment commit_id field.
|
||||
// Per-comment CommitID is not forwarded to Gitea inline comments:
|
||||
// Gitea's CreatePullReview API has no per-comment commit_id field.
|
||||
// The review-level commit anchor is set via req.CommitID instead.
|
||||
giteaComments = append(giteaComments, ReviewComment{
|
||||
Path: c.Path,
|
||||
NewPosition: int64(lineNum),
|
||||
|
||||
+70
-34
@@ -214,40 +214,6 @@ func TestAdapter_PostReview_EventTranslation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdapter_PostReview_CommitID(t *testing.T) {
|
||||
var gotCommitID string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var payload struct {
|
||||
CommitID string `json:"commit_id"`
|
||||
}
|
||||
json.NewDecoder(r.Body).Decode(&payload)
|
||||
gotCommitID = payload.CommitID
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 1,
|
||||
"body": "test",
|
||||
"user": map[string]any{"login": "bot"},
|
||||
"commit_id": payload.CommitID,
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := gitea.NewClient(server.URL, "token")
|
||||
adapter := gitea.NewAdapter(client)
|
||||
|
||||
_, err := adapter.PostReview(context.Background(), "owner", "repo", 1, vcs.ReviewRequest{
|
||||
Body: "test",
|
||||
Event: vcs.ReviewEventApprove,
|
||||
CommitID: "sha256abc",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gotCommitID != "sha256abc" {
|
||||
t.Errorf("expected commit_id %q forwarded to client, got %q", "sha256abc", gotCommitID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdapter_PostReview_WithComments_PositionTranslation(t *testing.T) {
|
||||
diff := `diff --git a/main.go b/main.go
|
||||
--- a/main.go
|
||||
@@ -442,3 +408,73 @@ func TestAdapter_RequestReviewerSelf(t *testing.T) {
|
||||
t.Fatalf("RequestReviewerSelf() error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdapter_PostReview_CommitID_Threading(t *testing.T) {
|
||||
var gotPayload struct {
|
||||
Body string `json:"body"`
|
||||
Event string `json:"event"`
|
||||
CommitID string `json:"commit_id"`
|
||||
}
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewDecoder(r.Body).Decode(&gotPayload)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 1,
|
||||
"body": "test",
|
||||
"user": map[string]any{"login": "bot"},
|
||||
"commit_id": "abc123def456",
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := gitea.NewClient(server.URL, "token")
|
||||
adapter := gitea.NewAdapter(client)
|
||||
|
||||
review, err := adapter.PostReview(context.Background(), "owner", "repo", 1, vcs.ReviewRequest{
|
||||
Body: "LGTM",
|
||||
Event: vcs.ReviewEventApprove,
|
||||
CommitID: "abc123def456",
|
||||
// No comments → no diff fetch needed
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gotPayload.CommitID != "abc123def456" {
|
||||
t.Errorf("commit_id = %q, want %q", gotPayload.CommitID, "abc123def456")
|
||||
}
|
||||
if review.CommitID != "abc123def456" {
|
||||
t.Errorf("review.CommitID = %q, want %q", review.CommitID, "abc123def456")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdapter_PostReview_EmptyCommitID_Omitted(t *testing.T) {
|
||||
var gotRawPayload map[string]any
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewDecoder(r.Body).Decode(&gotRawPayload)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 1,
|
||||
"body": "test",
|
||||
"user": map[string]any{"login": "bot"},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := gitea.NewClient(server.URL, "token")
|
||||
adapter := gitea.NewAdapter(client)
|
||||
|
||||
_, err := adapter.PostReview(context.Background(), "owner", "repo", 1, vcs.ReviewRequest{
|
||||
Body: "looks good",
|
||||
Event: vcs.ReviewEventComment,
|
||||
// CommitID intentionally empty
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
// With empty CommitID and omitempty tag, the field should not appear in JSON
|
||||
if _, exists := gotRawPayload["commit_id"]; exists {
|
||||
t.Errorf("commit_id should be omitted when empty, but was present: %v", gotRawPayload["commit_id"])
|
||||
}
|
||||
}
|
||||
|
||||
+60
-60
@@ -147,66 +147,6 @@ func TestPostReview(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_CommitID(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
t.Fatalf("expected POST, got %s", r.Method)
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
var payload struct {
|
||||
Body string `json:"body"`
|
||||
Event string `json:"event"`
|
||||
CommitID string `json:"commit_id"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &payload); err != nil {
|
||||
t.Fatalf("unmarshal payload: %v", err)
|
||||
}
|
||||
if payload.CommitID != "deadbeef123" {
|
||||
t.Errorf("expected commit_id %q, got %q", "deadbeef123", payload.CommitID)
|
||||
}
|
||||
if payload.Event != "APPROVED" {
|
||||
t.Errorf("expected event APPROVED, got %q", payload.Event)
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"id":101,"user":{"login":"review-bot"},"state":"APPROVED","stale":false,"commit_id":"deadbeef123"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient(server.URL, "test-token")
|
||||
review, err := client.PostReview(context.Background(), "owner", "repo", 3, "APPROVED", "LGTM", "deadbeef123", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if review.ID != 101 {
|
||||
t.Errorf("expected review ID 101, got %d", review.ID)
|
||||
}
|
||||
if review.CommitID != "deadbeef123" {
|
||||
t.Errorf("expected commit_id %q, got %q", "deadbeef123", review.CommitID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_EmptyCommitID_OmittedFromPayload(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
// When commit_id is empty, it should not appear in JSON (omitempty)
|
||||
if strings.Contains(string(body), "commit_id") {
|
||||
t.Errorf("expected commit_id to be omitted from payload, got: %s", body)
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"id":102,"user":{"login":"review-bot"},"state":"APPROVED","stale":false}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient(server.URL, "test-token")
|
||||
_, err := client.PostReview(context.Background(), "owner", "repo", 3, "APPROVED", "LGTM", "", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPullRequest_Non200(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
@@ -1005,6 +945,7 @@ func TestDoGet_RespectsContextCancellation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// mockTransport is a test helper that returns errors for the first N calls,
|
||||
// then delegates to a real server.
|
||||
type mockTransport struct {
|
||||
@@ -1203,3 +1144,62 @@ func TestSanitizeErrorForLog(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_CommitID_InPayload(t *testing.T) {
|
||||
var gotPayload struct {
|
||||
Body string `json:"body"`
|
||||
Event string `json:"event"`
|
||||
CommitID string `json:"commit_id"`
|
||||
}
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewDecoder(r.Body).Decode(&gotPayload)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 200,
|
||||
"body": "LGTM",
|
||||
"user": map[string]any{"login": "bot"},
|
||||
"state": "APPROVED",
|
||||
"commit_id": "deadbeef1234",
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient(server.URL, "test-token")
|
||||
review, err := client.PostReview(context.Background(), "owner", "repo", 5, "APPROVED", "LGTM", "deadbeef1234", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gotPayload.CommitID != "deadbeef1234" {
|
||||
t.Errorf("sent commit_id = %q, want %q", gotPayload.CommitID, "deadbeef1234")
|
||||
}
|
||||
if review.CommitID != "deadbeef1234" {
|
||||
t.Errorf("response commit_id = %q, want %q", review.CommitID, "deadbeef1234")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_EmptyCommitID_OmittedFromPayload(t *testing.T) {
|
||||
var gotRaw map[string]any
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewDecoder(r.Body).Decode(&gotRaw)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 201,
|
||||
"body": "ok",
|
||||
"user": map[string]any{"login": "bot"},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient(server.URL, "test-token")
|
||||
_, err := client.PostReview(context.Background(), "owner", "repo", 5, "COMMENT", "ok", "", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if _, exists := gotRaw["commit_id"]; exists {
|
||||
t.Errorf("commit_id should be omitted when empty, but was present: %v", gotRaw["commit_id"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func TestPostReview_WithComments(t *testing.T) {
|
||||
{Path: "util.go", NewPosition: 10, Body: "[MINOR] Style issue"},
|
||||
}
|
||||
|
||||
_, err := client.PostReview(context.Background(), "owner", "repo", 1, "REQUEST_CHANGES", "summary", "abc123", comments)
|
||||
_, err := client.PostReview(context.Background(), "owner", "repo", 1, "REQUEST_CHANGES", "summary", "", comments)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
+11
-9
@@ -82,31 +82,33 @@ func translateGitHubReviewState(state string) string {
|
||||
// (via the omitempty tag on postReviewRequest.Comments).
|
||||
//
|
||||
// The GitHub API accepts a single commit_id per review submission. PostReview
|
||||
// uses req.CommitID as the primary anchor when set. If req.CommitID is empty,
|
||||
// it falls back to extracting commit_id from the first comment with a non-empty
|
||||
// CommitID. If any comment specifies a CommitID that conflicts with the
|
||||
// resolved value, PostReview returns ErrConflictingCommitIDs.
|
||||
// Comments with an empty CommitID are allowed and inherit the review-level value.
|
||||
// uses req.CommitID as the primary commit anchor. If req.CommitID is empty,
|
||||
// it falls back to extracting from the first comment with a non-empty CommitID.
|
||||
// If any subsequent comment specifies a different CommitID, PostReview returns
|
||||
// ErrConflictingCommitIDs. Comments with an empty CommitID are allowed and
|
||||
// inherit the review-level value.
|
||||
func (c *Client) PostReview(ctx context.Context, owner, repo string, number int, req vcs.ReviewRequest) (*vcs.Review, error) {
|
||||
reqURL := fmt.Sprintf("%s/repos/%s/%s/pulls/%d/reviews",
|
||||
c.baseURL, url.PathEscape(owner), url.PathEscape(repo), number)
|
||||
|
||||
payload := postReviewRequest{
|
||||
CommitID: req.CommitID,
|
||||
Body: req.Body,
|
||||
Event: string(req.Event),
|
||||
CommitID: req.CommitID,
|
||||
}
|
||||
|
||||
// Build the payload in one pass. The GitHub API accepts a single commit_id
|
||||
// per review. We use req.CommitID as the primary anchor; if any comment
|
||||
// specifies a different non-empty CommitID, we reject the request.
|
||||
// per review. req.CommitID is the primary source; if empty, we extract from
|
||||
// the first comment that supplies one. Reject if any comment disagrees with
|
||||
// the resolved commit_id.
|
||||
for _, comment := range req.Comments {
|
||||
if comment.CommitID != "" {
|
||||
if payload.CommitID == "" { // only reachable when req.CommitID is empty
|
||||
if payload.CommitID == "" {
|
||||
payload.CommitID = comment.CommitID
|
||||
} else if payload.CommitID != comment.CommitID {
|
||||
return nil, ErrConflictingCommitIDs
|
||||
}
|
||||
// else: matching SHA is a no-op by design
|
||||
}
|
||||
payload.Comments = append(payload.Comments, reviewCommentEntry{
|
||||
Path: comment.Path,
|
||||
|
||||
+53
-82
@@ -390,124 +390,95 @@ func TestPostReview_ConflictingCommitIDs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_CommitIDFromRequest(t *testing.T) {
|
||||
c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
var req postReviewRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
t.Fatalf("unmarshal request: %v", err)
|
||||
}
|
||||
if req.CommitID != "req-level-sha" {
|
||||
t.Errorf("expected commit_id %q, got %q", "req-level-sha", req.CommitID)
|
||||
}
|
||||
func TestPostReview_RequestCommitID_TakesPriority(t *testing.T) {
|
||||
var gotPayload struct {
|
||||
CommitID string `json:"commit_id"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"id": 200,
|
||||
"body": "ok",
|
||||
c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewDecoder(r.Body).Decode(&gotPayload)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 42,
|
||||
"body": "LGTM",
|
||||
"state": "APPROVED",
|
||||
"commit_id": "req-level-sha",
|
||||
"user": map[string]string{"login": "bot"},
|
||||
"user": map[string]any{"login": "bot"},
|
||||
})
|
||||
})
|
||||
|
||||
// CommitID set at request level, no comments
|
||||
review, err := c.PostReview(context.Background(), "owner", "repo", 5, vcs.ReviewRequest{
|
||||
Body: "ok",
|
||||
review, err := c.PostReview(context.Background(), "owner", "repo", 1, vcs.ReviewRequest{
|
||||
Body: "LGTM",
|
||||
Event: vcs.ReviewEventApprove,
|
||||
CommitID: "req-level-sha",
|
||||
Comments: []vcs.ReviewComment{
|
||||
{Path: "a.go", Position: 1, CommitID: "req-level-sha", Body: "looks good"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gotPayload.CommitID != "req-level-sha" {
|
||||
t.Errorf("sent commit_id = %q, want %q", gotPayload.CommitID, "req-level-sha")
|
||||
}
|
||||
if review.CommitID != "req-level-sha" {
|
||||
t.Errorf("expected commit_id %q, got %q", "req-level-sha", review.CommitID)
|
||||
t.Errorf("review.CommitID = %q, want %q", review.CommitID, "req-level-sha")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_CommitIDFallbackToComment(t *testing.T) {
|
||||
func TestPostReview_RequestCommitID_ConflictsWithComment(t *testing.T) {
|
||||
c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
var req postReviewRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
t.Fatalf("unmarshal request: %v", err)
|
||||
}
|
||||
// When req.CommitID is empty, should fall back to comment's CommitID
|
||||
if req.CommitID != "comment-sha" {
|
||||
t.Errorf("expected commit_id %q (from comment fallback), got %q", "comment-sha", req.CommitID)
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"id": 201,
|
||||
"body": "ok",
|
||||
"state": "APPROVED",
|
||||
"commit_id": "comment-sha",
|
||||
"user": map[string]string{"login": "bot"},
|
||||
})
|
||||
t.Fatal("request should not be sent when commit IDs conflict")
|
||||
})
|
||||
|
||||
review, err := c.PostReview(context.Background(), "owner", "repo", 5, vcs.ReviewRequest{
|
||||
Body: "ok",
|
||||
Event: vcs.ReviewEventApprove,
|
||||
// CommitID intentionally empty — should fall back to comment
|
||||
Comments: []vcs.ReviewComment{
|
||||
{Path: "main.go", Position: 1, CommitID: "comment-sha", Body: "nit"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if review.CommitID != "comment-sha" {
|
||||
t.Errorf("expected commit_id %q, got %q", "comment-sha", review.CommitID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_CommitIDConflictBetweenRequestAndComment(t *testing.T) {
|
||||
c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatal("request should not have been sent")
|
||||
})
|
||||
|
||||
_, err := c.PostReview(context.Background(), "owner", "repo", 5, vcs.ReviewRequest{
|
||||
Body: "ok",
|
||||
Event: vcs.ReviewEventApprove,
|
||||
// req.CommitID is set, and a comment has a different CommitID → conflict
|
||||
_, err := c.PostReview(context.Background(), "owner", "repo", 1, vcs.ReviewRequest{
|
||||
Body: "Review",
|
||||
Event: vcs.ReviewEventComment,
|
||||
CommitID: "req-sha",
|
||||
Comments: []vcs.ReviewComment{
|
||||
{Path: "main.go", Position: 1, CommitID: "different-sha", Body: "nit"},
|
||||
{Path: "a.go", Position: 1, CommitID: "different-sha", Body: "nit"},
|
||||
},
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected error for conflicting commit IDs")
|
||||
}
|
||||
if !errors.Is(err, ErrConflictingCommitIDs) {
|
||||
t.Errorf("expected ErrConflictingCommitIDs, got %v", err)
|
||||
t.Errorf("expected ErrConflictingCommitIDs, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostReview_CommitIDMatchBetweenRequestAndComment(t *testing.T) {
|
||||
c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
var req postReviewRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
t.Fatalf("unmarshal request: %v", err)
|
||||
}
|
||||
if req.CommitID != "same-sha" {
|
||||
t.Errorf("expected commit_id %q, got %q", "same-sha", req.CommitID)
|
||||
}
|
||||
func TestPostReview_RequestCommitID_FallbackToComment(t *testing.T) {
|
||||
var gotPayload struct {
|
||||
CommitID string `json:"commit_id"`
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"id": 202,
|
||||
c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewDecoder(r.Body).Decode(&gotPayload)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": 43,
|
||||
"body": "ok",
|
||||
"state": "APPROVED",
|
||||
"commit_id": "same-sha",
|
||||
"user": map[string]string{"login": "bot"},
|
||||
"state": "COMMENTED",
|
||||
"commit_id": "comment-sha",
|
||||
"user": map[string]any{"login": "bot"},
|
||||
})
|
||||
})
|
||||
|
||||
_, err := c.PostReview(context.Background(), "owner", "repo", 5, vcs.ReviewRequest{
|
||||
Body: "ok",
|
||||
Event: vcs.ReviewEventApprove,
|
||||
CommitID: "same-sha",
|
||||
// req.CommitID is empty, so it falls back to the comment's CommitID
|
||||
_, err := c.PostReview(context.Background(), "owner", "repo", 1, vcs.ReviewRequest{
|
||||
Body: "ok",
|
||||
Event: vcs.ReviewEventComment,
|
||||
// CommitID intentionally empty
|
||||
Comments: []vcs.ReviewComment{
|
||||
{Path: "main.go", Position: 1, CommitID: "same-sha", Body: "nit"},
|
||||
{Path: "a.go", Position: 1, CommitID: "comment-sha", Body: "note"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gotPayload.CommitID != "comment-sha" {
|
||||
t.Errorf("sent commit_id = %q, want %q (fallback from comment)", gotPayload.CommitID, "comment-sha")
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -95,9 +95,9 @@ type ReviewRequest struct {
|
||||
// Event is the review action (approve, request changes, or comment).
|
||||
Event ReviewEvent `json:"event"`
|
||||
// CommitID anchors the review to a specific commit SHA.
|
||||
// Both GitHub and Gitea accept this at the review level.
|
||||
// If empty, each platform applies its default behavior (Gitea uses PR
|
||||
// head; GitHub derives from comments or omits).
|
||||
CommitID string `json:"commit_id,omitempty"`
|
||||
// If empty, the platform defaults to the current PR head.
|
||||
// Adapters use this as the primary commit anchor for the review submission.
|
||||
CommitID string `json:"commit_id,omitempty"`
|
||||
|
||||
Comments []ReviewComment `json:"comments,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user