Skip to content

Commit dfdddae

Browse files
committed
add create repo support
1 parent 76facd1 commit dfdddae

File tree

4 files changed

+122
-3
lines changed

4 files changed

+122
-3
lines changed

client/dto/pullrequest.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ type PullRequestStats struct {
8383
UnresolvedCount int `json:"unresolved_count,omitempty"`
8484
}
8585

86+
// CreatePullRequest represents the request body for creating a new pull request
87+
type CreatePullRequest struct {
88+
Title string `json:"title"`
89+
Description string `json:"description,omitempty"`
90+
SourceBranch string `json:"source_branch"`
91+
TargetBranch string `json:"target_branch,omitempty"`
92+
IsDraft bool `json:"is_draft,omitempty"`
93+
}
94+
8695
// PullRequestOptions represents the options for listing pull requests
8796
type PullRequestOptions struct {
8897
State []string `json:"state,omitempty"`

client/pullrequest.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import (
99
)
1010

1111
const (
12-
pullRequestBasePath = "code/api/v1/repos"
13-
pullRequestGetPath = pullRequestBasePath + "/%s/pullreq/%d"
14-
pullRequestListPath = pullRequestBasePath + "/%s/pullreq"
12+
pullRequestBasePath = "code/api/v1/repos"
13+
pullRequestGetPath = pullRequestBasePath + "/%s/pullreq/%d"
14+
pullRequestListPath = pullRequestBasePath + "/%s/pullreq"
15+
pullRequestCreatePath = pullRequestBasePath + "/%s/pullreq"
1516
)
1617

1718
type PullRequestService struct {
@@ -120,3 +121,22 @@ func (p *PullRequestService) List(ctx context.Context, scope dto.Scope, repoID s
120121

121122
return prs, nil
122123
}
124+
125+
// Create creates a new pull request in the specified repository
126+
func (p *PullRequestService) Create(ctx context.Context, scope dto.Scope, repoID string, createPR *dto.CreatePullRequest) (*dto.PullRequest, error) {
127+
path := fmt.Sprintf(pullRequestCreatePath, repoID)
128+
params := make(map[string]string)
129+
addScope(scope, params)
130+
131+
if createPR == nil {
132+
createPR = &dto.CreatePullRequest{}
133+
}
134+
135+
pr := new(dto.PullRequest)
136+
err := p.client.Post(ctx, path, params, createPR, pr)
137+
if err != nil {
138+
return nil, fmt.Errorf("failed to create pull request: %w", err)
139+
}
140+
141+
return pr, nil
142+
}

pkg/harness/pullreq.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,90 @@ func splitAndTrim(s, sep string) []string {
214214

215215
return result
216216
}
217+
218+
// CreatePullRequestTool creates a tool for creating a new pull request
219+
func CreatePullRequestTool(config *config.Config, client *client.Client) (tool mcp.Tool, handler server.ToolHandlerFunc) {
220+
return mcp.NewTool("create_pull_request",
221+
mcp.WithDescription("Create a new pull request in a Harness repository."),
222+
mcp.WithString("repo_identifier",
223+
mcp.Required(),
224+
mcp.Description("The identifier of the repository"),
225+
),
226+
mcp.WithString("title",
227+
mcp.Required(),
228+
mcp.Description("The title of the pull request"),
229+
),
230+
mcp.WithString("description",
231+
mcp.Description("The description of the pull request"),
232+
),
233+
mcp.WithString("source_branch",
234+
mcp.Required(),
235+
mcp.Description("The source branch for the pull request"),
236+
),
237+
mcp.WithString("target_branch",
238+
mcp.Description("The target branch for the pull request"),
239+
mcp.DefaultString("main"),
240+
),
241+
mcp.WithBoolean("is_draft",
242+
mcp.Description("Whether the pull request should be created as a draft"),
243+
mcp.DefaultBool(false),
244+
),
245+
WithScope(config, false),
246+
),
247+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
248+
repoIdentifier, err := requiredParam[string](request, "repo_identifier")
249+
if err != nil {
250+
return mcp.NewToolResultError(err.Error()), nil
251+
}
252+
253+
title, err := requiredParam[string](request, "title")
254+
if err != nil {
255+
return mcp.NewToolResultError(err.Error()), nil
256+
}
257+
258+
description, err := OptionalParam[string](request, "description")
259+
if err != nil {
260+
return mcp.NewToolResultError(err.Error()), nil
261+
}
262+
263+
sourceBranch, err := requiredParam[string](request, "source_branch")
264+
if err != nil {
265+
return mcp.NewToolResultError(err.Error()), nil
266+
}
267+
268+
isDraft, err := OptionalParam[bool](request, "is_draft")
269+
if err != nil {
270+
return mcp.NewToolResultError(err.Error()), nil
271+
}
272+
273+
targetBranch, err := OptionalParam[string](request, "target_branch")
274+
if err != nil {
275+
return mcp.NewToolResultError(err.Error()), nil
276+
}
277+
278+
scope, err := fetchScope(config, request, false)
279+
if err != nil {
280+
return mcp.NewToolResultError(err.Error()), nil
281+
}
282+
283+
createRequest := &dto.CreatePullRequest{
284+
Title: title,
285+
SourceBranch: sourceBranch,
286+
TargetBranch: targetBranch,
287+
IsDraft: isDraft,
288+
Description: description,
289+
}
290+
291+
data, err := client.PullRequests.Create(ctx, scope, repoIdentifier, createRequest)
292+
if err != nil {
293+
return nil, fmt.Errorf("failed to create pull request: %w", err)
294+
}
295+
296+
r, err := json.Marshal(data)
297+
if err != nil {
298+
return nil, fmt.Errorf("failed to marshal pull request: %w", err)
299+
}
300+
301+
return mcp.NewToolResultText(string(r)), nil
302+
}
303+
}

pkg/harness/tools.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ func InitToolsets(client *client.Client, config *config.Config) (*toolsets.Tools
3232
AddReadTools(
3333
toolsets.NewServerTool(GetPullRequestTool(config, client)),
3434
toolsets.NewServerTool(ListPullRequestsTool(config, client)),
35+
).
36+
AddWriteTools(
37+
toolsets.NewServerTool(CreatePullRequestTool(config, client)),
3538
)
3639

3740
// Create the repositories toolset

0 commit comments

Comments
 (0)