feat(agentic): add forge PR close action
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
57ee930717
commit
24bb3b26c6
5 changed files with 92 additions and 0 deletions
|
|
@ -343,6 +343,16 @@ func (s *PrepSubsystem) handlePRMerge(ctx context.Context, options core.Options)
|
|||
return s.cmdPRMerge(normaliseForgeActionOptions(options))
|
||||
}
|
||||
|
||||
// result := c.Action("agentic.pr.close").Run(ctx, core.NewOptions(
|
||||
//
|
||||
// core.Option{Key: "_arg", Value: "go-io"},
|
||||
// core.Option{Key: "number", Value: "12"},
|
||||
//
|
||||
// ))
|
||||
func (s *PrepSubsystem) handlePRClose(ctx context.Context, options core.Options) core.Result {
|
||||
return s.cmdPRClose(normaliseForgeActionOptions(options))
|
||||
}
|
||||
|
||||
// result := c.Action("agentic.review-queue").Run(ctx, core.NewOptions(
|
||||
//
|
||||
// core.Option{Key: "workspace", Value: "core/go-io/task-5"},
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ func (s *PrepSubsystem) registerForgeCommands() {
|
|||
c.Command("pr/get", core.Command{Description: "Get a Forge PR", Action: s.cmdPRGet})
|
||||
c.Command("pr/list", core.Command{Description: "List Forge PRs for a repo", Action: s.cmdPRList})
|
||||
c.Command("pr/merge", core.Command{Description: "Merge a Forge PR", Action: s.cmdPRMerge})
|
||||
c.Command("pr/close", core.Command{Description: "Close a Forge PR", Action: s.cmdPRClose})
|
||||
c.Command("repo/get", core.Command{Description: "Get Forge repo info", Action: s.cmdRepoGet})
|
||||
c.Command("repo/list", core.Command{Description: "List Forge repos for an org", Action: s.cmdRepoList})
|
||||
}
|
||||
|
|
@ -293,6 +294,27 @@ func (s *PrepSubsystem) cmdPRMerge(options core.Options) core.Result {
|
|||
return core.Result{OK: true}
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) cmdPRClose(options core.Options) core.Result {
|
||||
ctx := context.Background()
|
||||
org, repo, num := parseForgeArgs(options)
|
||||
if repo == "" || num == 0 {
|
||||
core.Print(nil, "usage: core-agent pr close <repo> --number=N [--org=core]")
|
||||
return core.Result{Value: core.E("agentic.cmdPRClose", "repo and number are required", nil), OK: false}
|
||||
}
|
||||
|
||||
var pr pullRequestView
|
||||
err := s.forge.Client().Patch(ctx, core.Sprintf("/api/v1/repos/%s/%s/pulls/%d", org, repo, num), &forge_types.EditPullRequestOption{
|
||||
State: "closed",
|
||||
}, &pr)
|
||||
if err != nil {
|
||||
core.Print(nil, "error: %v", err)
|
||||
return core.Result{Value: err, OK: false}
|
||||
}
|
||||
|
||||
core.Print(nil, "closed %s/%s#%d", org, repo, num)
|
||||
return core.Result{OK: true}
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) cmdRepoGet(options core.Options) core.Result {
|
||||
ctx := context.Background()
|
||||
org, repo, _ := parseForgeArgs(options)
|
||||
|
|
|
|||
|
|
@ -339,6 +339,50 @@ func TestCommandsforge_CmdPRMerge_Good_CustomMethod(t *testing.T) {
|
|||
assert.True(t, r.OK)
|
||||
}
|
||||
|
||||
func TestCommandsforge_CmdPRClose_Bad_MissingArgs(t *testing.T) {
|
||||
s, _ := testPrepWithCore(t, nil)
|
||||
r := s.cmdPRClose(core.NewOptions())
|
||||
assert.False(t, r.OK)
|
||||
}
|
||||
|
||||
func TestCommandsforge_CmdPRClose_Good_Success(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, http.MethodPatch, r.Method)
|
||||
assert.Equal(t, "/api/v1/repos/core/go-io/pulls/5", r.URL.Path)
|
||||
|
||||
bodyResult := core.ReadAll(r.Body)
|
||||
assert.True(t, bodyResult.OK)
|
||||
assert.Contains(t, bodyResult.Value.(string), `"state":"closed"`)
|
||||
|
||||
w.Write([]byte(core.JSONMarshalString(map[string]any{
|
||||
"number": 5,
|
||||
"state": "closed",
|
||||
})))
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
s, _ := testPrepWithCore(t, srv)
|
||||
r := s.cmdPRClose(core.NewOptions(
|
||||
core.Option{Key: "_arg", Value: "go-io"},
|
||||
core.Option{Key: "number", Value: "5"},
|
||||
))
|
||||
assert.True(t, r.OK)
|
||||
}
|
||||
|
||||
func TestCommandsforge_CmdPRClose_Ugly_APIError(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
s, _ := testPrepWithCore(t, srv)
|
||||
r := s.cmdPRClose(core.NewOptions(
|
||||
core.Option{Key: "_arg", Value: "go-io"},
|
||||
core.Option{Key: "number", Value: "5"},
|
||||
))
|
||||
assert.False(t, r.OK)
|
||||
}
|
||||
|
||||
func TestCommandsforge_CmdIssueGet_Good_WithBody(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(core.JSONMarshalString(map[string]any{
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ func (s *PrepSubsystem) OnStartup(ctx context.Context) core.Result {
|
|||
c.Action("agentic.pr.get", s.handlePRGet).Description = "Get a Forge PR by number"
|
||||
c.Action("agentic.pr.list", s.handlePRList).Description = "List Forge PRs for a repo"
|
||||
c.Action("agentic.pr.merge", s.handlePRMerge).Description = "Merge a Forge PR"
|
||||
c.Action("agentic.pr.close", s.handlePRClose).Description = "Close a Forge PR"
|
||||
|
||||
c.Action("agentic.review-queue", s.handleReviewQueue).Description = "Run CodeRabbit review on completed workspaces"
|
||||
|
||||
|
|
|
|||
|
|
@ -490,6 +490,21 @@ func TestPrep_OnStartup_Good_RegistersSessionActions(t *testing.T) {
|
|||
assert.True(t, c.Action("sprint.archive").Exists())
|
||||
}
|
||||
|
||||
func TestPrep_OnStartup_Good_RegistersForgeActions(t *testing.T) {
|
||||
t.Setenv("CORE_WORKSPACE", t.TempDir())
|
||||
t.Setenv("CORE_AGENT_DISPATCH", "")
|
||||
|
||||
c := core.New(core.WithOption("name", "test"))
|
||||
s := NewPrep()
|
||||
s.ServiceRuntime = core.NewServiceRuntime(c, AgentOptions{})
|
||||
|
||||
require.True(t, s.OnStartup(context.Background()).OK)
|
||||
assert.True(t, c.Action("agentic.pr.get").Exists())
|
||||
assert.True(t, c.Action("agentic.pr.list").Exists())
|
||||
assert.True(t, c.Action("agentic.pr.merge").Exists())
|
||||
assert.True(t, c.Action("agentic.pr.close").Exists())
|
||||
}
|
||||
|
||||
func TestPrep_OnStartup_Good_RegistersContentActions(t *testing.T) {
|
||||
t.Setenv("CORE_WORKSPACE", t.TempDir())
|
||||
t.Setenv("CORE_AGENT_DISPATCH", "")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue