Skip to content

Commit f04c137

Browse files
authored
Reduce context usage for getting a Pull Request (#2017)
* introduce minimal pr type * update to use time.RFC3339 * confine change to single PR
1 parent efe9d40 commit f04c137

File tree

3 files changed

+140
-11
lines changed

3 files changed

+140
-11
lines changed

pkg/github/minimal_types.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package github
22

33
import (
4+
"time"
5+
46
"github.com/google/go-github/v82/github"
57
)
68

@@ -134,8 +136,138 @@ type MinimalProject struct {
134136
OwnerType string `json:"owner_type,omitempty"`
135137
}
136138

139+
// MinimalPullRequest is the trimmed output type for pull request objects to reduce verbosity.
140+
type MinimalPullRequest struct {
141+
Number int `json:"number"`
142+
Title string `json:"title"`
143+
Body string `json:"body,omitempty"`
144+
State string `json:"state"`
145+
Draft bool `json:"draft"`
146+
Merged bool `json:"merged"`
147+
MergeableState string `json:"mergeable_state,omitempty"`
148+
HTMLURL string `json:"html_url"`
149+
User *MinimalUser `json:"user,omitempty"`
150+
Labels []string `json:"labels,omitempty"`
151+
Assignees []string `json:"assignees,omitempty"`
152+
RequestedReviewers []string `json:"requested_reviewers,omitempty"`
153+
MergedBy string `json:"merged_by,omitempty"`
154+
Head *MinimalPRBranch `json:"head,omitempty"`
155+
Base *MinimalPRBranch `json:"base,omitempty"`
156+
Additions int `json:"additions,omitempty"`
157+
Deletions int `json:"deletions,omitempty"`
158+
ChangedFiles int `json:"changed_files,omitempty"`
159+
Commits int `json:"commits,omitempty"`
160+
Comments int `json:"comments,omitempty"`
161+
CreatedAt string `json:"created_at,omitempty"`
162+
UpdatedAt string `json:"updated_at,omitempty"`
163+
ClosedAt string `json:"closed_at,omitempty"`
164+
MergedAt string `json:"merged_at,omitempty"`
165+
Milestone string `json:"milestone,omitempty"`
166+
}
167+
168+
// MinimalPRBranch is the trimmed output type for pull request branch references.
169+
type MinimalPRBranch struct {
170+
Ref string `json:"ref"`
171+
SHA string `json:"sha"`
172+
Repo *MinimalPRBranchRepo `json:"repo,omitempty"`
173+
}
174+
175+
// MinimalPRBranchRepo is the trimmed repo info nested inside a PR branch.
176+
type MinimalPRBranchRepo struct {
177+
FullName string `json:"full_name"`
178+
Description string `json:"description,omitempty"`
179+
}
180+
137181
// Helper functions
138182

183+
func convertToMinimalPullRequest(pr *github.PullRequest) MinimalPullRequest {
184+
m := MinimalPullRequest{
185+
Number: pr.GetNumber(),
186+
Title: pr.GetTitle(),
187+
Body: pr.GetBody(),
188+
State: pr.GetState(),
189+
Draft: pr.GetDraft(),
190+
Merged: pr.GetMerged(),
191+
MergeableState: pr.GetMergeableState(),
192+
HTMLURL: pr.GetHTMLURL(),
193+
User: convertToMinimalUser(pr.GetUser()),
194+
Additions: pr.GetAdditions(),
195+
Deletions: pr.GetDeletions(),
196+
ChangedFiles: pr.GetChangedFiles(),
197+
Commits: pr.GetCommits(),
198+
Comments: pr.GetComments(),
199+
}
200+
201+
if pr.CreatedAt != nil {
202+
m.CreatedAt = pr.CreatedAt.Format(time.RFC3339)
203+
}
204+
if pr.UpdatedAt != nil {
205+
m.UpdatedAt = pr.UpdatedAt.Format(time.RFC3339)
206+
}
207+
if pr.ClosedAt != nil {
208+
m.ClosedAt = pr.ClosedAt.Format(time.RFC3339)
209+
}
210+
if pr.MergedAt != nil {
211+
m.MergedAt = pr.MergedAt.Format(time.RFC3339)
212+
}
213+
214+
for _, label := range pr.Labels {
215+
if label != nil {
216+
m.Labels = append(m.Labels, label.GetName())
217+
}
218+
}
219+
220+
for _, assignee := range pr.Assignees {
221+
if assignee != nil {
222+
m.Assignees = append(m.Assignees, assignee.GetLogin())
223+
}
224+
}
225+
226+
for _, reviewer := range pr.RequestedReviewers {
227+
if reviewer != nil {
228+
m.RequestedReviewers = append(m.RequestedReviewers, reviewer.GetLogin())
229+
}
230+
}
231+
232+
if mergedBy := pr.GetMergedBy(); mergedBy != nil {
233+
m.MergedBy = mergedBy.GetLogin()
234+
}
235+
236+
if head := pr.Head; head != nil {
237+
m.Head = convertToMinimalPRBranch(head)
238+
}
239+
240+
if base := pr.Base; base != nil {
241+
m.Base = convertToMinimalPRBranch(base)
242+
}
243+
244+
if milestone := pr.GetMilestone(); milestone != nil {
245+
m.Milestone = milestone.GetTitle()
246+
}
247+
248+
return m
249+
}
250+
251+
func convertToMinimalPRBranch(branch *github.PullRequestBranch) *MinimalPRBranch {
252+
if branch == nil {
253+
return nil
254+
}
255+
256+
b := &MinimalPRBranch{
257+
Ref: branch.GetRef(),
258+
SHA: branch.GetSHA(),
259+
}
260+
261+
if repo := branch.GetRepo(); repo != nil {
262+
b.Repo = &MinimalPRBranchRepo{
263+
FullName: repo.GetFullName(),
264+
Description: repo.GetDescription(),
265+
}
266+
}
267+
268+
return b
269+
}
270+
139271
func convertToMinimalProject(fullProject *github.ProjectV2) *MinimalProject {
140272
if fullProject == nil {
141273
return nil

pkg/github/pullrequests.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,9 @@ func GetPullRequest(ctx context.Context, client *github.Client, deps ToolDepende
186186
}
187187
}
188188

189-
r, err := json.Marshal(pr)
190-
if err != nil {
191-
return nil, fmt.Errorf("failed to marshal response: %w", err)
192-
}
189+
minimalPR := convertToMinimalPullRequest(pr)
193190

194-
return utils.NewToolResultText(string(r)), nil
191+
return MarshalledTextResult(minimalPR), nil
195192
}
196193

197194
func GetPullRequestDiff(ctx context.Context, client *github.Client, owner, repo string, pullNumber int) (*mcp.CallToolResult, error) {

pkg/github/pullrequests_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,14 @@ func Test_GetPullRequest(t *testing.T) {
127127
// Parse the result and get the text content if no error
128128
textContent := getTextResult(t, result)
129129

130-
// Unmarshal and verify the result
131-
var returnedPR github.PullRequest
130+
// Unmarshal and verify the minimal result
131+
var returnedPR MinimalPullRequest
132132
err = json.Unmarshal([]byte(textContent.Text), &returnedPR)
133133
require.NoError(t, err)
134-
assert.Equal(t, *tc.expectedPR.Number, *returnedPR.Number)
135-
assert.Equal(t, *tc.expectedPR.Title, *returnedPR.Title)
136-
assert.Equal(t, *tc.expectedPR.State, *returnedPR.State)
137-
assert.Equal(t, *tc.expectedPR.HTMLURL, *returnedPR.HTMLURL)
134+
assert.Equal(t, tc.expectedPR.GetNumber(), returnedPR.Number)
135+
assert.Equal(t, tc.expectedPR.GetTitle(), returnedPR.Title)
136+
assert.Equal(t, tc.expectedPR.GetState(), returnedPR.State)
137+
assert.Equal(t, tc.expectedPR.GetHTMLURL(), returnedPR.HTMLURL)
138138
})
139139
}
140140
}

0 commit comments

Comments
 (0)