139 lines
3.9 KiB
Go
139 lines
3.9 KiB
Go
package repo
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"gitea.com/gitea/gitea-mcp/pkg/errors"
|
|
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
|
"gitea.com/gitea/gitea-mcp/pkg/log"
|
|
"gitea.com/gitea/gitea-mcp/pkg/params"
|
|
"gitea.com/gitea/gitea-mcp/pkg/to"
|
|
|
|
gitea_sdk "code.gitea.io/sdk/gitea"
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
"github.com/mark3labs/mcp-go/server"
|
|
)
|
|
|
|
const (
|
|
CreateCommitStatusToolName = "create_commit_status"
|
|
)
|
|
|
|
var (
|
|
CreateCommitStatusTool = mcp.NewTool(
|
|
CreateCommitStatusToolName,
|
|
mcp.WithDescription("Create a commit status check for a repository. Adds a new status context to a commit without overwriting existing statuses."),
|
|
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
|
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
|
mcp.WithString("sha", mcp.Required(), mcp.Description("commit SHA (full 40-character SHA or short SHA)")),
|
|
mcp.WithString("state", mcp.Required(), mcp.Description("status state: pending, success, error, or failure")),
|
|
mcp.WithString("target_url", mcp.Description("URL with more details about the status (e.g., review environment link like https://review.lumbridgecorp.com)")),
|
|
mcp.WithString("context", mcp.Description("status context identifier (e.g., 'ci/metal', 'ci/cloud-1', 'continuous-integration/jenkins')"), mcp.DefaultString("default")),
|
|
mcp.WithString("description", mcp.Description("short description of the status")),
|
|
)
|
|
)
|
|
|
|
func init() {
|
|
Tool.RegisterWrite(server.ServerTool{
|
|
Tool: CreateCommitStatusTool,
|
|
Handler: CreateCommitStatusFn,
|
|
})
|
|
}
|
|
|
|
// CreateCommitStatusFn creates a status check for a commit
|
|
func CreateCommitStatusFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
log.Debugf("Called CreateCommitStatusFn")
|
|
args := req.GetArguments()
|
|
|
|
owner, err := params.GetString(args, "owner")
|
|
if err != nil {
|
|
return to.ErrorResult(err)
|
|
}
|
|
|
|
repo, err := params.GetString(args, "repo")
|
|
if err != nil {
|
|
return to.ErrorResult(err)
|
|
}
|
|
|
|
sha, err := params.GetString(args, "sha")
|
|
if err != nil {
|
|
return to.ErrorResult(err)
|
|
}
|
|
|
|
state, err := params.GetString(args, "state")
|
|
if err != nil {
|
|
return to.ErrorResult(err)
|
|
}
|
|
|
|
statusState, err := parseStatusState(state)
|
|
if err != nil {
|
|
return to.ErrorResult(fmt.Errorf("invalid state '%s': must be one of pending, success, failure, error", state))
|
|
}
|
|
|
|
targetURL, _ := args["target_url"].(string)
|
|
context, _ := args["context"].(string)
|
|
description, _ := args["description"].(string)
|
|
|
|
// Use default context if not provided
|
|
if context == "" {
|
|
context = "default"
|
|
}
|
|
|
|
opt := gitea_sdk.CreateStatusOption{
|
|
State: statusState,
|
|
TargetURL: targetURL,
|
|
Context: context,
|
|
Description: description,
|
|
}
|
|
|
|
client, err := gitea.ClientFromContext(ctx)
|
|
if err != nil {
|
|
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
|
}
|
|
|
|
status, _, err := client.CreateStatus(owner, repo, sha, opt)
|
|
if err != nil {
|
|
translatedErr := errors.TranslateError(err, map[string]string{
|
|
"operation": "CreateCommitStatus",
|
|
"owner": owner,
|
|
"repo": repo,
|
|
"sha": sha,
|
|
"state": state,
|
|
"context": context,
|
|
})
|
|
return to.ErrorResult(translatedErr)
|
|
}
|
|
|
|
return to.TextResult(slimStatus(status))
|
|
}
|
|
|
|
// parseStatusState converts a string state to gitea_sdk.StatusState
|
|
func parseStatusState(state string) (gitea_sdk.StatusState, error) {
|
|
switch state {
|
|
case "pending":
|
|
return gitea_sdk.StatusPending, nil
|
|
case "success":
|
|
return gitea_sdk.StatusSuccess, nil
|
|
case "failure":
|
|
return gitea_sdk.StatusFailure, nil
|
|
case "error":
|
|
return gitea_sdk.StatusError, nil
|
|
default:
|
|
return "", fmt.Errorf("invalid state: %s", state)
|
|
}
|
|
}
|
|
|
|
// slimStatus creates a slimmed down representation of a commit status
|
|
func slimStatus(s *gitea_sdk.Status) map[string]any {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
return map[string]any{
|
|
"id": s.ID,
|
|
"state": s.State,
|
|
"target_url": s.TargetURL,
|
|
"context": s.Context,
|
|
"description": s.Description,
|
|
}
|
|
}
|